Java——多态

  1. 定义:一个对象具备多种形态,也可以理解为事物存在的多种体现形态。如果一个方法的参数类型是父类,可以向该方法的参数传递任何子类的对象,基类型对象可以访问派生类重写的方法,这称为多态。

(循环调用基类对象,访问不同派生类方法)

(实参是派生类,行参是基类)

  1. 实现多态的条件:

(1)继承:必须有子类继承父类的关系。

(2)方法重写:方法重写发生在具有继承关系的不同类中,子类会重写父类中的一些方法,调用方法时就会调用子类重写的方法而非父类的方法。

(3)向上转型(upcasting):在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够调用父类的方法和子类的方法。

3.向上转型的实例与解释:

public class Human {
	
	public void sleep() {
		System.out.println("Human sleep...");
	}
	
	public static void main(String[] args) {
		Male m = new Male();
		m.sleep();
		
		Human h = new Male(); // 向上转型
		h.sleep(); // 动态绑定
		// h.speak();不能编译,因为在Human中没有speak方法
	}
}

class Male extends Human{
	@Override
	public void sleep() {
		System.out.println("Male sleep...");
	}
	
	public void speak( ) {
		System.out.println("I am Male");
	}
}

class Female extends Human{
	@Override
	public void sleep() {
		System.out.println("Female sleep...");
	}
	
	public void speak( ) {
		System.out.println("I am Female");
	}
}

运行结果:

向上转型中有需要注意的点:

(1):向上转型不要强制转型

(2):父类引用指向的或者调用的方法是子类的方法,此为动态绑定。

(3):向上转型后父类引用不能调用子类自己的方法。

4.向下转型:

public class Human {
	
	public void sleep() {
		System.out.println("Human sleep...");
	}
	
	public static void main(String[] args) {
		// (1) 向上转型
		Male m1 = new Male();
		Human h1 = m1;
		h1.sleep();
		//h1.speak; //此时需要向下转型,否则不能调用speak方法
		// (2) 向下转型
    		Male m2 = new Male();
		Human h2 = m2;
		m2 = (Male)h2;
		m2.speak();
//
//		// (3) 向下转型,失败
//		Human h3 = new Human();
//		Male m3 = (Male)h3;
//		m3.speak();	//此时会出现运行时错误,所以可以用instanceOF判断
//
//		// (4) 向下转型,类型防护
//		Human h3 = new Human();
//		if(h4 instanceOf Male){ //因为h4不是Male的实例,所以不执行if内部代码
//		Male m4 = (Male)h4;
//		m4.speak();
//		}
	}
}

class Male extends Human{
	@Override
	public void sleep() {
		System.out.println("Male sleep...");
	}
	
	public void speak( ) {
		System.out.println("I am Male");
	}
}

向下转型必须要在向上转型之后

5.动态绑定:

动态绑定与多态:多态是动态绑定的使用,动态绑定是多态的实现原理。

动态绑定的工作机制如下:

假设对象o是类C1,C2,…,Cn-1,Cn的实例,其中C1是C2的子类,C2是C3的子类,…,Cn-1是Cn的子类。也就是说,Cn是最通用的类,C1是最特殊的类。在Java中,Cn是Object类。如果对象o调用一个方法p,那么JVM会依次在类C1,C2,…,Cn-1,Cn中查找方法p的实现,直到找到为止。一旦找到一个实现,就停止查找,然后调用这个首先找到的实现。

6.抽象类与抽象方法:

(1)概念:抽象类用来描述一种类型应该具备的基本特征和功能,具体如何去完成这些行为由子类通过方法重写来完成,抽象方法只有功能声明,没有功能主体实现的方法,具有抽象方法的类一定为抽象类。

(2)定义:在Java语言中通过abstract关键词定义抽象类与抽象方法

一个抽象方法只有方法头,没有方法主体。

访问修饰符 abstract 返回类型 方法名(参数列表);

例如:public abstract void getArea();

抽象类:

例如:public abstract class 类名

3)注意:

包含抽象方法的类就会自动变成抽象类,因此必须通过以abstract关键字声明。

如果派生类没有重写抽象方法,编译器会报错。

抽象方法被用来确保派生类会实现这个方法。

抽象类可以含零至多个普通方法,也可以含零至多个抽象方法。

不论抽象类是否含抽象方法,其都不允许实例化,即不能创建抽象类的对象,因为其描述的是抽象概念。它只能作为其他类的基类。

若父类为抽象类,且子类不想成为抽象类,则子类必须将父类中所有的抽象方法均重写为带方法体的普通方法,否则子类仍必须为抽象类。

参考文献:梁勇. Java语言程序设计与数据结构基础篇[M]. 北京:机械工业出版社,2018.167-175

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值