Java读书笔记06 继承
继承基础知识
关键字extends表示继承,如:
class Student extends Person
{
…
}
正在构造的新类派生于一个已经存在的类,已经存在类被称为超类(superclass)、基类(base class)、或父类(parent class);新类被称为子类(subclass)、派生类(derived class)、或孩子类(child class)。
继承关系是“is-a”关系。
在Java中,所有的继承都是公有继承,而没有C++中的私有继承和保护继承。
Java不支持多继承。
Java中默认的访问权限修饰符(即什么也不加的情况),允许定义它的类自身,以及处于同一个包中的其他类访问.
在定义一个类的时候,如果没有显式指定该类的父类,那么该类就会继承于java.lang.Object类(JDK提供的一个类)。
重写
子类中的同名方法可以覆盖(override)超类中的方法。
如果覆盖了以后希望调用超类中的同名方法,用关键字super。
(C++中采用超类名加上::操作符的形式)
注意:super和this引用不是一样的概念。super不是一个对象的引用,只是一个指示编译器调用超类方法的特有关键字。
在覆盖一个方法的时候,子类方法不能低于超类方法的可见性。
构造器
因为子类不能访问超类的私有域,所以必须用super实现对超类构造器的调用。使用super调用构造器的语句必须是子类构造器的第一条语句。
如果子类的构造器没有显式地调用超类的构造器,将自动调用超类的默认构造器(无参数的),如果超类没有默认构造器,而子类没有显式调用超类的其他构造器,则报错。
多态
多态(polymorphism)指一个对象变量可以引用多种实际类型的现象。
在运行时能够自动地选择调用适当方法的现象称为动态绑定(dynamic binding)。
在Java中,不需要将方法声明为虚拟方法,动态绑定是默认的处理方式。如果不希望让一个方法具有虚拟特性,可以将它标记为final。
(注意:在C++和C#中,如果没有特别说明,所有的方法都不具有多态性。)
如果方法是private、 static、 final或者构造器,那么编译器可以准确地知道应该调用哪个方法,这种调用方式称为静态绑定(static binding)。
阻止继承:final类和final方法
不允许扩展的类被称为final类。
如:
final class XXX
{
…
}
final类中的方法自动地成为final方法。
如果将一个类声明为final,只有其中的方法自动地成为final,而不包括域。
(final域是指构造对象之后就不能改变它们的值了。)
类中的方法可以被声明为final,这样做,子类就不能覆盖这个方法。
强制类型转换
将一个子类的引用赋给一个超类变量编译器是允许的,但将一个超类的引用赋给一个子类变量,必须进行类型转换。用一对圆括号将目标类名括起来,并放置在需要转换的对象引用之前就可以了。
Manager boss=(Manager) staff[0];
在进行类型转换之前,先查看一下是否能够成功转换。使用instanceof运算符就可以实现。
if(staff[0] instanceof Manager)
{
boss=(Manager) staff[0];
}
注意:尽量少用类型转换和instanceof运算符。
抽象类
使用abstract关键字的方法称为抽象方法,充当占位的角色(因为编译器只允许调用在类中声明的方法),抽象方法不需要实现。
包含一个或多个抽象方法的类本身必须被声明为抽象的。
即使不含抽象方法,也可以将类声明为抽象类。
除了抽象方法外,抽象类还可以包含具体数据和具体方法。
抽象类不能被实例化。不能创建这个类的对象。注意,可以声明对象变量(它只能引用非抽象子类的对象),但是不能创建对象。
如:
Person p=new Student();
Person(抽象类) p(抽象类的变量)=new Student()(非抽象子类的实例);
C++中没有提供用于表示抽象类的特殊关键字,在尾部标记=0的方法称为纯虚函数,只要有一个纯虚函数,这个类就是抽象类。
受保护的访问
Java中的受保护部分对于所有子类及同一个包中的所有其他类都可见。这与C++中的保护机制稍有不同,Java中的protected概念要比C++中的安全性差。