java_多态

问题引导

在这里插入图片描述

  • 使用传统的方法来解决(private 属性)
  • 传统的方法带来的问题是什么? 如何解决?

问题是: 代码的复用性不高,而且不利于代码维护
解决方案: 引出我们要讲解的多态

多态的基本介绍

方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

多态的具体体现

方法的多态

重写和重载就体现多态

package com.hspedu.poly_;

/**
 * @author:寰愬悏瓒�
 * @date:2024/12/4 version:1.0
 */
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()被调用....");
    }
}

对象的多态

记住:
在这里插入图片描述
父类的引用 可以指向它子类的对象;
在这里插入图片描述
例子代码
Animal:

package com.hspedu.poly_.objectpoly_;

public class Animal {
    public void cry() {
        System.out.println("Animal cry() 动物在叫。。。");
    }
}

Cat:

package com.hspedu.poly_.objectpoly_;

public class Cat extends Animal {
    
    public void cry() {
        System.out.println("Cat cry()小猫喵喵叫...");
    }
}

Dog:

package com.hspedu.poly_.objectpoly_;

public class Dog extends Animal {

    public void cry() {
        System.out.println("Dog cry()小狗旺旺叫...");
    }
}

PolyObject:

package com.hspedu.poly_.objectpoly_;


public class PolyObject {
    public static void main(String[] args) {
// 体验对象多态特点
//     animal 编译类型就是  Animal , 运行类型是 Dog
        Animal animal = new Dog();
        //因为运行时,这时候执行到改行时,animal运行类型是Dog,所以cry就是Dog的cry
        animal.cry(); // 小狗旺旺叫


        animal = new Cat();
        animal.cry();// 小猫喵喵叫
    }
}

使用多态的机制来解决主人喂食物的问题,走代码

在这里插入图片描述

多态注意事项和细节讨论

多态的向上转型

在这里插入图片描述
1.先编译后运行,在编译的时候看父类有没有这个方法有的 话,编译才能通过,但是后面 运行的时候还是就近原则,先看子类有没有,有的话就调用子类的
2.特有成员(是指父类没有,子类有的成员)
3.成员是指属性和方法

代码:
Animal类

package com.hspedu.poly_.detail_;


public class Animal {
    String name = "动物";
    int age = 10;
    public void sleep() {
        System.out.println("睡");
    }

    public void run() {
        System.out.println("跑");
    }

    public void eat() {
        System.out.println("吃");
    }

    public void show() {
        System.out.println("Hello,你好");
    }
}

Cat类

package com.hspedu.poly_.detail_;

public class Cat extends Animal {
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse() {  // Cat特有方法
        System.out.println("猫抓老鼠");
    }
}

PolyDatail类

package com.hspedu.poly_.detail_;

public class PolyDatail {
    public static void main(String[] args) {
        // 向上转型:   父类的引用指向了子类的对象
//    语法: 父类的类型引用名 = new 子类类型();
        Animal animal = new Cat();
        Object obj = new Cat(); //Object 也是 Cat的父类;

//    向上转型调用方法的规则如下:
//    (1)可以调用父类中的所有成员(需遵守访问权限)
//    (2)但是不能调用子类的特有成员(是指父类没有,子类有的方法)
//     (3)因为在编译阶段,能调用哪些成员,是由编译类型来决定的
//        animal.catchMouse(); 错误

//   (4)最终运行效果 看子类(运行类型)的具体实现,即调用方法时,按照从子类(运行类型)开始查找方法, 
//		然后调用,规则同前面讲的方法调用规则 一致。
animal.eat();  // 猫吃鱼
animal.show();  // Hello,您好
animal.sleep(); // 睡
animal.run();  // 跑
    }
}

多态的向下转型

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

1.animal 现在的编译类型还是 Animal
2.强制类型转换只是将animal引用的对象视为Cat类,而不是真的将其转换为Cat类;
3.现在的 animal编译类型是:Animal,运行类型是:Cat
4.现在的 Cat编译类型是:Cat,运行类型是:Cat

修改 上述 PolyDatail类

//   (4)最终运行效果 看子类(运行类型)的具体实现,即调用方法时,按照从子类(运行类型)开始查找方法,
//    然后调用,规则同前面讲的方法调用规则 一致。
animal.eat();  // 猫吃鱼
animal.show();  // Hello,您好
animal.sleep(); // 睡
animal.run();  // 跑

//       目的: 希望,可以调用Cat的 catchMouse();
//        多态的向下转型;
//        (1)语法:子类类型 引用名 = (子类类型)父类引用;
//        问一个问题? cat 的编译类型是 Cat, 运行类型是 Cat
        Cat cat = (Cat) animal;
        cat.catchMouse(); //猫抓老鼠
//        (2)要求父类的引用必须指向的是当前目标类型的对象;

    }
}

属性没有重写之说!属性的值看编译类型

在这里插入图片描述

属性没有重写之说!属性的值看编译类型,方法看运行类型

package com.hspedu.poly_.detail_;

public class PolyDetail03 {
    public static void main(String[] args) {
        BB bb = new BB();
        System.out.println(bb instanceof BB);// true
        System.out.println(bb instanceof AA);// true
//aa 编译类型 AA, 运行类型是 BB
//BB 是 AA 子类
        AA aa = new BB();
        System.out.println(aa instanceof AA);// true
        System.out.println(aa instanceof BB);// true
        Object obj = new Object();
        System.out.println(obj instanceof AA);//false
        String str = "hello";
//System.out.println(str instanceof AA);
        System.out.println(str instanceof Object);//true
    }
}

class AA {} //父类

class BB extends AA {} // 子类

练习1

在这里插入图片描述
解析:

1.double不多介绍 了
2.double -> long 自动类型转换
3.int -> boolean 错误
4.String类是 Object的子类,当然 可以 向上/向下转型了
5.Integer就是int ,也是 Object的子类

练习2

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HHppGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值