public abstract class A {
int i=1;
public void printI() {
System.out.println("i="+i);
}
}
public class B extends A{
int i=2;
public static void main(String[] args) {
B b=new B();
b.printI();
}
}
那么,控制台打出來的i的值是多少?
呵呵,如果一下功夫就能說出正確結果1,那么,下面部分就不需要往下看了。
1、類的繼承知識點
(1)java不支持多重繼承,也就是說子類至多只能有一個父類
(2)子類繼承了其父類中不是私有的成員變量和成員方法,作為自己的成員變量和方法
(3)子類中定義的成員變量和父類中定義的成員變量相同時,則父類中的成員變量不能被繼承
(4)子類中定義的成員方法,並且這個成員方法的名字,返回類型,及參數個數和類型與父類的某個成員方法完全相同,則父類的成員方法不能被繼承。
2、答案是2者如是說
子類B中的變量i和父類A中的變量i重名, 那么子類B中的變量i將會覆蓋掉父類中的同名變量i. 則訪問父類中的變量時jvm會把子類cast到父類.所以,打印出的結果應該是“i=2”;
3、歧義的產生
歧義的產生最關鍵的地方是子類B中的變量i將會覆蓋掉父類中的同名變量i的覆蓋兩個字。這里,我覺得這兩個字容易誤導。應該改為屏蔽或隱藏。因為在這里父類的成員變量是沒有被改變。
4、jvm的執行過程
(1)子類B 的構造方法被調用,實例化一個B對象,B對象的成員被初始化
(2)jvm隱含的調用父類的構造方法,實例化一個A對象,A對象的成員被初始化。
(3)由於A對象的printI()未被屏蔽,所以調用的A對象的printI()函數。
那么,在這里A的成員函數當然是訪問自己的成員變量了。
5、super關鍵字
super關鍵字在java中的作用是使被屏蔽的成員變量或者成員方法或變為可見,或者說用來引用被屏蔽的成員變量和成員成員方法。super是用在子類中,目的是訪問直接父類中被屏蔽的成員。上面的代碼也可以這樣寫:
Java代碼
public abstract class A {
int i=1;
public void printI() {
System.out.println("i="+i);
}
}
public class B extends A{
public int i=2;
public void printI(){
super.printI();
}
public static void main(String[] args){
B b= new B();
b.printI();
}
}
注:
JVM實例化程序的過程中,若對子類進行實例化,必然要對父類的構造器進行實例化繼承。
C exteds D(){}
C c = new C();
構造器,采取先父后子的關系。
而方法,若調用的方法為子類所覆蓋,則主動調用兒子的方法,因為此時,已經繼承了父類所擁有的
相關變量,而方法行為,子類具有相對來說的獨立性,可以獨立調用。
D c = new C();
JVM處理過程,也是如此。
先繼承D的構造器(基因),再加載C獨自的構造器,同時,對相關方法進行相應的調用。
