5.1 类、超类和子类

来源:互联网 发布:传奇盛世宝石升级数据 编辑:程序博客网 时间:2024/06/05 20:51
关键字extends表示继承,表明正在构造的新类派生于一个已存在的类。
已存在的类称为超类(superclass)、基类、或父类;新类称为子类(subclass)、派生类或或孩子类。
子类比超类拥有的功能更加丰富。
在通过扩展超类定义子类的时候,仅需要支出子类与超类的不同之处。然而超类中有些方法对子类不一定使用,为此需要提供一个新的方法来覆盖(overdide)超类中的这个方法。
子类不能直接访问超类的私有域,如果一定要访问就必须借助于共有的接口。
如果超类和子类拥有同名的方法且需要调用超类的方法,则可以使用关键字super.来完成
public doubel getSlary() {
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
可以看出,在子类中可以增加域、增加方法或覆盖超类的方法,然而绝对不能删除继承的任何域和方法。
super在构造器中的应用
public Manager(String n, double s, int year, int month, int day) {
super(n,s,year,month,day);
bonus = 0;
}
这里super的含义是
调用超类Employee中含有n、s、year、month和day参数的构造器
由于子类的构造器不能访问超类的私有域,所以必须利用超类的构造器对这部分私有域进行初始化。使用super调用构造器的语句必须是子类构造器的第一条语句。

关键字this的两个用途:
1引用隐式参数
2调用该类其他的构造器
关键字super的两个用途:
1调用超类的方法
2调用超类的构造器

一个对象变量可以指示多种实际类型的现象被称为多态(polymorphism)在运行时能够自动的选择调用哪个方法的现象称为动态绑定(dynamic binding)。


5.1.1 继承层次
继承并不仅限于一个层次。由一个公共超类派生出来的所有类的几何体称为继承层次(inheritance hierarchy)。从某各类到其祖先的路径被称为子孙继承链。
5.1.2 多态 
子类每个对象也是超类的对象,因此其具有置换法则。 例如可以将子类的对象赋给父类。
对象变量是多态的。一个超类变量既可以引用一个超类对象,也可以引用一个子类的对象
显然不能讲超类的引用赋给子类变量。例如:
Manager m = staff[i];
就是错误的

5.1.3 动态绑定
弄清调用对象方法的执行过程十分重要
1)编译器查看对象的声明类型和方法名。编译器会意义列举所有C类中名为f的方法 和其超类中访问属性为public且名为f的方法(超类的私有方法不可访问)。           
2)接下来编译器将查看调用方法时提供的参数类型。

方法的名字和参数列表称为方法的签名。                                                   
不过返回类型不是签名的一部分。但允许子类讲覆盖方法的返回类型定义为原返回类型的子类型。
3)如果是private方法、static方法、final方法或者构造器,name编译器可以准确的知道应该调用那个方法,这种调用方式称为静态绑定(static binding)                                
4)当程序运行并且采用动态绑定调用方法时虚拟机一定调用与x所引用对象的实际类型最合适的那个类的方法。                         
每次调用都要进行搜索,时间开销大,因此虚拟机预先为每个类创建了一个方法表(method table),其中勒出了所有方法的签名和实际调用的方法。

5.1.4 阻止继承:final类和方法
不允许扩展的类称为final类。
类中的特定方法也可以被声明为final,如果这样做子类就不能覆盖这个方法(final类的所有方法都自动的转换为final方法)。
不过如果将一个类生命为final,只有其中的方法自动的称为final,而不包括域。

5.1.5 强制类型转换
有时候也可能需要将某个类的对戏昂引用转换成另外一个类的对象引用。仅需要用一对圆括号将目标类名括起来,防止在需要转换的对象引用之前就可以了。例如:
Manager boss = (Manager) staff[0];
在继承链上自上往下进行类型转换时,如果不能成功的转换,系统将报告这个错误并产生一个ClassCastException的异常,如果没有捕获这个异常,程序就会终止。 
所以可以利用instanceof运算符查看能否进行转换
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例
if(staff[1] instanceof Manager) {
boss = (Manager) staff[1];
}
如果这个类型转换不可能成功,编译器将不会进行这个转换


综上所述:
只能在继承层次内进行类型转换。
在将超类转换成子类之前,应该使用Instanceof进行检查。

5.1.6 抽象类
祖先类更加通用,人们只将它作为派生其他类的基类,而不作为想使用的特定的实例类。
可以使用abstract关键字进行抽象申明,例如:
public abstract String getDescription():
//不需要实现这个方法
包含一个或多个抽象方法的类本身必须被声明为抽象类
除了抽象方法外,抽象类也可以包含具体数据和具体方法。
抽象方法充当着占位的角色,他们的具体实现在子类中。
类即使不含抽象方法,也可以将类声明为抽象类。
抽象类不能被实例化。
需要注意,可以定义一个抽象类的对象变量,但是他只能引用非抽象子类的对象

5.1.7 受保护访问
Java用于控制可见性的4个访问修饰符
1)仅对本类可见——private
2)对所有类可见——public
3)对本包和所有子类可见——protected
3)对本包可见——默认 不需要修饰符





                                                                                                                                                                                                                                 
0 0