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

            例:动物中猫,狗。

                猫这个对象对应的类型是猫类型

                猫 x = new 猫();

             同时猫也是动物中的一种,也可以把猫称为动物。

                动物  y = new 猫();

        动物是猫和狗具体事物中抽取出来的父类型。

        父类型引用指向了子类对象。

    

2.程序中体现:

        父类或者接口的引用指向或者接收自己的子类对象。

    

3.多态的好处:

    提高了程序的扩展性,前期的程序可以使用后期的内容。在思想上也有不同,以前是面对一个对象调用,对象多了调用麻烦。

    相当于指挥一批对象做事情,将复杂事情简单化。

 

4.多态的弊端:

    多态的出现,虽然可以让前期的程序使用后期的内容。

    不可以使用子类的特有内容

    多态中的对象具有不同的类型,当对象具有父类类型的时候,只能调用父类的方法,不能调用父类中没有的方法。如果子类中有与父类相同的方法,对象就会调用子类覆盖了父类的方法主体。

    

5.前提:

        需要存在继承或者实现关系

        要有覆盖操作



多态的特点    

    1,成员变量。

    多态调用时,对于成员变量,无论是编译还是运行,结果只参考引用型变量所属的类中的成员变量。

        参考等号左边。

     

    2,成员函数。

    多态调用时,对于成员函数,

    编译时,参考引用型变量所属的类中是否有被调用的方法。有,编译通过,没有编译失败。

    运行时,参考的是对象所属的类中是否有调用的方法。

        编译看左边,运行看右边。

     

     

    3,静态函数。

        静态函数直接被类调用,和对象没关系,哪个类在调用这个静态函数,就运行哪个类的中的静态函数。 

            编译和运行都看左边。 

     

    4.构造函数

      初始化,子类默认继承super();多态时,初始化super()和子类本身构造函数。


多态的转型

class  AnimalDemo2
{
    public static void main(String[] args) 
    {
    /
    Animal a = new Cat();  //向上转型(类型提升)。子类对象提升为了父类型。
    /*
    提升的好处:就是提高了扩展性。隐藏了子类型。
    提升的局限性:只能使用父类中的方法。 如果子类有覆盖的话,运行的是子类的内容。
    */
    a.eat();
     
    //如何使用抓老鼠行为。
    Cat c = (Cat)a; //向下转型(强制类型转换)。好处:可以使用具体子类型的特有方法。
    c.catchMouse();
    //记住:对于子父类转型动作,自始自终都是子类对象在做着类型的转换而已。
    }
 }

多态的类型判断关键字instanceof

向下转型需要注意:父类型向下转成子类型,因为子类型不唯一,所以,需要进行判断。

       类型转换异常的时候,编译可以通过,运行时创建对象就会出问题。

如何判断对象类型呢? 用到一个关键字完成instanceof。 对象  instanceof  or接口

记住:一旦向下转型,必须先instanceof判断


 

        Animal an = new Cat();
        Dog d=(Dog)an  //运行时报错,猫的对象不能转为狗的类型。
 
         if(an instanceof Dog){
              Dog d = (Dog)an;    //Class Cast Exception
              d.lookHome();
         }else if(an instanceof Cat){
              Cat c = (Cat)an;
              c.catchMouse();
         }

     开发的时候不会挨个判断对象的子类型,通常只会判断一种子类型而已,最终只会用的一种子类型,就判断是不是这种子类型就可以了。如果是,直接就可以转一下,如果不是,直接告诉类型错误。一般情况下,一个功能只会用的一种子类型,如果有多个子类型,就分多钟功能来写。


接口与多态举例

/*
为了后期扩展笔记本的功能,比如使用手握式鼠标。 
加很多外围设备,又要降低外围设备和笔记本的耦合性。
所以可以通过定义接口来解耦。
*/
//先定义规则。
interface USB{
    void open();
    void close();
}
 
class USBMouse implements USB{
    public void open(){
        System.out.println("usemouse open");
    }
    public void close(){
        System.out.println("usemouse close");
    }
}
 
//描述笔记本
class NoteBook{
    void run(){
        System.out.println("notebook run");
    }
    void useUSB(USB usb){  //多态。USB usb = new USBMOuse();
        if(usb!=null){
            usb.open();
            usb.close();
        }
    }
}


class  USBDemo{
    public static void main(String[] args) {
        NoteBook book = new NoteBook();
        book.run();
        book.useUSB(null);
        book.useUSB(new USBMouse());
    }
}