• Java_多态/动态绑定机制/多态数组/多态参数


    多态

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    方法重载 和 方法重写 都体现出了多态。

    在这里插入图片描述
    编译类型:是在编译时由声明该变量时使用的类型决定的,已经在编译时确定好了,有多少的内存空间,这是无法改变的。
    运行类型:由实际赋值给该变量的对象决定,是可以重新赋值内存空间来修改的。


    在这里插入图片描述
    在这里插入图片描述
    Pig的构造方法,先调用父类的构造方法,先将父类的成员进行初始化,然后再对子类进行初始化。
    在这里插入图片描述
    Animal是父类,但是我们可以传子类进去,因为父类的内存位置是与子类一样的,我们仍可以找到这块空间。
    在这里插入图片描述
    在这里插入图片描述
    引用对象animal可以调用父类中的所有成员(遵守访问权限),但是不能调用子类的特有成员。
    这是因为animal的编译类型是Animal,我们只知道Animal的内存位置,并不知道Cat的内存位置。
    在编译阶段,能调用哪些成员,是由编译类型来决定的。


    当有方法重写时,优先调用子类的方法,这与前面的方法调用规则一致。
    这是因为方法重写将原先的那块空间给重新赋值了,所以父类能够访问到子类的方法。


    在这里插入图片描述
    在这里插入图片描述

    Cat cat = (Cat)animal;
    cat.catchMouse();
    
    • 1
    • 2

    将animal的编译类型Animal强制类型转换成Cat类型。


    在这里插入图片描述


    在这里插入图片描述
    父类的引用必须指向的是要强制类型转换的对象。
    e.g.父类为Animal animal(父类的引用) = new Cat();
    Cat cat = (Cat)animal; // OK
    Dog dog = (Dog)animal; // err


    在这里插入图片描述
    在这里插入图片描述
    instanceof(比较操作符)
    in-内 + st-站 + ance表n. -> 站在里面的东西(例子)
    作用:判断一个对象是否为一个类的实例。

    在这里插入图片描述
    在这里插入图片描述
    AA aa = new BB(); // 向上转型
    aa的编译类型为AA父类,运行类型为BB子类
    这边看的是运行类型,所以都是true。
    在这里插入图片描述
    这里是一个父类的对象引用 是否为 一个子类的实例,这就错了。


    动态绑定机制

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    System.out.println(a.sum());
    a的运行类型是B,所以JVM会先去看B类中有没有sum()
    在这里插入图片描述
    这时在B类中没有sum()方法,继承机制发动,他会在父类中找有没有sum()方法,如果没有报错。
    在这里插入图片描述
    在父类中有,里面又有一个getI()方法,动态绑定机制发动(动态绑定会自动将父类的方法绑定到子类上),
    在这里插入图片描述
    发现有getI()这个方法,return的 i 为就是子类的i


    多态数组

    在这里插入图片描述
    在这里插入图片描述
    main

    package com.Test.pkg;
    
    public class main {
       public static void main(String[] args) {
           // 创建1个Person对象,2个Stu..对象,2个Tea..对象,放在数组中
           Person[] persons = new Person[5];
           persons[0] = new Person("jack", 20);
           persons[1] = new Student("jack", 18, 100);
           persons[2] = new Student("smith", 19, 30.1);
           persons[3] = new Teacher("scott", 30, 20000);
           persons[4] = new Teacher("king", 50, 25000);
    
           for (int i = 0; i < persons.length; ++i) {
               // 它会先去运行机制里找有没有say()这个方法,
               // 这个就是动态绑定机制了~
               System.out.println(persons[i].say());
               // 判断persons[i]的运行类型是不是Student
               if (persons[i] instanceof Student) {
                   ((Student)persons[i]).study();
               } else if (persons[i] instanceof Teacher) {
                   ((Teacher)persons[i]).teach();
               }
           }
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    Person

    package com.Test.pkg;
    
    public class Person {
        // 1.成员属性
        private String name;
        private int age;
        // 2.构造器
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        // 3.属性的get和set方法
        // 顺口溜
        // get:要得值,必返回(只要是方法都得有返回值,构造器除外)
        // set:要改值,必传值
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
        public String say() {
            return "name = " + name + "\t" + " age = " + age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    Student

    package com.Test.pkg;
    
    public class Student extends Person {
        // 因为这里子类继承了父类,所以先要调用父类Person的构造器
        // 父类Person的默认构造器被覆盖了,所以我们要用super来调用
        private double score;
        // 子类的构造器
        public Student(String name, int age, double score) {
            super(name, age);
            this.score = score;
        }
        public double getScore() {
            return score;
        }
        public void setScore(double score) {
            this.score = score;
        }
        // 子类方法重写say方法
        public String say() {
            return super.say() + " score = " + score;
        }
        public void study() {
            System.out.println("学生:" + getName() + "正在学Java");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    Teacher

    package com.Test.pkg;
    
    public class Teacher extends Person {
        private double salary;
        public Teacher(String name, int age, double salary) {
            super(name, age);
            this.salary = salary;
        }
        public double getSalary() {
            return salary;
        }
        public void setSalary(double salary) {
            this.salary = salary;
        }
        // 重写父类的say()方法
        public String say() {
            return super.say() + " salary = " + salary;
        }
        public void teach() {
            System.out.println("老师:" + getName() + "正在讲Java课程");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    多态参数

    在这里插入图片描述

  • 相关阅读:
    JS中的异步编程与Promise
    将Helm编写的Chart推送到Harbor仓库
    PyTorch随机生成一个布尔型张量
    Operator 开发实践 六 (API分组)
    Laravel 第九章 其它功能
    Windows中Tomcat服务器搭建与配置
    0092 图
    RecyclerView懒加载失效问题(三)
    七、基于FreeRTOS&STM32移植MQTT
    第四十三章 持久对象和SQL - 查看存储的数据
  • 原文地址:https://blog.csdn.net/yeeeeeeeee_/article/details/125990116