Java从入门到精通_学习笔记11(接口、继承与多态)

接口、继承与多态

  • 类的继承
  • Object类
  • 对象类型的转换
  • 使用instanceof操作符判断对象类型
  • 方法的重载
  • 多态
  • 抽象类和接口

继承可以复用一些已经定义好的类,减少代码的冗余性;多态可以动态调整对象的调用,降低对象之间的依存关系。由于每个类只能有一个父类,所有出现了接口,每个类可以同时实现多个接口,接口被用来规范类与类之间关联的标准。

类的继承

  1. 概述
    继承的基本思想是基于某个父类进行扩展,得到一个新的子类。子类可以继承父类原有的属性和方法,也可以增加原来父类所不具备的属性和方法,或者直接重写父类中的某些方法。

  1. extends关键字
    在Java中使用extends关键字来标识两个类之间的继承关系。子类只能继承父类中publicprotected修饰符修饰的变量、常量和方法;可以通过super关键字来调用父类的变量、常量和方法。

  1. 代码演示:
class Test{
      
	public Test(){
      
		// 方法体
	}
	
	protected void doSomething(){
      
		// 方法体
	}
	
	protected Test doit(){
       // 返回一个Test类对象
		return new Test();
	}
}

// 使用extends关键字继承Test类
class Test2 extends Test{
       
	public Test2(){
      
		super(); // 调用父类构造方法
		super.doSomething(); //  调用父类方法
	}
	
	public void doSomethingNew(){
       // 新增父类没>有的方法
		// 方法体
	}
	
	protected void doSomething(){
       // 一种特殊的重写父类方法方式,只修改了方法体,也称为方法的【重构】
		// 方法体2
	}
	
	protected Test2 doit(){
       // 重写父类方法,返回一>个Test2类对象
		return new Test2();
	}
}

  1. 方法的重写可以修改方法的以下内容:
  • 访问权限修饰符
  • 返回值类型
  • 参数类型
  • 参数的个数
  • 参数的位置
  • 方法体

注: 重写方法时,访问权限修饰符只能从小范围往大范围改变 ,也就是不可以降低方法的访问权限。

Object类

  1. 概述:
    在Java中所有的类都直接或间接继承了java.lang.Object类。它是所有类的父类,是Java类层中的最高层类。

  1. Object类中重要的方法:
  • getClass( ) : 会返回对象执行时的Class实例,然后使用此实例调用getName( ) 方法可以取得类的名称;
  • toString( ) : 将一个对象返回为字符串形式,它会返回一个String实例;
  • equals( ) : 比较的是两个对象的实际内容;

  1. 代码演示:
// 重写toString()方法
public class ObjectInstance{
      
	public String toString(){
      
		return "在" + getClass().getName() + "类中重写toString()方法"
	}
	public static void main(String args[]){
      
		System.out.println(new ObjectInstance); // 在syso语句中会自动调用toString()方法
	}
}
// 使用equals()方法比较两个对象的内容

class V{
       // 自定义类V
}

public class OverWriteEquals{
      
	public static void main(String args[]){
      
		String str1 = "123";
		String str2 = "123"
		System.out.println(str1.equals(str2)); // 内容一样,结果为true
		V v1 = new V();
		V v2 = new V();
		System.out.println(v1.equals(v2)); // equals()方法默认是比较内存地址,结果为false,
		// 若想要比较内容,需要在自定义类中重写equals()方法
	}
}

对象类型的转换

  1. 向上转型
    向上转型就是将子类对象赋值给父类类型的变量,将子类对象看成是一个父类对象,这样就可以做到在父类中定义一个方法完成操作各个子类的功能。

(1) 语法格式:

  • 父类类型 父类对象引用名 = new 子类类型( );

(2) 代码演示:

class Quadrangle{
       // 定义一个四边形类
	public static void draw(Quadrangle q) {
       // 定义一个参数为四边形类的方法
		// 方法体
	}
}

public class Parallelogram extends Quadrangle{
       // 定义一个平行四边形类继承四边形类
	public static void main(String args[]){
      
		Parallelogram p = new Parallelogram(); // 实>例化一个平行四边形类对象引用
		draw(p);	// 调用父类方法,因为平行四边形>类继承四边形类,向上转型,可以看作是一个四边形类
	}
}
  1. 向下转型
    向下转型是将较抽象的类转换为较具体的类;越是具体的对象,具有的特性越多;越是抽象的对象,具有的特性越少。在做向下转型操作时,将特性范围小的对象转换为特性范围大的对象肯定会出现问题,所以这时需要告知编译器这个抽象的类就是一个具体的类。将父类对象强制转换为某个子类对象,这种方式称为显式类型转换。

(1) 语法格式:

  • 子类类型 子类对象引用名 = (子类类型) 父类对象引用名;
  • 子类类型 子类对象引用名 = 父类类型 父类对象引用名; (这是错误的)

(2) 代码演示:

class Quadrangle{
      
	public static void draw(Quadrangle q){
      
		//方法体
	}
}

public class Parallelogram extends Quadrangle{
      
	public static void main(String args[]) {
      
		draw(new Parallelogram()); // 向上转型
		Quadrangle q = new Parallelogram();
		Parallelogram p = (Parallelogram) q; //向下转型
	}
}

使用instanceof操作符判断对象类型

当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例。这个判断通常使用instanceof操作符来完成。可以使用instanceof操作符判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。


(1) 语法格式:

  • 某类的对象引用名  instanceof  某类类名

(2) 代码演示:

class Quadrangle{
      
	public static void draw(Quadrangle q){
      
		//方法体
	}
}

public class Parallelogram extends Quadrangle{
      
	public static void main(String args[]) {
      
		Quadrangle q = new Quadrangle();
		if(q instanceof Parallelogram) {
       // 判断父类对象q是否为子类Parallelogram的一个实例
			Parallelogram p = (Parallelogram) q; //向转型
		}	
	}
}

方法的重载

构成方法重载的条件:

  • 参数类型不同;
  • 参数个数不同;
  • 参数顺序不同;
  • 返回值类型不同

注:编译器是利用方法名、方法各参数类型和参数的个数以及参数的顺序来确定类中的方法是否唯一。


不定长参数的方法定义:

  • 返回值类型 方法名(参数类型 …参数名)

注:在参数列表中使用"…"形式定义不定长参数,这个参数其实质就是一个数组。

多态

使用多态可以节省开发和维护的时间,因为程序员无须在所有的子类中定义执行相同功能的方法,避免了大量重复代码的编写。同时,只要实例化一个继承父类的子类对象,即可调用相应的方法,对功能进行修改和维护时只要修改父类中的这个方法即可。


注:多态的实现依赖于继承关系对象类型的转换


代码演示:

public class Quadrangle{
      
	// 实例化保存四边形对象的数组对象
	private Quadrangle[] qtest = new Quadrangle[6];
	private int nextIndext = 0;
	public void draw(Quadrangle q){
       // 定义draw()方法,参数为四边形对象
		if(nextIndex < qtest.length){
      
			qtest[nextIndext] = q;
			System.out.println(nextIndex);
			nextIndex++;
		}
	}
	
	piblic static void main(String args[]){
      
		// 实例化两个四边形对象,用于调用draw()方法
		Quadrangle q = new Quadrangle();
		q.draw(new Square()); // 以正方形对象作为参数draw()
		q.draw(new Parallelogramgle()); // 以平行四边形对象作为参数调用draw()
	}
}

// 定义一个正方形类,继承四边形类
class Square extends Quadrangle{
      
	public Square(){
      
		System.out.println("正方形");
	}
}

// 定义一个平行四边形类,继承四边形类
class Parallelogramgle extends Quadrabgle{
      
	public Parallelogramgle(){
      
		System.out.println("");
	}
}

抽象类和接口

  • 抽象类和抽象方法

使用abstract关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法;抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,承载这个抽象方法的类必须是抽象类,而承载这个抽象方法的抽象类必须被继承,抽象类被继承后必须实现其所有的抽象方法。


抽象类被继承后需要实现其中所有的抽象方法,也就是保证相同的方法名称、参数列表和相同返回值类型创建出非抽象方法,当然也可以是抽象方法


  • 抽象类的定义语法:
public abstract class Test{
       //定义抽象类
	abstract void testAbstract(); // 定义抽象方法
}
  • 接口和继承

接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。 接口使用interface关键字进行定义。一个类可以使用implements关键字以实现一个接口。


  • 接口的定义语法(interface关键字):
public interface drawTest{
       // 使用interface关键字定义接口
	public abstract void draw(); // 定义抽象方法,>abstract关键字可以省略
}
  • 接口的实现(implements关键字):
public class Parallelogram implements drawTest{
       // 使用inplements关键字实现接口
	// 省略
}

注:

  • 接口中的方法必须被定义为public和abstract修饰,且即使不声明,也默认是public和abstrct;
  • 在接口中任何字段都自动是static和final的;
  • 与继承只能继承一个类不同,一个类可以同时实现多个接口,接口之间有 " , " 隔开。

你可能感兴趣的:(Java学习笔记,java,抽象类,多态,接口)