面向对象三大特征之一:多态

时间:2023-02-10 15:44:04

一,背景

为什么要是用多态?

举个很简单的例子(下面很多理解的概念都以这个例子为基础):

//父类
class abstract Pet{
     public abstract void eat();
}

 

//子类1
//狗吃东西的方法
class
Dog{ public void eat(){ System.out.print("..."); } }
//子类2
//猫
吃东西的方法 class Cat{ public void eat(){ System.out.print("..."); } }

那我们在主人类里面喂食就应该写成:

class Master{
      public void feed(Dog dog){
        dog.eat();
        }
      public void feed(Cat cat){
        cat.eat();
        }
}

言外之意就是每增加一个子类进食方法,那master类里面就要多加一个喂食方法

代码扩展性和维护性太差了,所以利用多态性可以把子类的进食方法写成:

class Master{
       public void feed(Pet pet){
       pet.eat();
       }
}  //所有的子类吃东西都是这个公式
//如再创建一个运行类
public class Test01 {
    public static void main(String[] args) {
         Pet pet=null;
           pet=new Dog(实例的参数值);
          pet.eat();
           pet=new Cat(实例的参数值);
          pet.eat();
      }
}

 

二,什么是多态

同一事物,由于条件不同,经过这个条件处理之后的结果也不同(举例)

面向对象三大特征之一:多态

程序中的多态

统一引用类型,经过不同子类相同处理方法,导致结果不同

如上例:同一引用类型指的就是父类 pet类

             不同子类指的是狗dog类,cat猫类等等等

               相同处理方法都是eat方法

              结果不同(狗是吃狗粮,猫是吃猫粮)

三,实现多态的步骤

1,编写父类

2,编写子类(子类一定要重写/实现父类的方法)上例中就有说明,父类中eat方法是抽象的,所以后面的子类都实现了父类的这个方法。

3,运行时,父类类型引用子类对象(如上述创建的运行类),Pet pet=new God(参数值);

四,多态的实现形式

1,父类类型引用子类对象(Pet pet=new God(参数值);)    //上面两行才介绍过了的

    只要是多态,全部都是这种格式

2,父类作为方法形参实现多态

public void feed(Pet pet){
     System.out.print(...);
     pet.eat();
}

这第二种就是和开头介绍为什么要用多态举的例子一样的格式

3,父类作为返回值实现多态

public Pet adoptPet(int type) {
        Pet pet = null;
        if(1 == type) {
            pet = new Dog();
        }else if(2 == type) {
            pet = new Penguin();
        }else if(3 == type){
            pet = new Cat();
        }
        return pet;
    }

(这个本人也弄得不是特别清楚,只知道父类类型是放在返回值位置上,上述例子用在输入数字,然后挑选宠物)

五,类型转换

早在之前学习基本数据类型的时候就学过类型转换(分为自动类型转换和强制类型转换)

当然多态里面也是这两种

1,(自动转换)向上类型转换(子类自动转换成父类)

    Pet pet=new Dog();

2.1,(强制转换)向下类型转换(父类转换成子类)

子类类型 引用=(子类) 父类对象;

   *儿子要当爹容易当,但是要爹当儿子就得用武力威胁爹

    一般而言,需要判断父类对象的真实类型,用instanceof关键字

2.2   instanceof

public static void main(String[] args) {
        Dog dog = new Dog();
        System.out.println(dog instanceof Dog); //true   Dog是dog的爹
        System.out.println(dog instanceof Pet); //true   Pet是爷爷,Dog是爹,dog是儿子
        System.out.println(dog instanceof Object); //true Object是所有类的祖宗,所以更不用说了,肯定正确
    }

如果要调用子类特有的方法时,一定要强制类型转换,通过instanceof鉴别具体类型

举例下面几种宠物的玩耍方法,那就要先instanceof一下具体是那种宠物

public void play(Pet pet){
      if(pet instanceof Dog){   //如果宠物是狗
           Dog dog = (Dog) pet;   //二话不说先强转
           dog.catchFlyDisc();    //然后再附上子类(狗类)特有的play方法
           }
             else if(pet instanceof Cat){
                Cat cat=(Cat)pet;
                cat.hide-seek;
                }
}