• Java学习之多态一


    目录

    一、入门案例

     Food类

    Animal类 

    Master类

    运行测试

    分析

    运行结果

     问题总结

    二、方法的多态

    三、对象的多态(重难点/核心)

    四个非常重要的知识点(背诵)

    举例说明

    父类-Animal类

    子类-Dog类

    子类-Cat类

    运行-PolyObject类

    运行结果

    ​编辑 分析

    改变运行类型

    分析

    运行结果

    举例说明


    多态是建立在封装和继承至上的,是面向对象中最难的部分

    一、入门案例

    主人需要给自己的不同的宠物喂不同的食物

    建立Food类(包括子类Bone和Fish),Animal类(包括子类Dog、Cat),Master类

    和Poly01(测试运行)

     Food类

    1. package com.hspedu.poly_;
    2. public class Food {
    3. private String name;
    4. public Food(String name) {
    5. this.name = name;
    6. }
    7. public String getName() {
    8. return name;
    9. }
    10. public void setName(String name) {
    11. this.name = name;
    12. }
    13. }
    1. package com.hspedu.poly_;
    2. public class Fish extends Food{
    3. //需要继承父类的构造器
    4. public Fish(String name) {
    5. super(name);
    6. }
    7. }
    1. package com.hspedu.poly_;
    2. public class Bone extends Food{
    3. public Bone(String name) {
    4. super(name);
    5. }
    6. }

    Animal类 

    1. package com.hspedu.poly_;
    2. public class Animal {
    3. private String name;
    4. public Animal(String name) {
    5. this.name = name;
    6. }
    7. public String getName() {
    8. return name;
    9. }
    10. public void setName(String name) {
    11. this.name = name;
    12. }
    13. }
    1. package com.hspedu.poly_;
    2. public class Cat extends Animal{
    3. public Cat(String name) {
    4. super(name);
    5. }
    6. }
    1. package com.hspedu.poly_;
    2. public class Dog extends Animal{
    3. public Dog(String name) {
    4. super(name);
    5. }
    6. }

    Master类

    1. package com.hspedu.poly_;
    2. public class Master {
    3. private String name;
    4. public Master(String name) {
    5. this.name = name;
    6. }
    7. public String getName() {
    8. return name;
    9. }
    10. public void setName(String name) {
    11. this.name = name;
    12. }
    13. //有一个feed方法,完成主人给动物喂食的动作
    14. public void feed(Dog dog, Bone bone){
    15. //dog.getName()继承自Animal的getName;
    16. //fish.getName()继承自Food的getName;
    17. System.out.println("主人" + name + "给小狗"+ dog.getName() + "喂" + bone.getName());
    18. }
    19. public void feed2(Cat cat, Fish fish){
    20. System.out.println("主人" + name + "给小猫"+ cat.getName() + "喂" + fish.getName());
    21. }
    22. }

    运行测试

    1. package com.hspedu.poly_;
    2. public class Poly01 {
    3. public static void main(String[] args) {
    4. Master master = new Master("小李");
    5. Dog spike = new Dog("Spike");
    6. Bone bone = new Bone("大骨头");
    7. master.feed(spike,bone);
    8. Cat tom = new Cat("Tom");
    9. Fish fish = new Fish("鱼罐头");
    10. master.feed2(tom,fish);
    11. }
    12. }

     上述代码中的

    1. Master master = new Master("小李");
    2. Dog spike = new Dog("Spike");
    3. Bone bone = new Bone("大骨头");
    4. master.feed(spike,bone);

    分析

    对象引用master调用feed方法,此时需要传入一个Dog类变量和一个Bone类变量,即spike和bone

    章节7.3.1基本数据类型的传参机制

    1. //创建 AA 对象 名字 obj
    2. int a = 10;
    3. int b = 20;
    4. AA obj = new AA();
    5. obj.swap(a, b); //调用 swap

    swap()方法

    1.  public void swap(int a,int b){
    2. }

    创建新对象obj,然后创建两个int型变量a,b,然后传参调用

    运行结果

     问题总结

    如果多几个宠物多几种食物就需要一直创建新的类和新的方法,不利于管理和维护

    此时就需要多态来解决这个问题

    二、方法的多态

    1. package com.hspedu.poly_;
    2. public class PolyMethod {
    3. public static void main(String[] args) {
    4. //方法重载体现多态
    5. A a = new A();
    6. //传入的参数个数不同,调用不同的sum方法
    7. //就是sum方法多重状态的体现
    8. System.out.println(a.sum(10,20));
    9. System.out.println(a.sum(10,20,30));
    10. //方法的重写体现出多态
    11. B b = new B();
    12. //两者会调用不同的say()方法,体现出say()方法的多态
    13. a.say();
    14. b.say();
    15. }
    16. }
    17. class B { //父类
    18. public void say() {
    19. System.out.println("B say() 方法被调用...");
    20. }
    21. }
    22. class A extends B {//子类
    23. public int sum(int n1, int n2) {//和下面 sum 构成重载
    24. return n1 + n2;
    25. }
    26. public int sum(int n1, int n2, int n3) {
    27. return n1 + n2 + n3;
    28. }
    29. public void say() {
    30. System.out.println("A say() 方法被调用...");
    31. }
    32. }

    方法重载体现多态: 传入的参数个数不同,调用不同的sum方法,就是sum方法多重状态的体现

    方法的重写体现出多态:两者会调用不同的say()方法(一个子类,一个父类),体现出say()方法的多态


    三、对象的多态(重难点/核心)

    四个非常重要的知识点(背诵)

    1.一个对象的编译类型和运行类型可以不一致

    2.编译类型在定义对象时就确定了,不能改变,

    3.运行类型是可以变化的

    4.编译类型看定义时“=”的左边,运行类型看“=”的右边

    举例说明

    父类-Animal类

    1. package com.hspedu.poly_.objectpoly_;
    2. public class Animal {
    3. public void cry() {
    4. System.out.println("Animal cry()动物在叫...");
    5. }
    6. }

    子类-Dog类

    1. package com.hspedu.poly_.objectpoly_;
    2. public class Dog extends Animal{
    3. @Override
    4. public void cry() {
    5. System.out.println("Dog cry()小狗汪汪叫...");
    6. }
    7. }

    子类-Cat类

    1. package com.hspedu.poly_.objectpoly_;
    2. public class Cat extends Animal{
    3. @Override//重写的注解
    4. public void cry() {
    5. System.out.println("Cat cry()小猫喵喵叫...");
    6. }
    7. }

    运行-PolyObject类

    1. package com.hspedu.poly_.objectpoly_;
    2. public class PolyObject {
    3. public static void main(String[] args) {
    4. Animal animal = new Dog();
    5. animal.cry();
    6. }
    7. }

    运行结果


     分析

    Animal animal = new Dog();

    animal的编译类型(javac的时候)是Animal运行类型(java的时候)是Dog

    animal.cry();
    

    调用的是Dog的cry,因为运行时,执行到该行的时候,animal的运行类型Dog, 所以cry就是Dog的cry

    改变运行类型

    1. package com.hspedu.poly_.objectpoly_;
    2. public class PolyObject {
    3. public static void main(String[] args) {
    4. Animal animal = new Dog();
    5. animal.cry();
    6. animal = new Cat();
    7. animal.cry();
    8. }
    9. }

    分析

    编译类型不变,运行类型变成了Cat,本质是看堆内真正的对象,所以animal.cry()调用的Cat类的方法

    运行结果

     

    举例说明

    披着羊皮的狼 ,表面是羊(编译类型),实际是狼(运行类型)

    披着狼皮的羊,表面是狼(编译类型),实际是羊(运行类型)

  • 相关阅读:
    对Happens-Before的理解
    QT默认自带mscv2017 2019 ,配置vs2022
    设计模式学习笔记(二十一)访问者模式及其实现
    LeetCode_动态规划_中等_688.骑士在棋盘上的概率
    7-1 sdut-oop-5 计算长方体和四棱锥的表面积和体积(类的继承) (10分)
    java与es8实战之六:用JSON创建请求对象(比builder pattern更加直观简洁)
    Spring @Profile注解使用和源码解析
    【Apache Tomcat信息泄露漏洞】
    ChatGPT 插件 “Consensus“ 实现论文搜索功能;数据工程在语言建模中的重要性
    python -正则表达式基础
  • 原文地址:https://blog.csdn.net/wjkqq0921/article/details/128170299