《Java程式設計基礎》 第8章手記Part 1
本章主要內容 Part 1
- 子類的建立
- 在子類中訪問父類的成員
- 覆蓋父類的方法
- ……
本章主要講繼承、抽象類和介面,這篇部落格講的是繼承這一部分。使用實驗的程式碼做例子來說明。
類的繼承
類的繼承是面向物件的程式設計的一個重要特點,通過繼承實現程式碼的複用,被繼承的類稱為父類或超類(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 | 微博@從流域到海域