java多态性以及向上向下转型

来源:互联网 发布:windows7 软件中文乱码 编辑:程序博客网 时间:2024/06/06 01:23

多态:同一操作产生不同的意义,不同的结果,基类引用对象引用不同的子类对象。

相关类

public class A {    public String show(D obj) {        return ("A and D");    }    public String show(A obj) {        return ("A and A");    } }public class B extends A{    public String show(B obj){        return ("B and B");    }    public String show(A obj){        return ("B and A");    } }public class C extends B{}public class D extends B{}

 A a1 = new A(); if(condition1){     a1 = new B(); }else{     a1 = new A(); } if(condition2){     a1.show(new A()); }else{     a1.show(new B()); } //程序在编译期间无法确定调用的具体类型或者方法,根据不同的条件在运行期间产生不同的类型和方法,就是多态性。

Java实现多态有三个必要条件:继承、重写、向上转型。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
当子类转父类时,自动转型,也就是向上转型,当父类转子类时,需要强制类型转化

向上转型:

B b = new B();A a = b;

向下转型:

A a1 = new B();B b1 = (B)a1;A a2 = new A();B b2 = (B)a;//编译正常,运行报错

这里A a1 = new B(),它在内存中的本质还是B类型,因为赋给A,所以只有A中的方法,能力弱化了,这里B b1 = (B)a1时,由于a1原来的本质类型还是B类型,所有这里强制类型转化成功。
如果A a2 = new A()的话,B b2 = (B)a2;运行时会抛出ClassCastException异常信息,编译器在编译时只会检查类型之间是否存在继承关系,有则通过;而在运行时就会检查它的真实类型,是则通过,否则抛出ClassCastException异常。
所以父类强制转换为子类时只有当引用类型真正的身份为子类时才会强制转换成功


public class Test {    public static void main(String[] args) {        A a1 = new A();        A a2 = new B();        B b = new B();        C c = new C();        D d = new D();        System.out.println("1--" + a1.show(b));        System.out.println("2--" + a1.show(c));        System.out.println("3--" + a1.show(d));        System.out.println("4--" + a2.show(b));        System.out.println("5--" + a2.show(c));        System.out.println("6--" + a2.show(d));        System.out.println("7--" + b.show(b));        System.out.println("8--" + b.show(c));        System.out.println("9--" + b.show(d));          }}
1--A and A2--A and A3--A and D4--B and A5--B and A6--A and D7--B and B8--B and B9--A and D

1.当超类对象引用变量引用子类对象(A a2 = new B())时,超类对象只会重写子类对象的方法,对于子类对象的新方法是不会定义的

这时候的a2中实际的方法应该是:

public class A {    public String show(D obj) {        return ("A and D");    }    public String show(A obj) {        return ("B and A");//B中的show(A obj)方法重写了A中的该方法    } }

2 当new一个相同对象(B b = new B())B会添加超类A中存在且B中不存在的方法

b中的方法为

public class B {    public String show(B obj){        return ("B and B");    }    public String show(A obj){        return ("B and A");    }     public String show(D obj) {//父类的show(D obj)        return ("A and D");    }}

3 对于一个对象引用变量引用子类对象,他会加载对象父类的方法,并重写对象中与子类相同的方法,而当new一个相同对象时,他只会加载对象中不存在且父类中存在的方法,并不会覆盖对象中原有的方法

4 当对象中方法不存在时,它会寻找入参的(super)父类及父类的父类匹配(所有继承关系的类),都不存在,编译就会报错。

B b = new B()C c = new C();b.show(c)//入参为C的方法没有找到,因此找到父类B,访问show(B obj)方法,输出B and B

记:第一次的博客,好好学习Markdown