Java进阶----多态

多态

什么是多态

在继承父类或者实现接口的基础上,允许同一类事物出现不同的状态
多态的前提:继承或实现的关系、方法的重写、父类(接口)引用指向子类(实现类)对象

表现形式

父类 变量 = 子类对象();
接口 变量 = 实现对象();

需求:

  • 定义Animal动物类作为父类,规定吃饭、喝水功能。
  • 定义子类Dog和Cat,分别创建Dog对象和Cat对象,调用吃饭功能和喝水功能

思考:
1.定义Animal动物类,作为父类
2.定义Dog狗类和Cat猫类,作为子类
3.分别创建Dog和Cat对象,调用吃饭、喝水功能

/**
 * 动物类,作为父类的
 */
public abstract class Animal {
    //喝水
    public void drink() {
        System.out.println("喝水");
    }
    //吃饭
    public abstract void eat();
}
/**
 * 猫类
 */
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
/**
 * 狗类,作为子类
 */
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
}

之前的想法:

Dog dog = new Dog();
Cat cat = new Cat();

引入多态的思想:

//允许将子类对象,给父类类型变量赋值
//将dog和cat变量变成同一类型
Animal dog = new Dog();
Animal cat = new Cat();

//呈现相同状态
dog.drink();
cat.drink();
//呈现不同状态
dog.eat();
cat.eat();

多态关系中,成员的访问特点

目标:了解多态中成员的访问特点

  • 方法调用:编译看左边,运行看右边
  • 变量调用:编译看左边,运行也看左边

需求:有父类Fu和子类Zi,请使用多态的形式创建对象并访问各自属性和方法

//父类
public class Fu {
    String field = "父类属性";

    public void method() {
        System.out.println("父类方法");
    }
}

//子类
public class Zi extends Fu {
    String field = "子类属性";
    String ziField = "子类特有属性";

    public void method() {
        System.out.println("子类方法");
    }

    public void ziMethod() {
        System.out.println("子类特有方法");
    }
}
public static void main(String[] args) {
        /**
         * 多态中成员访问特点:
         *      变量调用:编译看左边,运行也看左边
         *      方法调用:编译看左边,运行看右边
         *
         * 需求:有父类Fu和子类Zi,请使用多态的形式创建对象并访问各自属性和方法
         */
        //1.用多态的代码形式创建Zi对象,给Fu类型变量赋值
        Fu zi = new Zi();

        //2.访问父类和子类都有(同名)的属性
        System.out.println(zi.field);
        //结果: 父类属性

        //3.访问父类没有但子类有的属性
        //System.out.println(zi.ziField);
        //报错
        //访问变量:编译看左边,运行也看左边
        System.out.println("-------------------");

        //4.访问父类和子类都有(同名)的方法
        zi.method();
        //结果: 子类方法

        //5.访问父类没有但子类有的方法
        //zi.ziMethod();
        //报错
        //访问方法:编译看左边,运行看右边
    }

多态好处与弊端

优势:解耦合,提高方法的扩展性,把方法的形参写成父类/接口类型,调用方法的时候可以传递子类/实现类对象
劣势:多态下不能使用子类的特有功能

需求:利用多态技术优化useDog和useCat方法,使两个方法变为一个方法!
public abstract class Animal {
    public void drink() {
        System.out.println("喝水!");
    }

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

    //猫类特有功能:抓老鼠
    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

    //狗类特有功能:狗看家
    public void lookHome() {
        System.out.println("狗看家");
    }
}
public static void main(String[] args) {
	feedAnimal(new Dog());
    feedAnimal(new Cat());
}

public static void feedAnimal(Animal animal) {
        animal.eat();
        //2.尝试访问子类的特有功能,失败报错
        //访问:狗看家
        //animal.lookHome();
        //访问:猫抓老鼠
        //animal.catchMouse();
        //多态的弊端:在多态形式下,不能访问子类的特有功能
    }

多态的转型

目标:了解多态下引用数据类型的类型转换操作

多态转型指的是:把父类类型强制转换为子类类型
格式:子类  变量 = (子类)被转换的数据;
原本是什么类型,才能还原为什么类型
Animal   a  =  new Dog();
Dog d = (Dog)a;

instanceof关键字

作用:测试它左边的对象是否是它右边的类的实例

if( a instanceof Dog ){
	Dog d = (Dog)a;
	d.lookHome();

}

目标:了解多态下引用数据类型的类型转换操作

public static void useAnimal(Animal animal) {
        animal.eat();
        //1.强转成Dog狗类型
        //Dog dog = (Dog) animal;
        //调用狗的特有功能
        //dog.lookHome();

        //2.正确的强转方案:先判断,后强转。使用instanceof
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.lookHome();
        }

        //3.在高版本的jdk中,上面的代码可以进一步简化
        if (animal instanceof Cat cat) {
            cat.catchMouse();
        }
    }
小结
  1. 多态的形式有表现形式有两种
    父类变量接收__子类对象
    接口变量接收__实现类对象
  2. 多态的好处是什么?
    如果方法的参数是父类类型,那么调用方法可以传递子类对象
    如果方法的参数是接口类型,那么调用方法可以传递实现类对象______
  3. 多态的弊端是什么?
    在多态的情况下,不能调用子类或者实现类的_特有方法
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值