关于多态

怎么理解多态,多态表示的是多身份多状态,那又怎么去理解这句话呢,看下面的代码

Person p = new Chinese();

父类的声明指向子类的构造方法,活脱脱的一个多态例子。那么问题来了,现在的对象p是什么类型呢

咱们在学校或者在资料上看到的说pPerson类型,因为什么类型的声明,就是什么类型的对象。能够理解很多资料上为什么这样解释,因为通过instanceof关键字判断p是否是Person类型返回值为true。但是,咱们不能忽略,instanceof判定是扩展性判定的

 a instanceof A 只要aA的类型或者是A的子类,他都会返回true 所以这样判定是不严谨的 而且更重要的是这样一来就解释不了多态多身份的含义了。

最好的判定类型的方式,利用反射 p.getClass() 我们进行输出可以很容易知道pChinese类型,由此知道一个对象是什么类型不是由类型声明决定的,而是由构造方法决定的。以此作为基础,咱们去理解多态多身份的解释

 

首先,上述代码 表示构造了一个Chinese类型的对象,他现在的身份是Person类型

所以此时咱们通过p.去调用类成员,只能访问到Person类拥有的成员(属性或方法),而我们可以通过强制类型转换

Chinese c = (Chinese)p;

此时表示咱们将p对象的身份改变为了Chinese,用c去接收,我们发现此时c就可以访问到Chinese类型拥有的成员和方法了。

而如果咱们的声明是

Person p = new Person();

表示当前的对象pPerson类型的

所以咱们通过(Chinese)p去强转会抛出类型转换异常

因为对于此时的对象p来说,他是Person类型的 他并没有Chinese类型的身份。

所以,从某一层面来说,继承拓展的也是对象的身份,这便是多态,多身份的体现。

============================================================================================
    多重身份,其实这是类比的理解,对象空间有一个很好的类比模型,洋葱模型:
  多态的声明本质,其实是对象空间访问权限的控制。
    什么样的声明就能访问什么样的空间
    A b = new B();//生成的是一个B实例的对象空间,此时A声明,所以只能访问到 B实例中的父类A空间
    A c = new C();//生成的是一个C实例的对象空间,此时A声明,所以只能访问到 C实例中的B空间内的A空间
    造型的本质也是访问权限的更替。
    向上可自动转型,向下必须强制造型。
     如 B bb = (B) b;//可以将对象b的访问权限变更为整个B实例,并且将对象空间引用交给新的变量bb。
     而 C cb = (C)b;//运行时会抛出造型异常,因为b本身空间就没有c空间,你要将它改变成访问C的权限当然异常啦。
     但是对象c就可以在ABC之间互相转换,因为他拥有三者的访问权限

============================================================================================

 

多态的执行

多态执行方法或者.属性是什么过程呢

咱们知道Person p = new Chinese();

此时p对象的身份是Person 所以在搜索成员的时候,他会优先在Person的空间内去搜索,如果搜索不到这个成员,表示当前的身份没有这个成员,编译就报错了。如果搜索到了这个成员,那么他会再到子类里面去搜索,如果在子类找到了这个成员,那么就使用的是子类的成员。如果子类成员搜索完毕,没有找到这个成员,那么就执行Person搜索到的成员了。

体现在一些资料里归纳的就是,

p只能访问到Person类内部的属性和方法,如果方法在Chinese里重写了,那么执行子类重写的方法

全部评论

相关推荐

球球别再泡了:坏,我单9要了14
点赞 评论 收藏
分享
4 收藏 评论
分享
牛客网
牛客企业服务