zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    序列操作
    random模块
    windows系统杀掉explorer.exe进程后黑屏
    Apache + SVN: Could not open the requested SVN filesystem
    使用ps命令批量删除相关进程
    'pybot.bat'不是内部或外部命令,也不是可运行的程序
    安装wxpython的时候报错 “no installation of python 2.7 found in registy”
    wxPython 使用Dialog实现模态对话框
    Python os.system()出现乱码
    Git操作reset --hard失误
  • 原文地址:https://www.cnblogs.com/linkworld/p/7445363.html
Copyright © 2011-2022 走看看