繼承
一個新類從已有的類那裏獲得其已有的屬性和方法,這種現象叫類的繼承
這個新定義的類稱爲子類或派生類,被繼承的已經存在的類稱爲父類、超類或基類。
面向對象中的繼承實際上就是從一般到特殊
下面舉個例子
例1:
class Human {
String name = "張三";
int age = 20;
int high = 175;
int weight = 65;
}
class Student extends Human{
int num = 1201;
}
public class Test {
public static void main(String[] args) {
Student s = new Student();
System.out.printf("姓名:%s\n", s.name);
System.out.printf("年齡:%d\n", s.age);
System.out.printf("身高:%d\n", s.high);
System.out.printf("體重:%d\n", s.weight);
System.out.printf("學號:%d\n", s.num);
}
}
輸出結果爲:
姓名:張三
年齡:20
身高:175
體重:65
學號:1201
在上面的程序中,Human是基類,Student是子類,類的繼承使用的關鍵字是extends,具體使用的情況見上面程序的第八行,由第15行到19行可知,Student類已經繼承了Human類的屬性
Human中擁有的屬性Student中一定也有,如果沒有繼承,那那些屬性又要從新在Student中定義,這導致代碼的利用率不高,而且,通過繼承,使得類的功能更加清晰,而且,利用繼承可以較好的模擬出現實世界事物之間的聯繫
總之,繼承的主要好處有:
代碼的利用率得到極大的提高
形成一種類的體系結構
爲多態創造了條件
另外,關於訪問權限需要說明一下:
子類的所有方法(包括私有方法)都可以訪問父類內部的所有非私有成員
通過子類對象名可以訪問:
1、父類的所有非私有成員
2、子類的所有非私有成員
注:私有成員包括私有屬性和私有方法
下面舉個例子
例2:
class A {
private int s;
int m;
public int g;
protected int b;
private void fs() {
}
public void fg() {
}
void fm() {
}
protected void fb() {
}
}
class B extends A {
// 子類的所有方法內部都可以訪問父類除私有成員以外的所有成員
private void g() {
m = g = 10;
fg();
fm();
fb();
// s = 10; //error
// fs(); //error
}
}
public class Test {
public static void main(String[] args) {
B bb = new B();
// 通過子類對象名可以訪問父類除私有成員外的所有成員
bb.g = bb.b = bb.m = 22;
// bb.s = 11; //error
// bb.fs(); //error
bb.fg();
bb.fm();
bb.fb();
System.out.println("2014年6月30日08:41:46");
}
}
小結:
私有成員不能被繼承
實際上,私有成員物理上已經被繼承過來,只不過邏輯上程序員不能去訪問它。因此,私有成員的繼承必須慎重,否則會浪費內存
請看下圖
√ 表示可以被繼承和訪問
還有,java只支持但繼承,不允許多繼承,所謂多繼承就是一個子類只能有一個父類,當然,一個父類可以有多個子類
子類可以繼承父類一般的所有成員變量和成員方法(儘管被繼承的私有方法無法訪問),但是子類永遠無法繼承父類的構造方法,當然,在子類的構造方法中可以使用語句super(參數列表)調用父類的構造方法
下面舉個例子
例3:
class A {
public int i;
public int j;
public A() {
}
public A(int i, int j) {
this.i = i;
this.j = j;
}
}
class B extends A {
public int k;
public B() {
}
public B(int i, int j, int k) {
// A(i, j); //錯誤,不能直接調用父類的構造函數
super(i, j);// 這樣可以調用父類的構造函數
this.k = k;
}
}
public class Test {
public static void main(String[] args) {
B bb = new B(1, 2, 3);
System.out.printf("i= %d j = %d\n", bb.i, bb.j);
System.out.printf("k = %d\n", bb.k);
}
}
輸出結果爲:
i= 1 j = 2
k = 3
需要注意的是:對super的調用必須在構造函數裏邊,且必須是構造函數的第一個語句;每個子類構造方法的第一條語句都隱含的調用了super()語句;如果將super()語句寫出來,則必須保證父類中有無參數的構造函數,否則會出錯;也可以這樣寫super(實參),當然,父類必須有帶參數的構造函數;最後,一個子類的任何一個構造函數都只能出現一個super(參數列表)
【所有代碼均在windows系統下eclipse環境JDK 1.7下運行通過】
(如有錯誤,敬請指正)