Java多态基础学习

多态基础的学习

多态的基础语法:

    1.向上转型(自动类型转换的意思)
        子----->父
    2.向下转型(强制类型转换的意思)
        父----->子
    注意:
        Java中允许向上转型,也允许向上转型
        无论是向上转型还是向下转型,两种类型之间必须有继承关系
    3.多态指的是:
        父类型引用指向子类型对象
        包括编译阶段和运行阶段
        编译阶段:绑定父类的方法
        运行阶段:动态绑定子类型对象的方法
    4.什么时候向下转型?
        如果想访问的方法是子类中特有的方法,此时使用向下转型

创建Animal类

public class Animal {
    public void move(){
        System.out.println("动物在移动");
    }
}

创建Bird类

public class Bird extends Animal{
    public void move(){
        System.out.println("鸟儿在飞翔");
    }
    public void eatWorm(){
        System.out.println("鸟儿在吃虫");
    }
}

创建Cat类

public class Cat extends Animal{
    public void move(){
        System.out.println("猫在走猫步");
    }
    public void catchMouse(){
        System.out.println("猫在抓老鼠");
    }
}

创建测试类Test01

public class Test01 {
    public static void main(String[] args){
        Animal a1=new Animal();
        a1.move();
        Cat c1=new Cat();
        c1.move();
        Bird b1=new Bird();
        b1.move();
        System.out.println();

        //父类型的引用允许指向子类型的对象
        //向上转型
        Animal a2=new Cat();
        //调用a2的move()方法
        a2.move();//输出“猫在走猫步”

        Animal a3=new Cat();
        Cat x=(Cat)a3;
        x.catchMouse();//“猫在抓老鼠”
        Animal a4=new Bird();
        if(a4 instanceof Cat){//判断是否为猫
            Cat y=(Cat)a4;
            y.catchMouse();//“猫在抓老鼠”
        }else if(a4 instanceof Bird){//判断是否为鸟
            Bird y=(Bird)a4;
            y.eatWorm();//“鸟在吃虫”
        }
    }
}

程序输出结果:

动物在移动
猫在走猫步
鸟儿在飞翔

猫在走猫步
猫在抓老鼠
鸟儿在吃虫

分析a2.move();

java编译阶段:
  对于编译器来说,编译器只知道a2的类型是Animal,所以编译器在检查语法的时候,会去Animal.class字节码文件中找move()方法,找到了,绑定上move()方法,编译通过,静态绑定成功。(编译阶段属于静态绑定)
运行阶段:
  运行阶段的时候,实际上是在堆内存中创建的java对象是Cat对象,所以move的时候,真正参与move的对象是一只猫,所以运行阶段会动态执行Cat对象的move()方法。这个过程属于运行绑定阶段。(运行阶段绑定属于动态绑定)
多态表示多种形态:
  编译的时候是一种形态
  运行的时候是另一种形态

分析向下转型:

Animal a3=new Cat();
注意:只有编译通过的代码才能运行!

提问:a3.catchMouse();这样可以吗?
答案:不可以!
因为:编译器只知道a3的类型是Animal,去Animal.class中找不到catchMouse方法
所以:a3.catchMouse();这样编译会报错

现在必须要向下转型了(强制类型转换)

Cat x=(Cat)a3;
x.catchMouse();//“猫在抓老鼠”

向下转型有风险吗?
Animal a4=new Bird();//表面上a4是一个Animal,运行的时候实际上是个鸟
Cat y=(Cat)a4;    //编译无错,运行阶段Bird不能转换成Cat
          //运行后会出现java.lang.ClassCastException这样的错
y.catchMouse();

怎么避免java.lang.ClassCastException这样的错?

使用运算符:instanceof
 第一:instanceof可以在运行阶段判断动态引用指向对象的类型
 第二:语法:(引用 instanceof 类型)
 第三:instanceof运算符的结果只能是:true/false
 第四:
   假设(c instanceof Cat)为true表示:c引用指向的堆内存中的java对象是一个Cat
   假设(c instanceof Cat)为false表示:c引用指向的堆内存中的java对象不是一个Cat
   任何时候,对类型向下转型时,一定要使用instanceof 运算符进行判断(java规范要求)

Animal a4=new Bird();
        if(a4 instanceof Cat){//判断是否为猫
            Cat y=(Cat)a4;
            y.catchMouse();//“猫在抓老鼠”
        }else if(a4 instanceof Bird){//判断是否为鸟
            Bird y=(Bird)a4;
            y.eatWorm();//“鸟在吃虫”
        }

你可能感兴趣的:(Java多态基础学习)