继承与多态
继承一般是指晚辈从父辈那里继承财产,也可以说是子女拥有父母所给予他们的东西。
在面向对象程序设计中,继承的含义与此类似,所不同的是,这里继承的实体是类。也就是说继承是子类拥有父类的成员。
子类对象的创建
在类的声明中,可以通过使用关键字extends来显式地指明其父类。
语法格式为:
[修饰符] class 子类名 extends 父类名
修饰符:可选,用于指定类的访问权限,可选值为public、abstract和final。
子类名:必选,用于指定子类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。
extends 父类名:必选,用于指定要定义的子类继承于哪个父类。
继承的使用原则
子类可以继承父类中所有可被子类访问的成员变量和成员方法,但必须遵循以下原则:
(1)子类能够继承父类中被声明为public和protected的成员变量和成员方法,但不能继承被声明为private的成员变量和成员方法;
(2)子类能够继承在同一个包中的由默认修饰符修饰的成员变量和成员方法;
(3)如果子类声明了一个与父类的成员变量同名的成员变量,则子类不能继承父类的成员变量,此时称子类的成员变量隐藏了父类的成员变量;
(4)如果子类声明了一个与父类的成员方法同名的成员方法,则子类不能继承父类的成员方法,此时称子类的成员方法覆盖了父类的成员方法。
使用super关键字
super关键字主要有以下两种用途。
(1)调用父类的构造方法。
子类可以调用父类的构造方法,但是必须在子类的构造方法中使用super关键字来调用。其具体的语法格式如下:
super([参数列表]);
如果父类的构造方法中包括参数,则参数列表为必选项,用于指定父类构造方法的入口参数。
(2)操作被隐藏的成员变量和被覆盖的成员方法。(同名的情况下)
如果想在子类中操作父类中被隐藏的成员变量和被覆盖的成员方法,也可以使用super关键字。
语法格式为:
super.成员变量名
super.成员方法名([参数列表])
子类的继承
子类中的一部分成员是子类自己声明、创建的,另一部分是通过它的父类继承的。
在Java中,Object类是所有类的祖先类,也就是说任何类都继承自Object类。除了Object类以外的每个类,有且仅有一个父类,一个类可以有零个或多个子类。
继承关系的UML图
当一个类是另一个类的子类的时候,可以通过UML图使用实线连接两个类来表示二者之间的继承关系。实线的起始端是子类的UML图,实线的终止端是父类的UML图。在实线的终止端使用一个空心三角形表示实线的结束。
多 态
多态是面向对象程序设计的重要部分,是面向对象的3个基本特性之一。在Java语言中,通常使用方法的重载(Overloading)和覆盖(Overriding)实现类的多态性。
方法的重载
方法的重载是指在一个类中,出现多个方法名相同,但参数个数或参数类型不同的方法,则称为方法的重载。Java在执行具有重载关系的方法时,将根据调用参数的个数和类型区分具体执行的是哪个方法。
方法的覆盖
当子类继承父类中所有可能被子类访问的成员方法时,如果子类的方法名与父类的方法名相同,那么子类就不能继承父类的方法,此时,称子类的方法覆盖了父类的方法。覆盖体现了子类补充或者改变父类方法的能力,通过覆盖,可以使一个方法在不同的子类中表现出不同的行为。
抽象类
所谓抽象类就是只声明方法的存在而不去具体实现它的类。抽象类不能被实例化,也就是不能创建其对象。在定义抽象类时,要在关键字class前面加上关键字abstract。
语法格式为:
abstract class 类名{
类体
}
综上所述,抽象类和抽象方法的规则总结如下:
(1)抽象类必须使用abstract修饰符来修饰,抽象方法必须使用abstract修饰符来修饰。
(2)抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例,即使抽象类里不包含抽象方法,这个抽象类也不能创建实例。
(3)抽象类可以包含属性、方法(普通方法和抽象方法)、构造器、初始化块、内部类、枚举类。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。
(4)含有抽象方法的类(包括直接定义了一个抽象方法;继承了一个抽象父类,但没有完全实现父类包含的抽象方法;以及实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。
抽象类的作用
抽象类不能被创建实例,只能被继承。从语义角度上看,抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类为模板,从而避免子类的随意设计。
抽象类体现的就是这种模板模式的设计,抽象类作为多个子类的模板,子类在抽象类的基础上进行扩展,但是子类大致保留抽象类的行为。
final类
使用关键字final修饰的类称为final类,该类不能被继承,即不能有子类。有时为了程序的安全性,可以将一些重要的类声明为final类。例如,Java语言提供的System类和String类都是Final类。
语法格式为:
final class 类名{
类体
}
使用final修饰符修饰的方法是不可以被重写的。
如果想要不允许子类重写父类的某个方法,可以使用final修饰符修饰该方法。
例如:
public class Father {
public final void say (){}
}
public class Son extends Father {
public final void say (){} // 编译错误,不允许重写final方法
}
内部类
Java语言允许在类中定义内部类,内部类就是在其他类内部定义的子类。
一般格式为:
public class Zoo{
……
class Wolf{ // 内部类Wolf
}
}