17-多态

案例

编写一个程序,Master类中有一个feed(喂食)的方法,可以完成主人对动物喂食物的操作。

代码
food类

package com.xbxaq.poly_;

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;
    }
}

fish类

package com.xbxaq.poly_;

public class Fish  extends Food{
    public Fish(String name){
        super(name);
    }
}

bone类

package com.xbxaq.poly_;

public class Bone extends Fish{
    public Bone(String name){
        super(name);
    }
}

animal类

package com.xbxaq.poly_;

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;
    }
}

dog类

package com.xbxaq.poly_;

public class Dog extends Animal{
    public Dog(String name) {
        super(name);
    }
}

cat类

package com.xbxaq.poly_;

public class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }
}

master类

package com.xbxaq.poly_;

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(Dog dog, Bone bone){
        System.out.println("主人 " + name + " 给" + dog.getName() + "喂 " + bone.getName());
    }
}

poly类

package com.xbxaq.poly_;

public class Poly01 {
    public static void main(String[] args) {
        Master tom = new Master("tom");
        Dog dog = new Dog("小白");
        Bone bone = new Bone("大白骨");
        tom.feed(dog, bone);
    }
}

运行结果

基本概述

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

多态的具体体现

1、方法的多态(重载与重写)
2、对象的多态

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

多态的细节

1、多态的前提是:两个对象(类)存在继承关系
2、多态的向上转型,本质为父类的引用指向了子类的对象

语法:父类类型    引用名  =  new  子类类型()
特点:编译类型看右边,运行类型看左边
可以调用父类的所有成员(需遵守访问权限),不能调用子类的特有成员。

3、多态的向下转型

语法:子类类型    引用名 =   (子类类型)   父类引用;
只能强转父类的引用,不能强转父类的对象
要求父类的引用必须指向的是当前目标类型的对象
当向下转型后可以调用子类类型中所有的成员

4、属性没有重写之说,属性的值看编译类型

animal类

cat类

Detail类

结果

动态绑定机制

  • 当调用对象方法时,该方法会和对象的内存地址[运行类型]进行绑定
  • 当调用对象属性时,没有动态绑定机制,哪里声明哪里使用

示例代码-1

public class BangDing{
    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 getl() + 10;
    }
    public int sum1(){
        return i + 10;
    }
    public int getl(){
        return i;
    }
}

class B extends A {
    public int i = 20;
    public int sum(){
        return i + 20;
    }
    public int getl(){
        return i;
    }
    public int sum1(){
        return i + 10;
    }
}

image-20240228170629776

代码示例-2

public class BangDing{
    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 getl() + 10;
    }
    public int sum1(){
        return i + 10;
    }
    public int getl(){
        return i;
    }
}

class B extends A {
    public int i = 20;
//    public int sum(){
//        return i + 20;
//    }
    public int getl(){
        return i;
    }
    public int sum1(){
        return i + 10;
    }
}

image-20240228171648042

代码示例-3

public class BangDing{
    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 getl() + 10;
    }
    public int sum1(){
        return i + 10;
    }
    public int getl(){
        return i;
    }
}

class B extends A {
    public int i = 20;
//    public int sum(){
//        return i + 20;
//    }
    public int getl(){
        return i;
    }
//    public int sum1(){
//        return i + 10;
//    }
}

image-20240228171847770

细节讨论

属性看编译类型,方法看运行类型

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

代码

public class a1{
    public static void main(String[] args){
        Base base = new Sub();
        System.out.println(base.count);

        Sub sub = new Sub();
        System.out.println(sub.count);
    }
}

class Base{
    int count = 10;
}

class Sub extends Base{
    int count = 20;
}


image-20240228152656794

instanceOf比较操作符,用于判断对象的运行类型是否为xx类型或者xx类型的子类型

public class a1{
    public static void main(String[] args){
    Sub sub = new Sub();
    System.out.println(sub instanceof Sub);
    System.out.println(sub instanceof Base);

    }
}

class Base{

}

class Sub extends Base{

}


image-20240228163659097

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值