zoukankan      html  css  js  c++  java
  • 面向对象的三大特性之三——多态


    typora-copy-images-to: images

    什么是多态?

    举例:

    一般对象这样创建:

    猫 x = new 猫();建立了猫的对象,并通过本类引用x指向了这个猫对象;

    多态中的对象:

    动物 x1 = new 猫();父类引用x1指向了子类这个猫对象;

    x1这个引用即具备猫的形态,又具备着动物的形态。

    简单的说:就是一个对象对应着不同类型,在代码中如何体现呢?父类或者接口的引用指向其子类的对象。

    多态存在的三个前提:

    1. 要有继承关系
    2. 子类重写父类方法
    3. 父类引用指向子类对象

    多态举例

    父类Animal

    class Animal {
        int num = 10;
        static int age = 20;
    
        public void eat() {
            System.out.println("动物吃饭");
        }
        public static void sleep(){
            System.out.println("动物睡觉");
        }
        public void run(){
            System.out.println("动物在奔跑");
        }
    }
    

    子类Cat

    class Cat extends Animal{
        int num  = 66;
        static int age = 40;
        String name = "tomCat";
    
        public void eat() {
            System.out.println("猫吃饭");
        }
    
        public static void sleep(){
            System.out.println("猫睡觉");
        }
    
        public void catMouse(){
            System.out.println("猫在抓老鼠");
        }
    }
    

    测试类

    /**
     * @ClassName: DuotaiDemo
     * @author: benjamin
     * @version: 1.0
     * @description: 多态举例
     */
    public class DuotaiDemo {
        public static void main(String[] args) {
    
            // 父类引用指向了子类对象
            Animal am = new Cat();
    
            am.eat();
            am.sleep();
            am.run();
    
            System.out.println(am.num);
            System.out.println(am.age);
        }
    }
    

    结果

    猫吃饭
    动物睡觉
    动物在奔跑
    10
    20

    发现问题

    子类重写了非静态成员方法eat(): 猫吃饭

    子类重写了静态成员方法sleep(): 动物睡觉

    子类未重写父类成员方法run():动物在奔跑

    总结:

    成员变量:编译看左边(父类),运行看左边(父类)

    成员方法:编译看左边(父类),运行看右边(子类)

    静态方法:不涉及对象的多态性。因为静态函数随着类的加载而加载。直接用类名调用即可。

    特点举例

    成员变量

    简单地说:编译和运行都参考等号的左边

    编译时:参考引用型变量所属的类中是否有调用的成员变量,有,编译通过,没有,编译失败;

    运行时:参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。

    举例:

    执行DuotaiFu f = new DuotaiZi(); 此时子类型提升为父类型,用父类型找父

    public class DuotaiDemo2 {
        public static void main(String[] args) {
    
            DuotaiFu f = new DuotaiZi();
    
            System.out.println(f.num);//3
    
        }
    
    }
    class DuotaiFu{
        int num = 3;
    }
    
    class DuotaiZi extends DuotaiFu{
        int num = 4;
    }
    

    内存图解

    成员函数(重点)

    非静态函数

    简单说:编译时看左边,运行时看右边

    编译时:参考引用变量所属的类中是否有调用的函数,有,编译通过,没有,编译失败;

    运行时:参考的是对象所属的类中是否有调用的函数。

    举例:

    show函数运行时,持有this引用,指向了0x0034的对象(new Zi() ),找到该对象的show方法运行;

    public class DuotaiDemo2 {
        public static void main(String[] args) {
    
            DuotaiFu f = new DuotaiZi();
            f.show();
        }
    }
    class DuotaiFu{
    
         void show(){
             System.out.println("fu show...");
         }
    }
    
    class DuotaiZi extends DuotaiFu{
        void show(){
            System.out.println("zi show...");
        }
    }
    // zi show...
    

    内存图解:

    静态函数

    不涉及对象的多态性。因为静态函数随着类的加载而加载。直接用类名调用即可。

    编译时:参考引用型变量所属的类中是否有调用的静态方法;

    运行时:参考引用型变量所属的类中是否有调用的静态方法;

    举例:

    非静态方法必须绑定到指定的对象上,才能运行;

    package java_demo_2;
    
    public class DuotaiDemo2 {
        public static void main(String[] args) {
    
            DuotaiFu f = new DuotaiZi();
            f.method();
            DuotaiFu.method();
            DuotaiZi.method();
    
        }
    
    }
    class DuotaiFu{
    
         void show(){
             System.out.println("fu show...");
         }
    
         static void method(){
             System.out.println("父类静态方法");
         }
    }
    
    class DuotaiZi extends DuotaiFu{
        void show(){
            System.out.println("zi show...");
        }
        static void method(){
            System.out.println("子类静态方法");
        }
    }
    

    结果:

    父类静态方法
    父类静态方法
    子类静态方法

    向上转型和向下转型

    向上转型:

    • 概念:Animal a = new Cat(); 猫提升成动物类型,但是猫特有的功能无法访问。
    • 目的:限制对特有功能的访问,专业讲就是向上转型。

    向下转型:

    • 概念:如果还想用具体动物猫的特有功能,可以将对象进行向下转型。如:

      Cat c = (Cat) am;

      c.catchMouse();

    • 目的:为了使用子类中的特有方法。

    举例:

    // 向上转型
    Animal am = new Cat();
    am.eat();
    
    // 向下转型
    Cat cat = (Cat) am;
    cat.catMouse();
    System.out.println(cat.name);
    
    输出
    猫在抓老鼠
    tomCat
    

    类型转换异常:

    对于转型,自始至终都是在类对象在做着类型的变化。猫-动物-猫

    Cat c2 = (Cat) d;
    c2.catchMouse();//ClassCastException
    // 不能把一个猫——动物——狗;报错
    

    类型判断:

    instanceof :运行时指出对象是否是特定类的一个实例,只能用于引用数据类型判断,通常在向下转型前用于健壮性的判断。

    举例:

    public class DuotaiDemo {
        public static void main(String[] args) {
            //向上转型
            Animal c = new Cat();
            Animal d = new Dog();
    
            method(c);
            method(d);
    
        public static void method(Animal a){ 
    
            a.eat();
            if(a instanceof Cat){
    
                Cat c = (Cat) a;//向下转型,执行对象的特有方法;
                c.catchMouse();
            }
            else if(a instanceof Dog){
                Dog d = (Dog) a;
                d.lookHome();
            }
        }
    }
    

    参考链接

    JAVA的多态用几句话能直观的解释一下吗? - 程序狗的回答 - 知乎
    https://www.zhihu.com/question/30082151/answer/120520568

  • 相关阅读:
    POJ 1328 Radar Installation
    POJ 1700 Crossing River
    POJ 1700 Crossing River
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3069 Saruman's Army(贪心)
    poj 3069 Saruman's Army(贪心)
    Redis 笔记与总结2 String 类型和 Hash 类型
    数据分析方法有哪些_数据分析方法
    数据分析方法有哪些_数据分析方法
  • 原文地址:https://www.cnblogs.com/benjieqiang/p/11481801.html
Copyright © 2011-2022 走看看