多态

多态

一个对象变量可以指示多种实际类型的现象称为多态。

在运行时,能够自动选择适当的方法,成为动态绑定。

Java中,对象变量是多态的。某类型变量既可以引用本类对象,也可以引用任何一个子类的对象。

多态是方法的多态,属性没有多态。

public class Employee {
    private int salary = 3000;

    public int getSalary() {
        return salary;
    }
}

public class Manager extends Employee {

    private int bonus=0;


    public void setBonus(int bonus) {
        this.bonus = bonus;
    }

    @Override
    public int getSalary() {
        int baseSalary = super.getSalary();
        return baseSalary+bonus;
    }

}

public class Application {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        Employee e2 = new Employee();
        Manager boss = new Manager();

        Employee[] staff = new Employee[3];
        staff[0]=e1;
        staff[1]=e2;
        staff[2]=boss;

        boss.setBonus(5000);

        for(Employee e : staff){
            System.out.println(e.getSalary());
        }
    }
}

在Java中,子类引用的数组可以转换成超类引用的数组,不需要强制类型转换。

Manager[] managers = new Manager[10];
Employee[] staff = managers;
//managers 和 staff引用的是同一个数组

警告

staff[0] = new Employee();

这里staff[0]和manager[0]是相同的引用,把一个普通员工擅自归入经理行列中了。当调用manager[0].setBonus(5000)的时候,会试图调用一个不存在的实例字段,进而搅乱相邻存储空间的内容。
为了确保不发生这类破坏,所有数组都要牢记创建时的元素类型,并负责监督仅将类型兼容的引用存储到数组中。如果试图存储一个Employee类型的引用就会引发ArrayStoreException异常。

动态绑定

在运行时能够自动地选择适当的方法,称为动态绑定。动态绑定无须修改现有代码就可以对程序进行扩展。

在Java中,动态绑定是默认的行为,如果不希望让一个方法是虚拟的,可以将它标记为final。

阻止继承

不允许扩展的类称为final类,final类可以阻止派生出本类的子类。

public final class Executive extends Manager{

}

类中的方法也可以声明为final,这样子类就不能重写这个方法。(final类中的所有方法自动成为final方法)。

public class Employee{
	public final String getName(){
		return name;
	}
}

字段也可以声明为final,对于final字段,构造对象之后就不允许改变它们的值。但只有final类中的方法自动成为final,不包括字段。

将方法或类声明为final可以确保它们不会在子类中改变语义。String类是final类,这意味着不允许任何人定义String类的子类,如果有一个String引用,引用的一定是String对象,而不可能是其他类的对象。

对象引用的强制类型转换

将某个类的对象引用转换成另外一个类的对象引用,转换语法与数值表达式的强制类型转换类似。

Manager boss = (Manager) staff[0];

只能在继承层次内进行强制类型转换。当承诺不符时,会产生一个ClassCastException异常,如果没有捕获这个异常,程序就会终止。

在将超类转换成子类之前,应使用instanceof进行检查。

if(staff[1] instanceof Manager){
	boss = (Manager) staff[1];
}

如果类型转换不成功,编译器就不会让你完成这个转换。

String c = (string) staff[1];//编译错误 String类不是Employee的子类。

一般情况下,最好尽量少用强制类型转换和instanceof运算符,而需要重新设计超类添加方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值