面向对象四——多态

2018-02-07  本文已影响0人  嗷老板

一、多态的概述

  多态其实就是同一个对象在不同时刻体现出来的不同状态,例如水在不同的温度下具有的三种状态。

多态的前提:
  1、有继承关系
  2、有方法重写
  3、有父类引用指向子类对象
例:

public class DuoTaiDemo {
    public static void main(String[] args) {
        //有父类引用指向子类对象
        Animal a = new Cat();
    }
}

二、多态中成员访问特点

1、成员变量的访问特点:
  ——编译看左边,运行看左边
2、成员方法的访问特点:
  ——编译看左边,运行看右边
例:

//定义一个父类Animal
public class Animal {
    //成员变量
    public int age = 40;
    //成员方法
    public void eat() {
        System.out.println("吃东西");
    }
}

//然后定义一个子类Cat继承Animal
public class Cat extends Animal {
    public int age = 20;
    public int weight = 10;
    
    public void eat() {
        System.out.println("猫吃鱼");
    }
    
    public void playGame() {
        System.out.println("猫捉迷藏");
    }
}

//定义测试类
public class DuoTaiDemo {
    public static void main(String[] args) {
        //多态
        Animal a = new Cat();
        System.out.println(a.age);//40
        //System.out.println(a.weight);
        //父类中没有weight变量,无法输出
        a.eat();//结果:猫吃鱼
        //a.playGame();
        //由于父类中没有playGame()方法,因此无法调用
    }
}

注意:
  多态中成员变量和成员方法的访问特点不同主要是因为成员方法在子类中有重写,但是变量没有。

三、多态的好处和弊端

1、好处

  多态提高了程序的扩展性,具体体现在:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作

2、弊端

  多态无法访问子类特有的功能。在上面的案例中,测试类中的对象a无法调用方法playGame(),就是因为这个方法是子类特有的方法,父类中没有,因此无法访问。
  那么如何访问子类中的特有功能呢?——通过多态的转型。

四、多态的转型

  多态中的转型有两种:
  (1)向上转型:从子到父,父类引用指向子类对象
  (2)向下转型:从父到子,父类引用转为子类对象
还是利用上面的例子:

public class DuoTaiDemo {
    public static void main(String[] args) {
        //多态
        Animal a = new Cat(); //向上转型
        a.eat();

        //无法访问子类特有的方法
        //a.playGame();

        //访问子类特有的方法,有两种方式:
        //第一种是直接重新定义一个子类的对象,通过子类的对象调用方法
        Cat c1 = new Cat();
        c1.eat();
        c1.playGame();
        

        //第二种就是向下转型
        Cat c2 = (Cat)a;
        c2.eat();
        c2.playGame();
    }
}

注意:
  1、使用向下转型必须要注意转型的那个对象的类型和原来的类型是否相同,也就是Cat类的对象只能转型成为Cat类,不能转型为Dog类,否则就会抛出类型转换错误的异常。
  2、一个对象在向下转型之前一定发生过向上转型。

五、多态中的内存图

//定义父类Animal
public class Animal{
    public void eat(){}
}

//定义子类Cat继承自Animal类
public class Cat extends Animal{
    public void eat(){}
    public void playGame(){}
}

//定义子类Dog继承自Animal
public class Dog extends Animal{
    public void eat(){}
}

//定义测试类
public class DuoTaiDemo{
    publc static void main(String[] args){
        //向上转型
        Animal a = new Cat();
        a.eat();

        //向下转型
        Cat c = (Cat)a;
        c.eat();
        c.playGame();

        //向上转型
        a = new Dog();
        a.eat();

        //向下转型
        Cat cc = (Cat) a;//ClassCastException 类型转换异常
        cc.eat();
        cc.playGame();
    }
}
多态的内存图
上一篇下一篇

猜你喜欢

热点阅读