java polymorphism - yaokun123/php-wiki GitHub Wiki

JAVA面向对象-多态

一、定义:某一类事物的多种存在形态。

例:动物中猫,狗。
猫这个对象对应的类型是猫类型(猫 x = new 猫())
同时猫也是动物的一种,也可以把猫称为动物。(动物 y = new 动物())
    动物是猫和狗具体事物中抽取出来的父类型。
    父类型引用指向了子类对象。

二、多态的好处

提高代码的扩展性,前期定义的代码可以使用后期的内容。

abstract class Animal{
    abstract eat(){}
}

class Cat extends Animal{
    public void eat(){
        System.put.println("cat eat");
    }

    public void catchMouse(){
        System.put.println("catch mouse");
    }
}

class DuTaiDemo{
    public static void main(String[] args){
        Animal c1 = new Cat();//状态一
        Cat c2 = new Cat();//状态二
    }
}

三、多态的弊端

前期定义的内容不能使用后期子类的特有内容

四、转型

Animal a = new Cat();//自动类型提升,猫对象提升了动物类型。但是特有功能无法访问
//作用就是可以限制对特有功能的访问。

a.eat();//只能调用Animal中存在的方法eat,不能调用catchMouse


//如果还想用具体猫的特有功能,你可以将该对象进行向下转型。
Cat c = (Cat)a;
c.eat();
c.catchMouse();

注意:对于转型,自始自终都是子类对象在做着类型的变化

Animal a = new Animal();
Cat c = (Cat)a;//此时就不能转化

五、类型判断-instanceof

public static void method(Animal a){
    a.eat();
    if(a instanceof Cat){//instanceof用于判断对象的具体类型,只能用于引用数据类型判断
                         //通常在向下转型前用于健壮性的判断。
        Cat c = (Cat)a;
        c.catchMouse();
    }else if(a instanceof Dog){
        Dog d = (Dog)a;
        d.lookHome();
    }
}

六、多台的特点

  • 成员变量
只看引用变量所属的类(简单说:编译和运行都参考左边)
编译时:参考引用型变量所属的类中是否有调用的成员变量,有,编译通过,没有,编译失败
运行时:参考引用型变量所属的类中是否有调用的成员变量,并运行该类中的成员变量。

class Fu{
    int num = 3;
}

class Zi extends Fu{
    int num = 4;
}

class DuoTaiDemo{
    public static void main(){
        Fu f = new Zi();
        System.out.println(f.num);//3
    }
}
  • 成员函数
编译时:参考引用型变量所属的类中是否有调用的函数,有,编译通过,没有,编译失败
运行时:参考的是对象所属的类中是否有调用的函数。
简单说:编译看左边,运行看右边。
class Fu{
    void show(){
        System.out.println("Fu show");
    }
}

class Zi extends Fu{
    void show(){
        System.out.println("Zi show")
    }
    
}

class DuoTaiDemo{
    public static void main(){
        Fu f = new Zi();
        f.show();//Zi show
    }
}
  • 静态函数
编译时:参考引用型变量所属的类中是否有调用的静态方法。
运行时:参考引用型变量所属的类中是否有调用的静态方法。
简单说:你编译和运行都看左边

其实对于静态方法,是不需要对象的,直接用类名调用即可。

class Fu{
    void show(){
        System.out.println("Fu show");
    }

    static void method(){
        System.out.println("Fu static method");
    }
}

class Zi extends Fu{
    void show(){
        System.out.println("Zi show")
    }

    static void method(){
        System.out.println("Zi static method");
    }
}

class DuoTaiDemo{
    public static void main(){
        Fu f = new Zi();
        f.method();//Fu static method
    }
}