您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
【第6章:面向对象(高级)】_对象的多态性
发布时间:2020-12-16 19:50:42编辑:雪饮阅读()
向上转型
将子类对象以父类视角对待叫做向上转型
格式:
父类 父类栈变量=子类实例化对象
当子类对父类方法有覆盖时候即便以父类视角也调用的是子类的覆盖方法
class A{
public void print1(){
System.out.println("A->println1");
}
}
class B extends A{
public void print1(){
System.out.println("B->println1");
}
public void print2(){
System.out.println("B->println2");
}
public void print3(){
System.out.println("B->println3");
}
}
public class Hello{
public static void main(String args[]){
B b=new B();
A a=b;
a.print1();
}
}
D:\>javac Hello.java
D:\>java Hello
B->println1
既然是以父类视角,则对应子类自己扩展的方法的调用,父类肯定就是查找不到该方法,从而报错。
class A{
public void print1(){
System.out.println("A->println1");
}
}
class B extends A{
public void print1(){
System.out.println("B->println1");
}
public void print2(){
System.out.println("B->println2");
}
}
public class Hello{
public static void main(String args[]){
B b=new B();
A a=b;
a.print2();
}
}
D:\>javac Hello.java
Hello.java:18: 找不到符号
符号: 方法 print2()
位置: 类 A
a.print2();
^
1 错误
向下转型
向下转型有点像是8大数据类型的转换。
向下转型后默认视角就是子类视角,则无论父类的方法或子类的方法都可以被调用。
class A{
public void print1(){
System.out.println("A->println1");
}
public void say(){
System.out.println("A->say");
}
}
class B extends A{
public void print1(){
System.out.println("B->println1");
}
public void print2(){
System.out.println("B->println2");
}
public void print3(){
System.out.println("B->println3");
}
}
public class Hello{
public static void main(String args[]){
B b=new B();
A a=b;
B b1=(B)a;
b1.print2();
b1.print3();
b1.say();
}
}
D:\>javac Hello.java
D:\>java Hello
B->println2
B->println3
A->say
其实这里向上转型还可以优化一些的
class A{
public void print1(){
System.out.println("A->println1");
}
public void say(){
System.out.println("A->say");
}
}
class B extends A{
public void print1(){
System.out.println("B->println1");
}
public void print2(){
System.out.println("B->println2");
}
public void print3(){
System.out.println("B->println3");
}
}
public class Hello{
public static void main(String args[]){
A a=new B();
B b1=(B)a;
b1.print2();
b1.print3();
b1.say();
}
}
D:\>javac Hello.java
D:\>java Hello
B->println2
B->println3
A->say
父类直接向下转型会出现问题
前面都是先实例化子类对象然后向上转型然后向下转型,如果实例化父类对象然后向下转型呢?
class A{
public void print1(){
System.out.println("A->println1");
}
public void say(){
System.out.println("A->say");
}
}
class B extends A{
public void print1(){
System.out.println("B->println1");
}
public void print2(){
System.out.println("B->println2");
}
public void print3(){
System.out.println("B->println3");
}
}
public class Hello{
public static void main(String args[]){
A a=new A();
B b1=(B)a;
b1.print2();
b1.print3();
b1.say();
}
}
D:\>javac Hello.java
D:\>java Hello
Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B
at Hello.main(Hello.java:23)
这是因为父类并不知道有谁是它的子类,如果贸然转型到子类,那么到底子类的类型是那个类型?子类A?子类B?而对于子类转父类则因为子类有extends关键字标识着谁是其父亲。
多态
对于相同的方法可以接收不同的类型形参并对其做一些处理,称之为多态。
那么来看看传统的多态的实现。
传统多态实现只能利用方法的重载
class A{
public void print1(){
System.out.println("A->println1");
}
}
class B extends A{
public void print1(){
System.out.println("B->println1");
}
}
class C extends A{
public void print1(){
System.out.println("C->println1");
}
}
public class Hello{
public static void main(String args[]){
B b=new B();
polymorphic(b);
C c=new C();
polymorphic(c);
}
public static void polymorphic(B obj){
obj.print1();
}
public static void polymorphic(C obj){
obj.print1();
}
}
D:\>javac Hello.java
D:\>java Hello
B->println1
C->println1
利用向上转型实现多态
class A{
public void print1(){
System.out.println("A->println1");
}
}
class B extends A{
public void print1(){
System.out.println("B->println1");
}
}
class C extends A{
public void print1(){
System.out.println("C->println1");
}
}
public class Hello{
public static void main(String args[]){
B b=new B();
polymorphic(b);
C c=new C();
polymorphic(c);
}
public static void polymorphic(A obj){
obj.print1();
}
}
形参接收的定义方式不就是很像向上转型吗?那么可以总结下多态其实就是相同的父类方法不同的子类继承后对该方法进行不同的方法覆盖,那么就是所谓的诸子百家大放异彩,而却又有着统一的标准。所以多态还不就是方法的覆盖呗。
关键字词:java,面向对象,多态