15-多态

覆写(Override)
在继承关系中,子类如果定义了一个与父类方法签名( 方法的名称和参数类型)完全相同的方法,被称为覆写(Override)。
Override(覆写)和 Overload(重载)不同的是,如果方法签名不同,就是Overload,Overload是一个新方法;如果方法签名相同,返回值也相同,就是Override。
注意:方法名相同,方法参数相同,但方法返回值不同,也是不同的方法。在Java程序中,出现这种情况,编译器会报错。
class Person {
    public void run() {}
}

public class Student extends Person {
    @Override // Compile error!
    public void run(String s) {}
}
//加上 @Override 可以让编译器检查是否进行了正确的覆写,但是@Override不是必需的


多态(Polymorphic)
多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法,而且允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码。
public class Main {
    public static void main(String[] args) {
        // 给一个有普通收入、工资收入和享受国务院特殊津贴的小伙伴算税:
        Income[] incomes = new Income[] {
            new Income(3000),//普通
            new Salary(7500),//工资
            new StateCouncilSpecialAllowance(15000)//津贴
        };
        System.out.println(totalTax(incomes));
    }
    //可变参数 Income类 
    public static double totalTax(Income... incomes) {
        double total = 0;
        for (Income income: incomes) {
            total = total + income.getTax();
            //当income = Income(3000) ,会执行Income类中的getTax
            //当income = Salary(3000) ,会执行Salary类中的getTax
        }
        return total;
    }
}

class Income {
    protected double income;

    public Income(double income) {
        this.income = income;
    }

    public double getTax() {
        return income * 0.1; // 税率10%
    }
}

class Salary extends Income {
    public Salary(double income) {
        super(income);//初始化字段
    }
    
    @Override
    public double getTax() {
        if (income <= 5000) {
            return 0;
        }
        return (income - 5000) * 0.2;
    }
}

class StateCouncilSpecialAllowance extends Income {
    public StateCouncilSpecialAllowance(double income) {
        super(income);
    }

    @Override
    public double getTax() {
        return 0;
    }
}



利用多态,totalTax()方法只需要和Income打交道,它完全不需要知道Salary和StateCouncilSpecialAllowance的存在,就可以正确计算出总的税。

覆写Object方法
因为所有的class最终都继承自Object,而Object定义了几个重要的方法:
toString():把instance输出为String;
equals():判断两个instance是否逻辑相等;
hashCode():计算一个instance的哈希值。

在必要的情况下,我们可以覆写Object的这几个方法,用来实现具体的功能。
class Person {
    ...
    @Override
    public String toString() {
        return "Person:name=" + name;
    }
}

调用super
在子类的覆写方法中,如果要调用父类的被覆写的方法,可以通过super来调用。
class Person {
    protected String name;
    public String hello() {
        return "Hello, " + name;
    }
}

class Student extends Person {
    @Override
    public String hello() {
        // 调用父类的hello()方法:
        return super.hello() + "!";
    }
}

final
继承是可以允许子类覆写父类的方法。如果一个父类不允许子类对它的某个方法进行覆写,可以把该方法标记为final。用final修饰的方法不能被Override(覆写):
class Person {
    protected String name;
    public final String hello() {//不允许覆写
        return "Hello, " + name;
    }
}


如果一个类不希望任何其他类继承自它,那么可以把这个类本身标记为final
final class Person {
    protected String name;
}

一个类的实例字段,同样可以用final修饰。用final修饰的字段在初始化后不能被修改。
class Person {
    public final String name;
    public Person(String name) {//可在构造中初始化final字段
        this.name = name;
    }
}


个人理解:
多态是将各种解决类型问题的方法预先写定,由运行时期的实际类型决定如何调用?

猜你喜欢

转载自www.cnblogs.com/nsss/p/11417494.html