java中的多态

两个重要概念: 1,向上转型 (子类到父类) 2,向下转型(父类到子类)

java允许以上两种类型,且两种类型之间必须有继承关系。

什么是多态: 多种形态(编译和运行是两种形态),多种状态。

      父类型引用指向子类型对象(编译阶段静态绑定父类型方法,运行阶段动态绑定子类型对象的方法)

java程序分为编译阶段和巡行阶段。

  编译阶段:编译器在检查语法的时候,会静态绑定(编译阶段不会new对象) 即找到父类中和子类同名的方法,并进行静态绑定。编译通过。

  运行阶段:在堆内存中实际创建的是子类的对象,所以在调用方法的时候,实际调用的是子类的方法,这个过程属于运行阶段绑定。(运行阶段绑定属于动态绑定)

 

****什么时候向下转型,当父类型的引用想访问子类型中特有的方法的时候,此时就必须进行向下转型。

class Animal{
    public void move(){
        System.out.println("animal is moving");
    }
}

class Cat extends Animal{
    public void move(){
        System.out.println("cat is catching the mouth");  //此处为方法覆盖
    }
    public void walk(){
        System.out.println("cat is walking");
    }
}

class Bird extends Animal{
    public void move(){
        System.out.println("bird is flying");  //此处也是方法覆盖override 覆盖的是Animal中的move方法
    }
}


public class DtTest{
    public static void main(String[] args){
        Animal cat = new Cat(); //此处就是动态绑定,即在编译阶段,声明一盒animal类型的变量cat,并不生成对象,因为在Animal中有move对象,所以可以编译通过
        cat.move();
        Animal bird = new Bird(); //在运行阶段,会在堆内存中生成cat对象,且在实际运行的时候 实际是调用cat类的(子类的)move方法。
        bird.move();
        
        
        
        Animal cat1 = new Cat();
        //cat1.walk();  //错误: 找不到符号
        Cat x = (Cat)cat1; //此处就是强制类型转换,专业术语为向下转型,一般情况下,强制类型转化多称呼与基本数据类型的时候。
        x.walk();
    }
}

 java中的向下转型风险

instanceof运算符:可在运行阶段动态判断

1,instanceof可以在运行阶段动态判断引用指向的对象的类型。

2,语法为  a instance b  返回的为 true 和 false  即判断 a引用指向的堆内存中的java对象是不是一个b类型的类

注意:任何时候只要有强制类型转换一定要使用instanceof进行判断。

class Animal{
    public void move(){
        System.out.println("animal is moving");
    }
}

class Cat extends Animal{
    public void move(){
        System.out.println("cat is catching the mouth");  //此处为方法覆盖
    }
    public void walk(){
        System.out.println("cat is walking");
    }
}

class Bird extends Animal{
    public void move(){
        System.out.println("bird is flying");  //此处也是方法覆盖override 覆盖的是Animal中的move方法
    }
}


public class DtTest{
    public static void main(String[] args){
        Animal cat = new Cat(); //此处就是动态绑定,即在编译阶段,声明一盒animal类型的变量cat,并不生成对象,因为在Animal中有move对象,所以可以编译通过
        cat.move();
        Animal bird = new Bird(); //在运行阶段,会在堆内存中生成cat对象,且在实际运行的时候 实际是调用cat类的(子类的)move方法。
        bird.move();
        
        
        
        Animal cat1 = new Cat();
        //cat1.walk();  //错误: 找不到符号
        Cat x = (Cat)cat1; //此处就是强制类型转换,专业术语为向下转型,一般情况下,强制类型转化多称呼与基本数据类型的时候。
        x.walk();
        
        //Animal cat2 = new Cat();
        //Bird bird1 = (Bird)cat2;
        //bird1.walk();
        Animal bird1 = new Bird();
        if(bird1 instanceof Cat){
            Cat c = (Cat)bird1; //此时就是可以编译通过,但是运行时错误。 因为cat和bird两个类之间是没有继承的
            c.walk();} //(向下转型风险)Exception in thread "main" java.lang.ClassCastException: class Bird cannot be cast to class Cat (Bird and Cat are in unnamed        //module of loader 'app')
                  //at DtTest.main(DtTest.java:41)
    }//此时就是可以编译通过,但是运行时错误。 因为cat和bird两个类之间是没有继承的
}
//instanceof的用到,解决未知的对象类型
public class DtTest1{
    public static void main(String[] args){
        Animal x = new Cat();
        Animal y = new Bird();
        
        if(x instanceof Cat){
            Cat c = (Cat)x;
            c.walk();
        }else if(x instanceof Bird){
            Bird b = (Bird)x;
            b.sing();
        }
        
        if(y instanceof Cat){
            Cat c = (Cat)y;
            c.walk();
        }else if(y instanceof Bird){
            Bird b = (Bird)y;
            b.sing();
        }
        
    }
}

 

posted @ 2022-06-22 14:44  _八级大狂风  阅读(922)  评论(0编辑  收藏  举报