多态性

多态性


只是围绕多态性的概念。代码与实际开发并没有关系,多态一定是在继承性的基础上才可以操作。本处使用类来描述,实际开发中,完整的类不应该被继承,开发中都要求继承抽象类和接口。
多态实现的两个前提:继承、覆写。
范例:引出代码

class A{
	public void print(){
		System.out.println("Hello");
	}
}
class B extends A{
	public void print(){
		System.out.println("你好");
	}
}
public class Hello{
	public static void main(String args[]){
		B b = new B();
		b.print();
	}
}

覆写调用的前提:看new的是哪个类的对象,而后看方法是否被子类所覆写。
在这里插入图片描述
范例:对象的向上转型

public class Hello{
	public static void main(String args[]){
		A a = new B();//向上转型
		a.print();//你好
	}
}

向上转型是自动完成的,除了向上转型之外,也可以实现对象的向下转型。
范例:对象的向下转型

public class Hello{
	public static void main(String args[]){
		A a = new B();//向上转型
		B b =(B) a;//向下转型
		b.print();//你好
	}
}

转型意义?
分析:向上转型的意义
定义fun(),要求可以接收A及A类做有子类的实例化对象,两种方案。

  • 方案一:重载
class A{
	public void print(){
		System.out.println("Hello");
	}
}
class B extends A{
	public void print(){
		System.out.println("你好");
	}
}
class C extends A{
	public void print(){
		System.out.println("不好");
	}
}
public class Hello{
	public static void main(String args[]){
		fun(new A());
		fun(new B());
		fun(new C());
	}
	public static void fun(A a){
		a.print();
	}
	public static void fun(B b){
		b.print();
	}
	public static void fun(C c){
		c.print();
	}
}

在这里插入图片描述
如果A类有特别多的子类呢?

  • 方案二:发现所有的子类调用的方法实际上都只是print()一个。可以利用对象自动向上转型的概念,直接使用A类接收。
public class Hello{
	public static void main(String args[]){
		fun(new A());
		fun(new B());
		fun(new C());
	}
	public static void fun(A a){
		a.print();
	}
}

在这里插入图片描述
所以对象的向上转型给开发者最大的帮助在于其数据操作上的统一性。
分析:向下转型的意义
范例:观察

class A{
	public void print(){
		System.out.println("Hello");
	}
}
class B extends A{
	public void print(){
		System.out.println("你好");
	}
	public void funB(){//子类自己扩充的新方法
		System.out.println("**********B**********");
	}
}

public class Hello{
	public static void main(String args[]){
		A a = new B();//向上转型
		a.print();
		a.funB();
	}
}

在这里插入图片描述
一旦发生向上转型后,父类不能调用子类新建的方法,只能够调用其自身的方法。也就是说,向上转型后,牺牲的是子类的个性特征。如果想调用子类定义的方法,可以采用向下转型。

public class Hello{
	public static void main(String args[]){
		A a = new B();//向上转型
		a.print();
		B b = (B) a;//向下转型才能使用子类的新方法
		b.funB();
	}
}

在这里插入图片描述
为什么需要先向上转型,再向下转型?

class A{
	public void print(){
		System.out.println("Hello");
	}
}
class B extends A{
	public void print(){
		System.out.println("你好");
	}
	public void funB(){//子类自己扩充的新方法
		System.out.println("**********B**********");
	}
}
class C extends A{
	public void print(){
		System.out.println("不好");
	}
	public void funC(){//子类自己扩充的新方法
		System.out.println("**********C**********");
	}
}
public class Hello{
	public static void main(String args[]){
		fun(new B());
		fun(new C());
		A a = new B();//向上转型
		a.print();
		B b = (B) a;//向下转型才能使用子类的新方法
		b.funB();
	}
	public static void fun(A a){
		a.print();
		//由于某种特殊要求必须调用B中的funB()方法,所以需要向下转型
		B b=(B)a;
		b.funB();
	}
}

现在如果使用了向下转型,那么之前好不容易建立起来的参数统一的局面就被打破了,所以这样的操作形式就属于不合理操作形式。但转型的意义却可以更加明确了:为了调用子类的特殊支持。
在进行向下转型时需要注意:
范例:错误的向下转型

class A{
	public void print(){
		System.out.println("Hello");
	}
}
class B extends A{
	public void print(){
		System.out.println("你好");
	}
	public void funB(){//子类自己扩充的新方法
		System.out.println("**********B**********");
	}
}
class C extends A{
	public void print(){
		System.out.println("不好");
	}
	public void funC(){//子类自己扩充的新方法
		System.out.println("**********C**********");
	}
}
public class Hello{
	public static void main(String args[]){
		fun(new B());
		fun(new C());
		A a = new B();//向上转型
		a.print();
		B b = (B) a;//向下转型才能使用子类的新方法
		b.funB();
	}
	public static void fun(A a){
		a.print();
		//由于某种特殊要求必须调用B中的funB()方法,所以需要向下转型
		B b=(B)a;
		b.funB();
	}
}

在这里插入图片描述
因为两个没有关系的类发生了强制转换。所以要想进行向下转型操作之前,一定要保证发生了向上转型,这样才可以建立父子对象的关系。
但是这样的转型本身是有安全隐患的,所以在Java中提供有一个关键字,instanceof ,利用此关键字可以判断某一个对象是否是指定类的实例。

对象 instanceof 类 返回boolean类型

范例:观察instanceof关键字的使用

public class Hello{
	public static void main(String args[]){
		A a = new A();//父类对象
		System.out.println(a instanceof A);
		System.out.println(a instanceof B);
	}
}

在这里插入图片描述
范例:发生了向上转型后的判断

public class Hello{
	public static void main(String args[]){
		A a = new B();//父类对象
		System.out.println(a instanceof A);
		System.out.println(a instanceof B);
	}
}

在这里插入图片描述
范例:利用instanceof保证转型的正确性

public class Hello{
	public static void main(String args[]){
		A a = new B();//父类对象
		System.out.println(a instanceof A);
		System.out.println(a instanceof B);
		if(a instanceof B){
			B b=(B)a;//详细强制转换
			b.print();
		}
	}
}

在这里插入图片描述
对于多态性总结如下:

  • 向上转型(90%):为了实现参数类型的统一,但是向上转型一定要与方法覆写产生关联;
  • 向下转型(1%):为了调用子类特殊的方法实现,但是向下转型前必须要首先发生向上转型,会存在操作的安全隐患,可以使用instanceof判断,但是不推荐这样使用;
  • 不转型(9%):为了方便操作直接使用系统类或者是功能类,例如:String、简单Java类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值