Fork me on GitHub

Java 之多态

  1. 概述
  2. 好处
  3. 弊端
  4. 转型
  5. 类型判断
  6. 成员变量
  7. 成员函数
  8. 静态函数

概述

定义:某一类事物的多种存在形态.
// 对象的多态性

class 动物
{}

class 猫 extends 动物
{}

class 狗 extends 动物
{}

猫 x = new 猫();
动物 x = new 猫(); // 一个对象, 两种形态

// 猫这类事物即具备着猫的形态, 又具备着动物的形态, 这就是对象的多态性
// 简单说: 就是一个对象对应着不同类型.
// 多态在代码中的体现:  父类或者接口的引用指向其子类的对象.

多态的好处

// 未使用多态之前
abstract class Animal
{
    abstract void eat();
}

class Dog extends Animal
{
    // 覆盖父类 eat() 方法
    void eat()
    {
        System.out.println("啃骨头");
    }

    // 狗类特有方法 看家
    void lookHome()
    {
        System.out.println("看家");
    }
}

class Cat extends Animal
{
    // 覆盖父类 eat() 方法
    void eat()
    {
        System.out.println("吃鱼");
    }

    // 猫类特有方法 抓老鼠
    void catchMouse()
    {
        System.out.println("抓老鼠");
    }
}

class DuoTaiDemo
{
    public static void main(String[] args)
    {
        Cat c = new Cat();
        Dog d = new Dog();

        // 调用猫 eat() 方法
        method(c);
        // 调用狗 eat() 方法
        method(d);
    }

    // 为提高代码复用性, 创建方法
    public static void method(Cat c)
    {
        c.eat();
    }

    // 函数重载
    public static void method(Dog d)
    {
        d.eat();
    }
}

// 问题分析: 随着动物的增多, 都需要增加与该动物相匹配的 eat() 方法.
// 升级版

class DuoTaiDemo
{
    public static void main(String[] args)
    {
        Cat c = new Cat();
        Dog d = new Dog();

        method(c); // Animal a = new Cat();
        method(d); // Animal d = new Dog();
    }

    // 多态, 此处只需要定义一个方法, 狗类和猫类都能使用
    public static void method(Animal a)
    {
        a.eat();
    }
}

多态的好处:

  • 提高了代码的扩展性, 前期定义的代码可以使用后期的内容.
    例如: 前期定义的 method() 方法, 在新增加动物(如猪, 属于后期的内容)也可以使用.

多态的弊端:

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

多态的前提:

  • 必须有关系, 要么继承,要么实现
  • 要有覆盖

转型

  1. 向上转型: 限制对特有功能的访问
  2. 向下转型: 为了使用子类中的特有方法
class DuoTaiDemo
{
    public static void main(String[] args)
    {
        Animal a = new Cat(); //此处猫对象提升为了动物类型, 即自动类型提升. 猫类型的特有功能无法访问
                              // 自动类型提升的作用: 就是限制对特有功能的访问
                              // 专业讲: **向上转型**
        a.eat();

        // 如果需要使用具体动物猫的特有功能
        // 可以将该对象进行**向下转型**
        Cat c = (Cat)a; // 向下转型的目的是为了使用子类中的特有方法
        c.catchMouse(); // 调用猫的特有方法

        // 注意: 对于转型, 自始至终都是子类对象(同一种动物)在做着类型的变化
        Animal a1 = new Dog();
        Cat c1 = (Cat)a1; // 错误: ClassCastException 类型转换异常
    }
}

对象类型判断 instanceof

instanceof: 用于判断对象的具体类型, 只能用于引用数据类型判断.

通常在向下转型前用于健壮性的判断.

多态时,成员的特点

  1. 成员变量
  2. 成员函数
  3. 静态变量

成员变量(了解)

编译时: 参考引用型变量所属的类中是否有调用的成员变量, 有, 编译通过; 没有, 编译失败.
运行时: 参考引用型变量所属的类中是否有调用的成员变量, 并运行该所属类中的成员变量.
简单说, 编译和运行都参考等号左边.

class Fu
{
    int num = 3;

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

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

class Zi extends Fu
{
    int num = 4;

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

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

class DuoTaiDemo
{
    public static void main(String[] args)
    {
        Fu f = new Zi(); // 子类对象初始化完成后,子类对象内存地址中既有子类的num, 又有父类的 num. 
        System.out.println(f.num); // 结果为 3
    }
}

成员函数 (非静态函数)

编译时, 参考引用类型变量所属的类中是否有调用的函数. 有, 编译通过; 没有, 编译失败.
运行时, 参考的是对象所属的类中是否有调用的函数.
简单说, 编译看左边, 运行看右边.

备注: 非静态函数只能通过对象实现调用, 引用类型变量执行对象所在的内存地址.

class DuoTaiDemo
{
    public static void main(String[] args)
    {
        Fu f = new Zi();
        f.show(); // 结果为 zi show
    }
}

// 示例2: 写出程序结果
interface A{}
class B implements A
{
    public String func()
    {
        return "func";
    }
}
class Demo
{
    public static void main (String[] args)
    {
        A a = new B();
        System.out.println(a.func()); //多态, 对于非静态方法, 编译看左边,运行看右边
                                      // 编译失败, 因为 a 所属的 A 接口中没有定义 func 方法
    }
}

静态函数

编译时, 参考引用类型变量所属的类中是否有调用的静态方法;
运行时, 参考引用类型变量所属的类中是否有调用的静态方法;
简单说, 编译和运行都看左边.

备注: 静态函数的调用不需要依赖对象, 直接用类名调用即可.因此,静态函数不涉及多态性.

class DuoTaiDemo
{
    public static void main(String[] args)
    {
        Fu f = new Zi();
        f.method(); // 结果 fu static method
    }
}



_参考资料_ - [JavaSE 基础视频](https://www.bilibili.com/video/av3096713/#page=2)
posted @ 2017-08-28 19:16  小a的软件思考  阅读(157)  评论(0编辑  收藏  举报