作为一种面向对象编程的语言,Java允许程序员从已经存在的类中定义新的类,我们称之为继承(inheritance)。继承作为Java语言的一个重要的特性,可以让我们通过设计出一个通用的父类(parent class)和若干子类(child class)的关系,使得子类能够共享父类的一些特征和行为。
在Java中,我们使用关键词extends来表示父类和子类的继承关系。父类也可以被称为超类(superclass)或基类(base class);子类也可以被称为次类(subclass)、拓展类(extended class)或派生类(derived class)。在Java中,一个子类只能够继承一个父类,一个父类可以有多个子类。子类从父类中继承一些可被访问的数据域和方法,子类也可以拥有自己的新的数据域和新的方法。
比如,我们可以设计出如下的父类和子类:
public class Geometry
{
private String color = "White";
public void setColor(String col)
{
color = col;
}
public String getColor()
{
return color;
}
}
public class Circle extends Geometry
{
private double radius;
public Circle(double rad, String color)
{
radius = rad;
setColor(color);
}
public double getRadius()
{
return radius;
}
public void setRadius(double rad)
{
radius = rad;
}
}
在父类Geometry中,定义了一个String型的数据域color,Circle继承了这个数据域;但是,由于color是实例变量(private instance variable),Circle必须通过Geometry Class中的getColor和setColor这两个方法,去获取、改变color。在这里,setColor和getColor是被Circle继承的两个方法。在Circle中,我们定义了一个构造器,在这个构造器中,我们通过调用setColor这个方法,对color这个数据域进行了访问和改变。
在讲构造器的知识点时,我们已经说过,子类可以重写(overriding)父类的方法,让子类的对象可以做出一些不同于父类的行为,我们把这种现象称之为多态(polymorphism)。另外,多态意味着父类的变量可以指向子类对象。比如,刚才我们定义了两个类——Geometry 和 Circle,我们可以说Geometry是Circle的父类型,Circle是Geometry的子类型。子类是父类的特殊化,每个子类的实例实际上也是其父类的实例。比如,我们可以定义一个参数是Geometry型的方法如下,然后再调用它:
public static void main(String[] args)
{
dosomething(new Geometry());
dosomething(new Circle(1, "Black"));
}
public static void dosomething(Geometry object)
{
System.out.println(object.getColor());
}
显示结果是:
White
Black
注意,上面的dosomething方法的参数是Geometry类型的对象,而我们在调用它时创建了2个对象,一个是Geometry型的实例,另一个既是Circle型的实例,也是Geometry型的实例,因此,这两个对象都可以作为dosomething的实际参数。
由于一个子类的实例也可以是父类型的实例,这里就牵涉到另外两个概念:声明类型(declared type)和实际类型(actual type),比如:
Geometry object = new Circle(1, “Black");
上面这行代码就声明了一个变量object,object的声明类型就是Geometry型,实际类型就是Circle型。这个时候就产生了一个问题:如果我们使用这个变量object去调用一个被子类Circle重写过的方法,那么Java 虚拟机会选择调用哪个呢?答案是调用Circle里重写的方法。这个就叫做动态绑定(dynamic binding)。当然,我们也可以使用这个object去调用Geometry里定义的其他方法,只不过当我们调用的这个方法(overriding methods)既在父类中,也在子类中的时候,Java 虚拟机会选择object的实际类型里的这个被重写的方法。
最后,给大家留一个小问题:
public class Geometry
{
public void dosomething()
{
System.out.println("Geometry");
}
}
public class Circle extends Geometry
{
public void dosomething()
{
System.out.println("Circle");
}
}
如上所示,我们定义了父类Geometry和子类Circle。如果通过如下代码对方法dosomething进行调用,请问输出结果是什么?
Geometry object = new Circle();
object.dosomething();
附:AP CS A Free Response Questions 下载地址:
https://apcentral.collegeboard.org/courses/ap-computer-science-a/exam
© 2024. All Rights Reserved. 沪ICP备2023009024号-1