方法重写和多态

本文深入探讨了Java中的方法重写与多态概念,解释了如何通过子类重写父类方法实现个性化输出,以及多态如何提高代码的可扩展性和可维护性。文章还介绍了抽象类和抽象方法的使用,以及向上转型和向下转型的概念。

方法重写

学过继承后,我们知道可以将子类都具有的属性和方法放到父类中。子类可以调用父类中的方法,但是不同子类调用父类方法,输出的格式都是一致的,要想个性化输出就可以用到方法重写。

什么是方法重写

方法的重写又称方法的覆盖:子类根据需求对从父类继承的方法进行重新编写。重写时,可以用super.方法的方式来保留父类的方法,需要注意的是构造方法不能被重写。

方法重写的规则

在继承的情况下,子类的方法满足一下条件:
①方法名相同
②参数列表相同
③返回值类型相同,或者是父类返回值类型的子类
④访问修饰符的权限不能小于父类方法
⑤抛出的异常不能多于父类

方法的重载与重写对比

在这里插入图片描述
示例:

// 父类Pet类
public class Pet extends Object {
    private String name;
    private int health;
    private int love = 60;
    public int a = 10;

    public Pet() {
    }

    public Pet(String name, int health, int love) {
        this.name = name;
        setHealth(health);
        setLove(love);
    }

    public String getName() {
        return name;
    }

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

    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        if(health<0||health>100){
            System.out.println("健康值应该在0至100之间,默认值为60。");
            return;
        }
        this.health = health;
    }

    public int getLove() {
        return love;
    }

    public void setLove(int love) {
        if(love<0||love>100){
            System.out.println("健康值应该在0至100之间,默认值为60。");
            return;
        }
        this.love = love;
    }

    public void product() {
        System.out.println("我的名字是" + this.getName() + ",健康值是" + this.getHealth()
                + ",和主人的亲密度为" + this.getLove());
    }
    public void  play(){
        System.out.println("陪主人玩!");
    }
    public void toHospital(){
        System.out.println("去医院");
    }
//  Dog类继承Pet类
public class Dog extends Pet{
    private String strain;
    public int a = 5;

    public Dog() {
    }

    public Dog(String name, int health, String strain, int love) {
        super(name,health,love);
        this.strain = strain;
    }

    public String getStrain() {
        return strain;
    }

    public void setStrain(String strain) {
        this.strain = strain;
    }
    public void eat(){

    }
	// 重写父类product()方法
    public void product(){
        super.product();
        System.out.println("我是一只"+strain);
    }
    // 重写父类play()方法
    public void play(){
        super.play();
        System.out.println("主人给我一根骨头");
    }
    // 重写父类toHospital()方法
    public void toHospital(){
        System.out.println("带狗狗去医院");
    }

Object类

Object类是java中所有类的父类,其中有一些方法经常会被子类重写:

在这里插入图片描述
示例

// 在上述Pet类中重写equals()方法
// 默认当Pet的姓名、健康值和亲密度都相同时,默认为同一对象

```java
public boolean equals(Object obj){
    if(this == obj){
        return true;
    }
    if(obj instanceof Pet){
        Pet pet = (Pet)obj;
        // 自定义比较规则
        // 如果宠物名称相同,则认为是一个对象
        if(this.name!=null&&this.name.equals(pet.name)&&this.health==pet.health&&this.love==pet.love){
            return true;
        }
    }
    return false;
}

多态

什么是多态

在这里插入图片描述
如上图打印机的例子,生活中的多态是指同一种事物,由于条件不同,产生的结果也不同。在java中多态是指同一个引用类型,使用不同的实例二执行不同操作。

为什么使用多态

在宠物的例子中,如果Pet类中有一个给宠物看病的方法,当给定不同宠物时,可能需要频繁修改代码,为了增加代码的可扩展性和可维护性,所以我们要使用多态。
示例:

// Dog类
public class Dog extends Pet {
    public void toHospital() {
        this.setHealth(60);
        System.out.println("打针、吃药");
    }
}
// Penguin类
public class Penguin extends Pet {
    public void toHospital() {
        this.setHealth(70);
        System.out.println("吃药、疗养");
    }
}
// Master类
public class Master {
    public void cure(Pet pet) {
        if (pet.getHealth() < 50)
            pet.toHospital();        
    }
}
// Test类部分代码
Pet pet = new Dog();
Master master = new Master();
master.cure(pet);

抽象类abstract

在上述Dog类中有个toHospital()方法,由于企鹅类和狗类中都有这个方法,故可以放到父类中,但是父类中该如何实现这个方法呢,由于方法重写后,子类调用的是重写后的方法,故父类方法的执行体并不重要,可以不写,这个时候就可以将父类定义为抽象类,用abstract关键字修饰,代码如下:

public abstract class Pet {
	//其他代码略
	// 将toHospital()定义为抽象方法,抽象方法没有方法体
	public abstract void toHospital();
抽象方法规则

①抽象方法必须在抽象类中
②抽象方法没有结构体
③子类继承抽象类的时候,必须实现父类的抽象方法,除非这个子类也是抽象方法

向上转型

向上转型:父类的引用指向子类对象,自动进行类型转换
<父类型> <引用变量名> = new <子类型>();

Pet pet = new Dog();

向上转型时,调用父类、子类同名方法时,调用的是子类的方法;调用同名属性时,调用的是父类的属性

向下转型

向下转型:将一个指向子类对象的父类引用赋给一个子类的引用,即:父类类型转换为子类类型
<子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;

Dog dog=(Dog)pet;
dog.(Dog类的特有方法)
instanceof运算符
// 用于判断pet是不是Dog类型
if(pet instanceof Dog){
	Dog dog = (Dog)pet;
	// Dog类特有方法
    dog.playDish();
}

注意:使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值