- 子类的创建 - 在子类中访问父类的成员 - 覆盖父类的方法 - ……
本章主要讲继承、抽象类和接口,这篇博客讲的是继承这一部分。使用实验的代码做例子来说明。
类的继承是面向对象的程序设计的一个重要特点,通过继承实现代码的复用,被继承的类称为父类或超类(superclass),由继承得到的类称为子类(subclass)
子类继承父类的成员变量和方法,同时可以修改父类的成员变量或重写父类的方法,还可以添加新的成员变量和方法。 Ps:C语言通过函数实现代码复用,但是函数一经写好,它的功能就已经确定,你修改这个函数会影响到所有已经使用这个函数的代码。了解这点,你就能理解继承这种代码复用机制的优点——可以修改,并且不会影响之前使用该功能的旧代码。
使用继承来组织、设计系统中的类,可以提高程序的抽象程度,使之更能接近人类的思维方式,同时继承也能较好的实现代码复用,提升程序开发效率,降低维护工作量。
Java中有一个名为java.lang.Object的特殊类,所有的类都是直接或间接继承得到的。如果没有指明子类所继承的父类,则默认继承这个特殊的类。
子类的创建方法
Java通过关键字extends实现继承,格式如下:
//Java继承示例
class SubClass extends SuperClass
{
...
}
C#实现继承的方式则没有使用任何关键字,而是通过英文分号实现的。
//C#继承示例
public class SubClass : SuperClass
{
}
实验8-1
class PersonB {
String name;
int age;
PersonB() {
name = "Steve Wang";
age = 20;
}
PersonB(String name, int age) {
this.name = name;
this.age = age;
}
void show() {
System.out.println(name+ " " +age);
}
}
class StudentB extends PersonB {
StudentB() {
name = "Zark Berg";
age = 23;
}
StudentB(String name, int age){
this.name = name;
this.age = age;
}
void show(){
System.out.println(name+ " " +age);
}
}
class Inherite {
public static void main(String[] args) {
PersonB a = new PersonB("apple",18);
StudentB b = new StudentB("pear",16);
a.show();
b.show();
}
}
说明: 1. 通过extends关键字,可将父类的成员继承给子类,在使用这些继承过来的成员时,可利用过去的语法即可。 2. Java程序在执行子类的构造方法之前,会先调用父类中没有参数的构造方法,其目的是为了帮助父类继承自父类的成员做初始化操作。
调用父类中特定的构造方法
即使程序中没有指明子类调用父类的构造方法,运行时也会默认代用父类中没有参数的构造方法。如果父类中有多个构造方法,则使用super关键字来调用特定的构造方法。this这里指代的是父类构造方法名称。
例: super(String a, int b)
将调用父类中有2个参数,并且第一个是字符串类型,第二个是整型的构造方法。
你需要阅读原书p123页到p123页的内容来具体了解super及super和this的关系。
在子类中访问父类的成员 也是使用super关键字,格式如下
super.变量名
super.方法名
需要说明的是,父类中的成员必须不是private,才能被子类访问,建议使用protected,使用public会降低封装性。
覆盖(Overriding)的概念与重载类似,都是Java“多态”的实现方法。覆盖是指在子类中,定义名称、参数个数和类型均与父类完全相同的方法,用来重写父类中同名方法的操作。C#的覆盖是通过虚方法实现的,具体参见之前的博文《C#多态》。
覆盖父类的方法
实验8-2
class Animal {
String name;
Animal() {
name = "Animal";
}
void play() {
System.out.println(name);
}
}
class Bird extends Animal {
String name;
Bird() {
name = "Bird";
}
void play() {
System.out.println(name);
}
}
class Fish extends Animal {
Fish() {
name = "Fish";
}
void play() {
System.out.println(name);
}
}
class Override {
public static void main(String[] args) {
Animal a = new Animal();
Bird b = new Bird();
Fish c = new Fish();
a.play();
b.play();
c.play();
Animal a1 = new Bird();
Animal a2 = new Fish();
a1.play();
a2.play();
}
}
用父类的对象访问子类的成员
Java中可以用父类的对象访问子类的成员,这体现了“父亲的行为像儿子,而不是儿子的行为像父亲”这种面向对象编的程思想。 注意: 父类的对象访问子类的成员仅限于“覆盖”发生时,如果子类没有覆盖父类的方法,则不能父类对象不能访问子类成员。
不可被继承的成员或最终类
默认情况下所有的成员变量和方法都可以被覆盖,如果不希望被覆盖,则需加final关键字做声明。
例:static final double PI = 3.1415926
例:public final void show()
final修饰成员变量,则说明该成员变量是最终量,即常量,程序的其他部分可以访问但不能修改。
final修饰成员方法,则该方法为最终方法,不能被子类所覆盖。
知乎:Solo | 微博@从流域到海域