注意,派生類的構造函數隱式調用了基類(或 Java 術語中的超類)的構造函數。在繼承中,所有的基類構造函數都是按照這些類出現在類層次中的順序在派生類的構造函數之前調用的。
將類型強制轉換到基類
與在 Java 中一樣,我們不能使用對基類的引用來訪問派生類的成員和方法,即使基類引用可能包含對派生類型對象的有效引用也同樣如此。
我們可以通過隱式地引用派生的類型來引用派生類:
ColorPoint clrpt = new ColorPoint();
Point pt = clrpt;
在這段代碼中,基類引用 pt 包含 clrpt 引用的副本。
base 關鍵字
通過使用 base 關鍵字,我們可以訪問子類中的基類成員,即使這些基類成員在超類中被重寫也同樣如此。例如,我們可以創建一個派生類,該類所包含的方法具有與基類中相同的簽名。如果我們在此方法前加上 new 關鍵字,就表示這是一個屬於派生類的全新方法。通過 base 關鍵字,我們仍然可以提供方法來訪問基類中的原始方法。
例如,我們的 Point 基類有名為 invert() 的方法,它交換 x 和 y 坐標。通過使用下面這樣的代碼,我們可以在派生類 ColorPoint 中提供此方法的替代方法:
public new void invert()
{
int holding = X;
X = Y;
Y = holding;
screenColor = Color.Gray;
}
正如您所見,該方法交換 x 和 y,然後將點的顏色設置為灰色。通過在 ColorPoint 中創建另一個方法(例如下面的這個方法),我們可以提供對此方法的基實現的訪問:
public void baseInvert()
{
base.invert();
}
然後,我們就可以通過調用 baseInvert() 方法來調用 ColorPoint 對象中的基方法。
ColorPoint clrpt = new ColorPoint();clrpt.baseInvert();
請記住,如果我們將對基類的引用賦值給 ColorPoint 的實例,然後訪問它的方法,我們將獲得相同的效果:
Point pt = clrpt;
pt.invert();
選擇構造函數
基類對象總是在任何派生類之前構造的。因此基類的構造函數在派生類的構造函數之前執行。如果基類有多個構造函數,派生類就可以決定要調用的構造函數。例如,我們可以修改我們的 Point 類來添加第二個構造函數:
public class Point
{
private int x, y;
public Point()
{
x = 0; y = 0;
}
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}