张小飞的Java之路——第十章

写在前面:

视频是什么东西,有看文档精彩吗?

视频是什么东西,有看文档速度快吗?

视频是什么东西,有看文档效率高吗?


待到吃饱喝足之后。。。。

“师弟,我先睡一会儿,你自便”说罢,诸小亮便走近了卧室

但张小飞飞却不想休息,正苦恼做什么,突然发现桌子上有一枚硬币,像发现宝物似的紧紧握在手里。

“正面看电影,反面打王者,竖着就学习,斜着就加班,摔碎了就熬夜学习,如果摔成俩-----
那就什么都不干了,坐在家里天天摔……!”

诸小亮:。。。。。

1. 多态

下午。

诸小亮:多态——就是事物的多种形态

张小飞:额…,能举个例子吗?

“比如:泰迪是狗,属于犬科,也是动物,更是生物”

“这样啊,那,水在常温下是液体,0度下是固体,100度是气体,这也是多态?”

“是这个道理,举一反三的能力挺不错的”

“呵呵,还好,不过这跟 Java 有什么关系?”

“Java中多态,说的是:对象的多态性

  • 就是:父类或者父接口类型的引用指向子类对象

示例:

interface Animal{
    void sound();
    void eat();
}

class Dog implements Animal {
    @Override
    public void sound(){
        System.out.println("汪汪汪。。。。。");
    }
    @Override
    public void eat() {
        System.out.println("骨头。。。。。");
    }
}
public class Demo{
    public static void main(String[] args){
        //多态:父类或父接口的引用指向子类对象
        Animal dog = new Dog();//Dog对象,既是Dog类型,又是Animal类型,这就是多态
    }
}


张小飞:“原来在 Java 中,这就是多态,不过这有什么用?”

2. 多态的好处

诸小亮:这好处就太多了

  • 使用父类或者父接口类型的变量,可以接收其所有子类的对象,提高代码的复用率

张小飞:还能提高代码复用率?

“是的,举个例子:狗在吃东西前会做一些事情,比如:叫几声”

public static void main(String[] args
    //泰迪
    Dog taidi = new Dog();
    taidi.sound();
    taidi.sound();
    taidi.eat();

	//藏獒
    Dog zangao = new Dog();
    zangao.sound();
    zangao.sound();
    zangao.eat();
}

“上面的代码很类似,所以可以用方法封装一下:”

//用一个方法封装狗吃东西时都做什么
public static void dogEat(Dog dog){
    dog.sound();
    dog.sound();
    dog.eat();
}

//这段代码要比上面的简介一些
public static void main(String[] args){
    Dog taidi = new Dog();
    dogEat(taidi);
    
    Dog zangao = new Dog();
    dogEat(zangao);
}


张小飞:“这跟多态没关系吧”

“不要着急,继续看:猫也一样,在吃东西前会做一些事情,像:叫几声”

interface Animal{
    void sound();
    void eat();
}

class Dog implements Animal {
    @Override
    public void sound(){
        System.out.println("汪汪汪。。。。。");
    }
    @Override
    public void eat() {
        System.out.println("骨头。。。。。");
    }
}
class Cat implements Animal{

    @Override
    public void sound() {
        System.out.println("喵喵喵。。。。。");
    }

    @Override
    public void eat() {
        System.out.println("鱼。。。。。");
    }
}
public class Demo2{
    public static void main(String[] args){
        Dog taidi = new Dog();
        dogEat(taidi);
        Dog zangao = new Dog();
        dogEat(zangao);

        Cat jiafeimao= new Cat();
        //Cat 不能使用 dogEat 方法,只能创建一个新的 catEat 方法
        catEat(jiafeimao);
        Cat tangmu = new Cat();
        catEat(tangmu);
    }

    //用一个方法封装狗吃东西时都做什么
    public static void dogEat(Dog dog){
        dog.sound();
        dog.sound();
        dog.eat();
    }

    //用一个方法封装猫吃东西时都做什么
    public static void catEat(Cat cat){
        cat.sound();
        cat.sound();
        cat.eat();
    }
}

诸小亮:“有没有发现,dogEat 和 catEat 方法差不多,所以这俩方法还可以合并”

张小飞:“不能把,他们的参数类型不同啊”

“这时候就可以用多态了,因为Dog 和 Cat 都是Animal,所以:”

//抽出一个公共的方法,参数是 Animal 类型,只要是 Animal 的子类都可以传进来
public static void animalEat(Animal animal){
    animal.sound();
    animal.sound();
    animal.eat();
}

public static void main(String[] args){
    Animal dog1 = new Dog();
    animalEat(dog1);
    Animal dog2 = new Dog();
    animalEat(dog2);

    Animal cat1 = new Cat();
    animalEat(cat1);
    Animal cat2 = new Cat();
    animalEat(cat2);

}

张小飞:“原来是这样,明白了”

3. 弊端

诸小亮:“但其实它也有弊端”

张小飞:“什么弊端?”

只能使用父类或父接口中的方法,不能使用子类的特有方法,比如:”

//狗都有看家的功能
public void seeHome() {
    System.out.println("看家,汪汪汪。。。。。");
}

“但是 Animal 没有‘seeHome’的功能,如果使用多态,不能调用 seeHome 方法”

image.png
解释:虽然创建的对象是 Dog ,但是作为一个 Animal ,无法使用 Dog 的特有方法

张小飞:那如果就是想用 Dog 的特有方法呢?

诸小亮:这时可以向下转型

4. 向上向下转型

诸小亮:这句代码:Animal dog = new Dog(); 专业说法叫:向上转型

张小飞:那,什么是向下转型呢?

“看下面代码:”
image.png
张小飞:“这不就是——强制类型转换么?”

“是的,但是需要注意:”

public static void main(String[] args){
    //animal 是一个猫
    Animal animal = new Cat();
    //不能强制转换位Dog类型,这样虽然编译不报错,但是运行时会出问题
    Dog d = (Dog) animal;
    d.seeHome();
}

结果:
image.png

张小飞:“那,如何判断 animal 具体是哪一种子类型呢?”

“使用 instanceof 就可以了,比如:”

public static void main(String[] args){
    Animal animal = new Cat();

    //instanceof:判断变量是不是对应类型
    if(animal instanceof Dog){
        Dog d = (Dog) dog;
        d.seeHome();
    }else{
        System.out.println("不是狗东西。。。。");
    }
}

5. 多态时的成员和方法

诸小亮:不过,使用多态,当子父类中有相同属性和方法时,需要注意两点

张小飞:具体是哪两点?

“第一:子父类中有同名属性时,使用父类中的属性,比如:”

class Animal{
   int num = 2;
}

class Dog extends Animal {
    int num = 3;
}
public class Demo2{
    public static void main(String[] args){
        Animal dog = new Dog();
        System.out.println(dog.num);//输出2
    }
}

“第二:子父类中有相同方法时,运行的是子类中的方法,比如:”

class Animal{
   int num = 2;
   void run(){
       System.out.println("疯狂动物城。。。。。");
   }
}

class Dog extends Animal {
    int num = 3;
    void run(){
        System.out.println("狗狗跑起来。。。。。");
    }
}
public class Demo2{
    public static void main(String[] args){
        Animal dog = new Dog();
        dog.run();//实际调用的是 Dog 类中的 run 方法
    }
}

结果:
image.png

张小飞:明白了

诸小亮:好了,多态就说这么多,你好好的回顾一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值