实验八 多态、抽象类

一、实验预热
1、“ClassCastException”是由什么产生的?
类型强制转换失败

2、向上转型和向下转型的一般形式是什么?
定义父类为A,子类为B
向上转型:A a = new B();
向下转型:B b = (B)a;

3、为了保证转型的顺利进行,我们使用哪个关键字来判断对象是否属于某个类?
instanceof

4、抽象类和普通类的区别?
抽象类无法实例化,可以包含普通方法和抽象方法,无法用final修饰。

5、向上转型和向下转型有什么意义?
当某个方法入口必须是父类的对象时,子类想要调用这个方法就必须使用向上转型变成父类的对象来使用。
当父类的对象想要调用子类独有的属性和方法时,必须向下转型为子类的对象才能够调用。

二、实验内容
1、需求:
1)定义一个主人类Master,包括两个方法:给宠物看病的方法cure(Pet pet)和给宠物喂食的方法feed(Pet pet),主人可以通过调用cure方法判断pet的健康状况,决定是否调用pet.toHospital()去医院看病,可以通过调用feed方法调用pet.eat()。
2)定义一个抽象动物类Pet,其属性包括姓名、健康值(默认值为60,要求健康值只能在0-100之间)、亲密度(默认值为10),其方法包括打印宠物信息的方法print()、抽象方法toHospital()、抽象方法eat()。通过继承Pet类,产生两个子类Dog和Cat,子类具有成员属性品种、打印方法print(),需要覆写Pet类的抽象方法,来实现去医院(输出打针、吃药,同时健康值设置到60)和吃东西的行为(每喂一次食物,亲密度和健康值加10)。实现如图所示功能:


image.png

代码:

package leif.tests;

public class ExperimentalReport {
    public static void main(String[] args) {
        Master master = new Master();
        Pet pet = new Dog("无名氏", "吉娃娃");
        master.cure(pet);
        pet.print();
        System.out.println("*************************");
        master.feed(pet);
        pet.print();
    }
}

class Master {
    public void cure(Pet pet) {
        if (pet.getHealth() < 60) {
            pet.toHospital();
        }
    }

    public void feed(Pet pet) {
        int health = pet.getHealth() + 10;

        if (health > 100) {
            pet.setHealth(100);
        } else {
            pet.setHealth(health);
        }

        pet.setIntimacy(pet.getIntimacy() + 10);
    }
}

abstract class Pet {
    private String name;
    private int health = 60;
    private int intimacy = 10;

    public Pet(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        this.health = health;
    }

    public int getIntimacy() {
        return intimacy;
    }

    public void setIntimacy(int intimacy) {
        this.intimacy = intimacy;
    }

    public void print() {
        System.out.println("宠物的自白:");
        System.out.println("我的名字叫" + name + ",我的健康值是" + health + ",我和主人的亲密程度是" + intimacy + "。");
    }

    public abstract void toHospital();

    public abstract void eat();
}

class Dog extends Pet {
    private String type;

    public Dog(String name, String type) {
        super(name);
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public void print() {
        super.print();
        System.out.println("我是一条" + type);
    }

    @Override
    public void toHospital() {
        System.out.println("打针、吃药");
        super.setHealth(60);
    }

    @Override
    public void eat() {
        setHealth(getHealth() + 10);
        setIntimacy(getIntimacy() + 10);
    }
}

class Cat extends Pet {
    private String type;

    public Cat(String name, String type) {
        super(name);
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public void print() {
        super.print();
        System.out.println("我是一只" + type);
    }

    @Override
    public void toHospital() {
        System.out.println("打针、吃药");
        super.setHealth(60);
    }

    @Override
    public void eat() {
        setHealth(getHealth() + 10);
        setIntimacy(getIntimacy() + 10);
    }
}

结果截图:


image.png

2、现在有三类事物:
1)机器人:充电、工作
2)人:吃饭、工作、睡觉
3)猪:吃饭、睡觉
要求实现可以任意的控制机器人、人、猪的行为(吃饭、睡觉、工作)。通过分析可知,这三个事物有一个共同的地方,就是行为,那么可以把行为作为一个抽象类Action,而机器人、人、猪可以认为是行为这个类的子类继承。
Action类包括抽象方法eat()、sleep()、work()和普通方法command(int flag),通过输入不同的flag来切换行为。
请实现猪的eat()打印“猪正在吃饭!”、sleep()打印:“猪正在睡觉!”,猪不会工作,则work()方法体为空。机器人和人也要有类似的行为实现。
代码:

package leif.tests;

public class ExperimentalReport {
    public static void main(String[] args) {
        function(new Robot());
        function(new Human());
        function(new Pig());
    }

    public static void function(Action action){
        action.command(1);
        action.command(2);
        action.command(3);
    }
}

enum Flag {
    EAT(1), SLEEP(2), WORK(3);

    private int flag;

    private Flag(int flag) {
        this.flag = flag;
    }

    public int getFlag() {
        return flag;
    }

    public void setFlag(int flag) {
        this.flag = flag;
    }

    public static String getFlag(int i) {
        for (Flag flag : Flag.values()) {
            if (i == flag.getFlag()) {
                return flag.name();
            }
        }

        return "";
    }
};

abstract class Action {
    public abstract void eat();

    public abstract void sleep();

    public abstract void work();

    public void command(int flag) {
        switch (Flag.getFlag(flag)) {
            case "EAT":
                eat();
                break;
            case "SLEEP":
                sleep();
                break;
            case "WORK":
                work();
                break;
        }
    }
}

class Robot extends Action {
    @Override
    public void eat() {
        System.out.println("充电");
    }

    @Override
    public void sleep() {}

    @Override
    public void work() {
        System.out.println("工作");
    }
}

class Human extends Action {
    @Override
    public void eat() {
        System.out.println("吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉");
    }

    @Override
    public void work() {
        System.out.println("工作");
    }
}

class Pig extends Action {
    @Override
    public void eat() {
        System.out.println("吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉");
    }

    @Override
    public void work() {}
}

结果截图:


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容