• 非零基础自学Java (老师:韩顺平) 第8章 面向对象编程(中级部分) 8.11 面向对象编程 - 多态


    非零基础自学Java (老师:韩顺平)

    ✈【【零基础 快速学Java】韩顺平 零基础30天学会Java】

    第8章 面向对象编程(中级部分)

    8.11 面向对象编程 - 多态
    8.11.1 看个问题

    在这里插入图片描述

    【传统方法解决】

    • private属性

    传统的方法带来的问题:代码的复用性不高,而且不利于代码维护。

    解决方案:多态

    【举个栗子】

    动物类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Animal
     * date: 2022/9/3 11:14
     *
     * @author DingJiaxiong
     */
    
    public class Animal {
        private String name;
    
        public Animal(String name){
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    狗类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Dog
     * date: 2022/9/3 11:16
     *
     * @author DingJiaxiong
     */
    
    public class Dog extends Animal{
        public Dog(String name) {
            super(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    猫类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Cat
     * date: 2022/9/3 11:16
     *
     * @author DingJiaxiong
     */
    
    public class Cat extends Animal{
        public Cat(String name) {
            super(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    猪类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Pig
     * date: 2022/9/3 11:21
     *
     * @author DingJiaxiong
     */
    
    public class Pig extends Animal{
        public Pig(String name) {
            super(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    食物类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Food
     * date: 2022/9/3 11:15
     *
     * @author DingJiaxiong
     */
    
    public class Food {
        private String name;
    
        public Food(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    骨头类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Bone
     * date: 2022/9/3 11:16
     *
     * @author DingJiaxiong
     */
    
    public class Bone extends Food{
    
        public Bone(String name) {
            super(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    鱼类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Fish
     * date: 2022/9/3 11:16
     *
     * @author DingJiaxiong
     */
    
    public class Fish extends Food{
        public Fish(String name) {
            super(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    米饭类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Rice
     * date: 2022/9/3 11:21
     *
     * @author DingJiaxiong
     */
    
    public class Rice extends Food {
        public Rice(String name) {
            super(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    主人类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Master
     * date: 2022/9/3 11:17
     *
     * @author DingJiaxiong
     */
    
    public class Master {
        private String name;
    
        public Master(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    
        //主人给动物喂食
        public void feed(Animal animal , Food food){
            System.out.println("主人" + name + "给" + animal.getName() + "吃" + food.getName());
        }
    
    //    //给狗喂骨头
    //    public void feed(Dog dog , Bone bone){
    //        System.out.println("主人" + name + "给" + dog.getName() + "吃" + bone.getName());
    //    }
    //
    //    //给猫猫喂鱼
    //    public void feed(Cat cat , Fish fish){
    //        System.out.println("主人" + name + "给" + cat.getName() + "吃" + fish.getName());
    //    }
        //如果动物很多,食物很多,feed方法很多,不利于维护 → 统一成给动物喂食物
    }
    
    • 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    测试类

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: Test
     * date: 2022/9/3 11:23
     *
     * @author DingJiaxiong
     */
    
    public class Test {
        public static void main(String[] args) {
            Master master = new Master("Tom");
            Animal animal = new Pig("Peiqi");
            Food food = new Rice("东北大米");
    //        Pig pig = new Pig("Peiqi");
    //        Rice rice = new Rice("东北大米");
    
            master.feed(animal,food);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行结果

    在这里插入图片描述

    8.11.2 多[多种]态[状态]基本介绍

    方法或对象具有多种形态。是面向对象的第三大特征。

    多态是建立在封装和继承基础之上的。

    8.11.3 多态的具体体现

    【方法的多态】

    举个栗子

    package com.dingjiaxiong.poly_;
    
    /**
     * ClassName: PloyMethod
     * date: 2022/9/3 11:28
     *
     * @author DingJiaxiong
     */
    
    public class PloyMethod {
        public static void main(String[] args) {
            //方法重载体现多态
            A a = new A();
            //传入不同的参数,就会调用不同的sum方法,体现了多态
            System.out.println(a.sum(10 ,20));
            System.out.println(a.sum(10 , 20 ,30));
    
            //方法重写也体现多态
            B b = new B();
            a.say();
            b.say();
        }
    }
    
    class B{//父类
        public void say(){
            System.out.println("B say() 方法被调用...");
        }
    }
    
    class A extends B{//子类
        public int sum(int n1 , int n2){
            return n1 + n2;
        }
    
        //重载
        public int sum(int n1, int n2 ,int n3){
            return n1 + n2 + n3;
        }
    
        //重写
        public void say(){
            System.out.println("A say() 方法被调用...");
        }
    }
    
    • 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    运行结果

    在这里插入图片描述

    【对象的多态】

    韩老师的几句话

    • 一个对象的编译类型和运行类型可以不一致
    • 编译类型在定义对象时,就确定了,不能改变
    • 运行类型是可以变化的
    • 编译类型看定义时 = 号的左边,运行类型看 = 的右边

    举个栗子

    动物类

    package com.dingjiaxiong.poly_.objectpoly_;
    
    /**
     * ClassName: Animal
     * date: 2022/9/3 11:35
     *
     * @author DingJiaxiong
     */
    
    public class Animal {
        public void cry(){
            System.out.println("Animal cry() 动物在叫...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    狗类

    package com.dingjiaxiong.poly_.objectpoly_;
    
    /**
     * ClassName: Dog
     * date: 2022/9/3 11:37
     *
     * @author DingJiaxiong
     */
    
    public class Dog extends Animal{
        public void cry(){
            System.out.println("Dog cry() 小狗汪汪叫...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    猫类

    package com.dingjiaxiong.poly_.objectpoly_;
    
    /**
     * ClassName: Cat
     * date: 2022/9/3 11:36
     *
     * @author DingJiaxiong
     */
    
    public class Cat extends Animal{
        public void cry(){
            System.out.println("Cat cry() 小猫喵喵叫...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试类

    package com.dingjiaxiong.poly_.objectpoly_;
    
    /**
     * ClassName: PolyObject
     * date: 2022/9/3 11:37
     *
     * @author DingJiaxiong
     */
    
    public class PolyObject {
        public static void main(String[] args) {
            Animal animal = new Dog();
            animal.cry();
    
            animal = new Cat();
            animal.cry();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行效果

    在这里插入图片描述

    8.11.4 多态解决主人喂食问题

    已解决

    在这里插入图片描述

    8.11.5 多态注意事项和细节讨论
    • 多态的前提是:两个对象(类)存在继承关系
    • 多态的向上转型
      • 本质:父类的引用指向了子类的对象
      • 语法:父类类型 引用名 = new 子类类型();
      • 特点
        • 编译类型看左边,运行类型看右边
        • 可以调用父类中的所有成员(要遵守访问权限)
        • 不能调用子类中的特有成员
        • 最终运行效果看子类的具体实现
    • 多态向下转型
      • 语法:子类类型 引用名 = (子类类型) 父类引用;
      • 只能强转父类的引用,不能强转父类的对象
      • 要求父类的引用必须指向的是当前目标类型的对象
      • 当向下转型后,可以调用子类类型中所有的成员
    8.11.7 java的动态绑定机制

    Java重要特性:动态绑定机制

    在这里插入图片描述

    举个栗子

    package com.dingjiaxiong.poly_.dynamic_;
    
    /**
     * ClassName: DynamicBinding
     * date: 2022/9/3 11:48
     *
     * @author DingJiaxiong
     */
    
    public class DynamicBinding {
        public static void main(String[] args) {
            A a = new B(); //向上转型
            System.out.println(a.sum());
            System.out.println(a.sum1());
        }
    }
    
    class A{//父类
        public int i = 10;
        //动态绑定机制
    
        public int sum(){
            return getI() + 10;
        }
    
        public int sum1(){
            return i + 10;
        }
    
        public int getI(){
            return i;
        }
    }
    
    class B extends A{
        public int i = 20;
    
        public int sum(){
            return i + 20;
        }
    
        public int getI(){
            return i;
        }
    
        public int sum1(){
            return i + 10;
        }
    }
    
    • 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    运行结果

    在这里插入图片描述

    8.11.8 多态的应用

    【多态数组】

    现有一个继承结构如下:要求创建 1 个 Person 对象、2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组
    中,并调用每个对象say 方法

    Person类

    package com.dingjiaxiong.poly_.polyarr_;
    
    /**
     * ClassName: Person
     * date: 2022/9/3 11:54
     *
     * @author DingJiaxiong
     */
    
    public class Person {//父类
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        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 + "\t" + 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    Student类

    package com.dingjiaxiong.poly_.polyarr_;
    
    /**
     * ClassName: Student
     * date: 2022/9/3 11:56
     *
     * @author DingJiaxiong
     */
    
    public class Student extends Person{
    
        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
        @Override
        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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    Teacher类

    package com.dingjiaxiong.poly_.polyarr_;
    
    /**
     * ClassName: Teacher
     * date: 2022/9/3 11:58
     *
     * @author DingJiaxiong
     */
    
    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方法
        @Override
        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
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    测试类

    package com.dingjiaxiong.poly_.polyarr_;
    
    /**
     * ClassName: PloyArray
     * date: 2022/9/3 11:59
     *
     * @author DingJiaxiong
     */
    
    public class PloyArray {
        public static void main(String[] args) {
    
            Person[] persons = new Person[5];
            persons[0] = new Person("Jack",20);
            persons[1] = new Student("Marry",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++) {
                System.out.println(persons[i].say()); //动态绑定机制
                //类型判断 + 向下转型
                if (persons[i] instanceof Student){ //判断persons[i]的运行类型是不是Student
                    Student student = (Student) persons[i];
                    student.study();
                }
                else if(persons[i] instanceof Teacher){
                    Teacher teacher = (Teacher) persons[i];
                    teacher.teach();
                }
                else if(persons[i] instanceof Person){
    //                System.out.println("类型有误");
                }
                else{
                    System.out.println("类型有误");
                }
            }
    
    
        }
    }
    
    • 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    运行结果

    在这里插入图片描述

    【多态参数】

    方法定义的形参类型为父类类型,实参类型允许为子类类型。

    前面的主人喂动物。

  • 相关阅读:
    二维码扫码登录原理,其实比你想的要简单的多
    四书五经 中庸
    信号与线性系统分析(吴大正,郭宝龙)(2-冲激函数)
    python读取.txt文件中某些关键字后面的内容 并根据该数据画图
    springboot项目集成kafka,并创建kafka生成消息线程池
    阿里云ESSD云盘最大和最小IOPS说明
    Mysql之锁与事务
    vue打包耗时显示插件安装、遇到插件版本不兼容问题以及解决方案
    信息共享的记忆被囊群算法-附代码
    用户投稿|Cursor——软件开发行业新变革
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/126883249