04_继承
继承
运用继承,可以创建一个通用类,它定义了一系列相关项目的一般特性。该类可以被更具体的类继承,每个具体的类都增加了一些自己特有的东西。
被继承的类叫超类,继承超类的类叫子类
继承的基础
- 继承一个类,只要用extends关键字把一个类的定义合并到另一个中就可以了。
- 子类包括它的超类中的所有成员
- 一个子类可以是另一个类的超类
- 每个子类只能继承一个超类
- 对于超类中定义的private成员,只能被超类中定义的其他成员访问,子类没有权访问它
- 超类变量可以引用子类对象
class Box{
double width;
double height;
double depth;
Box(){
......
}
double volume(){
return width*height*depth;
}
}
class BoxWeight extends Box{
double weight;
BoxWeight(){
......
}
}
class DemoBoxWeight{
BoxWeight weightbox=new BoxWeight();
Box plainbox=new Box();
plainbox=weightbox; //将BoxWeight的引用赋给Box引用,这是合法的
//System.out.println("Weight of plainbox is:"+plainbox.weight); //Error!plainbox不能访问weight,只能访问超类定义的对象的那一部分
}
使用super
任何时候一个子类需要引用它直接的超类,可以使用关键字super实现
super有两种通用形式,第一种调用超类的构造函数,第二种用来访问被子类的成员隐藏的超类成员
使用super调用超类构造函数
super(parameter-list);
parameter-list定义了超类中构造函数所用到的所有参数,super()必须是在子类构造函数中的第一个执行语句
class BoxWeight extends Box{
double wieght;
BoxWeight(double w,double h,double d,double m){
super(w,h,d);
weight=m;
}
}
super的第二种用法
super的第二种形式多数是用于超类成员名被子类同样的成员名隐藏的情况
class X{
int i;
}
class Y extends X{
int i;
Y(int a,int b){
super.i=a;
i=b;
}
void show(){
System.out.println("i in superclass:"+super.i);
System.out.println("i in subclass:"+i);
}
}
public class UseSuper {
public static void main(String[] args) {
Y subObj=new Y(5,6);
subObj.show();
}
}
//output:
//i in superclass:5
//i in subclass:6
方法重载
- 类层次结构中,如果子类中的一个方法与它超类中的方法有相同的方法名和类型声明,称子类中的方法重载超类中的方法。从子类中调用重载方法时,总是会引用子类定义的方法,而超类中定义的方法将被隐藏。
- 如果希望访问被重载的超类方法,可以使用super
class A{
int i,j;
A(int a,int b){
i=a;
j=b;
}
void show(){
System.out.println("i and j "+i+" "+j);
}
}
class B extends A{
int k;
B(int a,int b,int c){
super(a,b);
k=c;
}
void show(){
super.show();
System.out.println("K:"+k);
}
}
public class UseOverride {
public static void main(String[] args) {
B subObj=new B(1,2,3);
subObj.show();
}
}
//output:
//
//k:3
动态方法调度
上面提到超类的引用变量可以引用子类对象
plainbox=weightbox
这里plainbox为超类Box的引用对象,weightbox为子类WeightBox的引用对象。plainbox=weightbox
中plainbox为引用对象,weightbox为被引用对象。如果在子类中重载了超类的方法,那么当通过plainbox调用重载方法时,会根据被引用对象即weightbox决定执行哪个版本的重载方法。
抽象类
有些情况仅希望定义一个超类,该超类定义了一中给定结构的抽象但是不提供任何完整的方法实现,由每个子类自己去填写细节。可以使用抽象方法,包括抽象方法的类为抽象类
- 一个抽象类不能通过new操作符直接实例化
- 不能定义抽象构造函数或抽象静态方法
- 抽象类中可以实现具体方法
- 所有抽象类的子类都必须执行超类中的所有抽象方法或者是它自己也声明称abstract
- 抽象类虽然不能实例化,但是可以用来创建对象引用
//Figure是抽象类,Rectangle是子类
Figure f=new Figure(); //illegal
Figure f;
Rectangle r =new Rectangle();
f=r; //this is OK
继承中使用final
使用final阻止重载
如果不希望方法重载,可以在方法前定义final修饰符,声明成final的方法不能被重载
class A{
final void meth(){
System.out.println("this is a final method.");
}
}
class B extends A{
void meth(){ //不能进行重载
System.out.println("illegal");
}
}
使用final阻止继承
如果希望防止一个类被继承,只需要在类声明前加final。声明一个final类宣告了它的所有方法也都是final。
Object类
Object类是所有其他类的超类,意味着一个Object类型的引用变量可以引用其他任何一个类的对象,因为数组像类一样执行,所以Object类型变量可以引用任何数组