JAVA:多态的认识与理解

一,对象的多态

①,一个对象的编译类型和运行类型可以不一致。

②,编译类型在定义对象时,就确定了,不能改变。

③,运行类型是可以变化的。

④,编译类型看定义时=号的左边,运行类型看=号的右边。

二,多态的向上转型

①,本质:父类的引用指向了子类的对象。

②,语法:父类类型  引用名=new  子类类型();

③,特点:编译类型看左边,运行类型看右边。

   可以调用父类中的所有成员(需遵守访问权限),

    不能调用子类中特有成员。

    最终运行效果看子类的具体实现。

    在测试类运行时,系统会先在运行类型中寻找在父类中共有的方法,如果运行类型中找不到共有的方法时,系统则会掉头去找编译类型中要寻找的方法,所以是先在运行类型寻找,再到编译类型寻找。

源代码:测试类

package poly_practice;
public class Test {
    public static void main(String[] args) {
          Animal animal=new Dog();        //向上转型
          animal.cry();
          animal.look();
        System.out.println(animal.a);    
          Dog dog=(Dog) animal;         //向下转型
          dog.cry();
          dog.shout();
        System.out.println(dog.a);

    }
}

父类Animal:源代码

package poly_practice;
public class Animal {
    public int a=10;
public void cry() {
    System.out.println("动物叫唤。。");     
}
public void look(){
    System.out.println("小狗在看树..");
}
}

 子类Dog:源代码

package poly_practice;
public class Dog extends Animal {
    public int a=20;
    public void cry(){
        System.out.println("小狗汪汪叫。。");     //共有属性
    }
    public void shout(){
        System.out.println("小狗在乱叫。。");     //特有属性
    }
}

如上图,在子类中存在有方法的重写cry方法,父类中也有cry方法,为共有的方法,而dog是运行类型,所以在测试类中的向上转型中的animal.cry();代码运行时,系统会先到子类的dog中看看有没有cry方法,发现有,则运行Dog中的cry方法,所以最终的显示结果的第一条会是小狗汪汪叫。。,测试类的下一行代码是animal.look();,同样,系统会在子类的dog中寻找看看有没有这个look方法,发现没有,则再到编译类型即父类中去寻找,发现look方法在父类中,则输出小狗在看树..

 

三,多态的向下转型

①,语法:子类类型   引用名=(子类类型)    父类引用:

②,只能强转父类的引用,不能强转父类的对象。

③,要求父类的引用必须指向的是当前目标类型的对象。

④,可以调用子类类型中所有的成员。

如上图中的源代码块引用,测试类中的注释向下转型,这个时候转型了的对象引用dog就可以访问到子类dog的特有方法shout();它的访问顺序也是现在子类的dog中看看有没有要输出的方法,如果子类中有,就直接输出,不再往下看,如果没有,则往下找到父类中的方法,看有没有目标方法。这时父类中有子类没有的look方法,所以在向下转型中添加一个dog.look();,系统会先在子类中查找,发现没有,则往下到父类中查找,发现有,就直接输出小狗在看树..

 四,属性的重写问题

①,属性没有重写之说,属性的值看编译类型。

例如源代码:上图中的块引用测试类中有写到,在向上转型的那一步后,输出了一句System.out.println(animal.a);,因为向上转型的那一步中编译的是Animal animal=new Dog();,编译类型是Animal,所以输出语句时,直接查看animal父类中的属性a的值就可以了,也就是直接输出animal中的属性a的值10,而不会像查找重写的方法那样,现在运行类型中查看一遍,如果没有,再找编译类型。

接着在向下转型中,那一步的代码是Dog dog=(Dog) animal;,所以编译类型就是dog,所以在执行System.out.println(dog.a);时,就直接输出Dog类中的属性a的值20即可。

五,instanceof 比较操作符,用于判断对象的运行类型是否为比较类型的类型或者子类型

如下图源代码:创建一个AA父类,BB子类,在测试类中创建一个对象BB,使用bb去引用,那么bb的运行类型就是BB,BB是比较类型AA的子类,所以输出结果为true,如果创建一个AA对象,使用aa去引用这个AA对象,再用aa instanceof AA,则aa的运行类型是AA,AA是比较类型AA的类型,所以输出结果还是true。

package poly_practice;
public class Test {
    public static void main(String[] args) {
        BB bb=new BB();
        AA aa=new AA();
        System.out.println(bb instanceof AA);
    }
}
class  AA{}
class BB extends AA{}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值