第七章_Java中面向对的的三大特征之多态

第七章_Java中面向对的的三大特征之多态

1.什么是多态?

指同一个对象在不同时刻表现出来不同的形态。

2.多态的前提

  • 要有继承或实现(接口)关系
  • 要有方法的重写
  • 要有父类引用指向子类对象 --> 父类 对象名= new 子类()

代码演示:

public class Test {
    public static void main(String[] args) {
        //原始方式调用,当前的事物是一只猫
        Cat cat = new Cat();
        cat.eat();
        cat.catchMouse();
        System.out.println("--------------------");
        //多态形式调用,当前代表的是一个动物,并不特指猫
        Animal animal = new Cat();
        animal.eat();
//        animal.catchMouse();//不能调用子类中的特有方法
    }
}
class Animal{
    public void eat(){
        System.out.println("动物都吃饭");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {//重写父类中的eat方法
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){//子类中特有的方法
        System.out.println("猫抓老鼠");
    }
}

多态不可以调用子类的特有方法,编译无法通过

在这里插入图片描述

把这行代码注释后的执行效果

在这里插入图片描述

3.多态的成员访问特点

成员访问特点

3.1成员变量

​ 编译看父类,运行看父类

​ 看等号左边是谁,先调用谁

3.2成员方法

​ 编译看父类,运行看子类

​ 看new的是谁,先调用谁.子类没有,找父类

代码演示:

public class Test {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();//猫吃鱼
        animal.drink();//动物都喝水
        String name1 = animal.name;
        System.out.println(name1);//Animal
        System.out.println("---------------");
        Cat cat = new Cat();
        cat.eat();//猫吃鱼
        //子类中并没有重写drink方法,子类没有就找父类
        cat.drink();//动物都喝水
        String name2 = cat.name;
        System.out.println(name2);//Tom
    }
}
class Animal{
    String name = "Animal";
    public void eat(){
        System.out.println("动物都吃饭");
    }
    public void drink(){//此方法子类中没有重写
        System.out.println("动物都喝水");
    }
}
class Cat extends Animal{
    String name = "Tom";
    @Override
    public void eat() {//重写父类中的eat方法
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){//子类中特有的方法
        System.out.println("猫抓老鼠");
    }
}

执行效果:

在这里插入图片描述

总结

1.多态中成员变量需要看"="左边,左边是谁就调用谁

2.多态中成员方法需要看"="右边,右边是谁先调用谁,如果子类没有就找父类的

4.多态的优缺点

4.1优点(方法的参数传递)

定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作。

提高程序的扩展性。

4.2缺点

不能直接使用子类的特有成员 --> 多态最大的缺点

4.3原始方法的优缺点

优点:既可以调用自己特有的,还能调用重写的,还能调用继承的

缺点:扩展性差

5.多态中的转型

5.1向上转型(默认)

​ 父类引用指向子类对象,一般的多态形式就是向上转型。
​ 弊端:不能直接调用子类特有方法

5.2向下转型

格式:子类型 对象名 = (子类型)父类引用; -->向下转型后可以使用子类中特有的方法

简单举例:

​ double b = 10;
int i = b;–>报错
强转–>int i = (int)b

代码演示:

public class Test {
    public static void main(String[] args) {
        //向下转型格式:
        // 子类型 对象名 = (子类型)父类引用;
        Animal animal = new Cat();
        Cat cat = (Cat) animal;
        cat.catchMouse();
    }
}
class Animal{
    public void eat(){
        System.out.println("动物都吃饭");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {//重写父类中的eat方法
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){//子类中特有的方法
        System.out.println("猫抓老鼠");
    }
}

执行效果

在这里插入图片描述

5.3多态中转型存在的风险和解决方案
风险

如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException 的错误

解决方案
  • 关键字

    instanceof

  • 使用格式

    变量名 instanceof 类型

    通俗的理解:判断关键字左边的变量,是否是右边的类型,返回boolean类型结果

代码演示:

public class Test {
    public static void main(String[] args) {
        useAnimal(new Dog());// 相当于Animal animal = new Dog();
        System.out.println("----------------");
        useAnimal(new Cat());// 相当于Animal animal = new Cat();
    }
    //定义一个使用动物的方法
    public static void useAnimal(Animal animal){
        /*
        使用多态的形式调用动物的eat方法
        如果参数是dog就调用dog中的eat方法
        如果参数是cat就调用cat中的eat方法
         */
        animal.eat();

        //如果参数是此处就会出现类型转换异常的错误ClassCastException
        /*Dog dog = (Dog) animal;
        dog.watchHome();*/

        if (animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.watchHome();
        }else if (animal instanceof  Cat){
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }

    }
}
abstract class Animal {
    public abstract void eat();
}

class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }

    public void watchHome(){
        System.out.println("看家");
    }
}

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

执行效果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值