面对对象多态_Java学习4:面对对象-多态

741c8ea1e31bf5a60c6fb7bad60ebb6e.png

1.多态(最核心的特征)

主要参考知乎这个问题 程序狗的回答 以及自己学习的一些理解

1.1 生活中的例子:

  1. 动物的都有会吼叫,但是每个动物都有自己的叫声
  2. 对于不同程序,按F1的响应式是不同,Chrome浏览器下按住F1会跳出Chrome的帮助页面,Word对应F1的响应是浏览器中的office的支持帮助文档

总结:允许不同类的对象对同一消息作出不同的响应

1.2 分类

  • 编译时多态:设计时多态,编译器在编译过程中能够区分不同行为,通过方法重载实现
  • 运行时多态:Java程序运行时,系统才能够调用方法实例的类型来决定具体调用哪个方法,默认是多态的狭义定义

1.3 多态存在的三个必要条件:

  • 继承
  • 重写
  • 父类引用指向子类对象 Parent p = new Child()

2.代码说明:

父类 Animal.java:name month 属性,run() 和 static say()

package com.imooc.animal;

// abstract 设置抽象类后,不能实例化,但是可以向上转型,指向子类实例
public class Animal {

    private String name;
    private int month;

    public Animal(){}

    public Animal(String name,int month) {
        this.setName(name);
        this.setMonth(month);
    }
    // getter and setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    // 吃东西的方法
    public void eat() {
        System.out.println("动物都有吃东西的能力");
    }
    //打招呼的方法
    public static void say() {
        System.out.println("小动物之间打招呼");
    }
}

子类 Cat.java:猫类继承动物类,重写了eat()方法,并有独有的体重属性和普通方法 run()以及静态方法 say

package com.imooc.animal;

public class Cat extends Animal{
    //属性:体重
    private double weight;
    public Cat() {}
    public Cat(String name,int month,double weight) {
        super(name,month);
        this.weight=weight;
    }

    //方法:跑动
    public void run() {
        System.out.println("小猫快跑");
    }

    //方法:吃东西(重写父类方法)
    @Override
    public void eat() {
        System.out.println("猫吃鱼~~~!");
    }
    //say() 是 Cat类独有的静态的方法,与Animal父类的say()不构成重写关系,
    //因此不能加 @Override注解符
    public static void say() {
        System.out.println("小猫碰胡须");
    }
}

子类 Dog.java:继承Animal ,重写eat() 独有 sex属性和sleep()方法

package com.imooc.animal;

public class Dog extends Animal {
    //属性:性别
    private String sex;
    public Dog() {}
    public Dog(String name,int month,String sex) {
        super(name ,month);
        this.sex =sex ;
    }

    //方法:睡觉
    public void sleep() {
        System.out.println("小狗有午睡的习惯");
    }

    //方法:吃东西(重写父方法)
    @Override
    public void eat() {
        System.out.println("狗吃肉~~~!");
    }
}

TestDemo.java

package com.imooc.animal;
public class Test {
    public static void main(String[] args) {
        Animal animal=new Animal(); 

        //向上转型,自动转型,子类转父类
        Animal cat=new Cat(); //父类引用指向子类对象 
        Animal dog=new Dog(); //父类引用指向子类对象

        animal.eat(); // 动物都有吃东西的能力
        cat.eat(); // 猫吃鱼~~~!
        dog.eat(); // 狗吃肉~~~!
        cat.say();// == Animal.say()  小动物间打招呼
        cat.setName("kitty");
        System.out.println(cat.getName());
        // cat.run()  dog.sleep() 无法调用
        /**
         *1.向上转型后只能调用父类的派生方法如setName、静态方法以及子类重写的方法,子类特有的无法调用
         注意:父类静态方法无法被子类重写,因此向上转型后只能调用父类静态方法
         */
        System.out.println("=========================");        

        //如果想要调用 子类特有的成员属性和方法怎么办呢? 再转回来
        /**
         * 向下转型(强制转型),子类引用指向父类对象,必须强转
         * 可以调用子类特有的方法
         */
        Cat re_cat = (Cat) cat;
        re_cat.run();
        re_cat.eat();

        Dog re_dog = (Dog) dog;
        re_dog.sleep();
        re_dog.eat(); 
        System.out.println("====================");
        /**
         * 在强转的过程中,转换的右边即父类对象一定是之前经过向上转型得到的,原本就是子类对象,必须满足这个强转条件
         * instanceof 可以帮助判断 左边对象是否满足右边类的特性,是 就可以强转,下面重写上面 强转代码
         */
        if(cat instanceof Cat) {
            Cat re_cat2 = (Cat) cat;
            re_cat2.run();
            re_cat2.eat();

            re_cat2.say(); // 小猫碰胡须,调用的是 Cat子类独有的 static say()方法        }

        if(dog instanceof Dog) {
            Dog re_dog2 = (Dog) dog;
            re_dog2.sleep();
            re_dog2.eat();
        }

        if(animal instanceof Cat) {
            Cat animal_cat = (Cat) animal;

        } else {
            System.out.println("animal不是Cat类");
        }
    }
}

3.多态的实际应用

判断适合养什么宠物

Master.java

package com.imooc.animal;
public class Master {
    /**
     * 喂宠物
     * 喂猫猫:吃完东西后,主人会带着去玩线球
     * 喂狗狗:吃完东西后,主人会带着狗狗去睡觉
     * 养兔子、鹦鹉、乌龟
     */
    public void feed(Animal obj) {
        if(obj instanceof Cat) {
            Cat temp=(Cat) obj;
            temp.eat();
            temp.run();
        } else if(obj instanceof Dog) {
            Dog temp2=(Dog) obj;
            temp2.eat();
            temp2.sleep();
        }
    }
    /**
     * 饲养何种动物
     * 空闲时间多:养狗
     * 空闲时间少:养猫
     */
    public Animal raise(boolean isManyTime) {
        if(isManyTime) {
            System.out.println("主人时间多,适合养狗");
            return new Dog();
        }else{
            System.out.println("主人时间少,适合养猫");
            return new Cat();
        }
    }
}

MasterTest.java

package com.imooc.animal;
public class MasterTest {
    public static void main(String[] args) {
        Master master=new Master();
        Cat cat=new Cat();
        Dog dog=new Dog();
        master.feed(cat); //keypoint
        master.feed(dog);//keypoint
        System.out.println("================");
        boolean isManyTime=true;
        Animal temp=master.raise(isManyTime);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值