1.訪問父類成員的三種方法
- 在子類內(nèi)部訪問。
- 通過子類創(chuàng)建的對象,用對象名.成員名訪問。
- 如果成員是靜態(tài)的,通過子類名.成員名或者父類名.成員名訪問。
class A
{
public int i;
public static int j;
}
class B extends A
{
public void f()
{
i = 1; //在子類內(nèi)部訪問父類成員
}
}
public class Test
{
public static void main(String[] args)
{
B b1 = new B();
A.j = 1; //通過父類名訪問靜態(tài)成員
b1.i = 2; //通過子類對象名訪問
B.j = 3; //通過子類名訪問靜態(tài)成員
}
}
2.在子類中對父類成員初始化
- 子類中沒有與父類同名的成員
class A
{
int i;
}
class B extends A
{
int j;
B()
{
}
B(int i, int j)
{
this.i = i; //對父類成員賦值,如果父類成員有很多,使用這種方法效率太低
this.j = j; //對子類的成員進行賦值
}
}
public class Test
{
public static void main(String[] args)
{
B b1 = new B();
B b2 = new B(1, 2);
System.out.printf("%d, %d\n", b1.i,b1.j);
System.out.printf("%d, %d\n", b2.i,b2.j);
}
}
- 子類中有與父類同名的成員(需要使用this和super來區(qū)分)
class A
{
int i;
}
class B extends A
{
int i; //子類中有與父類同名的成員,需要用this和super來區(qū)分
int j;
B()
{
}
B(int i, int j, int k)
{
this.i = i; //對子類自身成員賦值,this說明成員是子類的
this.j = j; //對子類的成員進行賦值
super.i = k; //對父類成員賦值,因為子類中有與父類同名的成員,就需要用super來說明當(dāng)前成員是父類的
}
void f()
{
System.out.println(super.i);
System.out.println(this.i);
}
}
public class Test
{
public static void main(String[] args)
{
B b1 = new B();
B b2 = new B(1, 2, 3);
System.out.printf("%d, %d\n", b1.i,b1.j);
System.out.printf("%d, %d\n", b2.i,b2.j);
b2.f();
}
}
輸出結(jié)果:
0, 0
1, 2
3
1
2.子類中super的使用
- 通過super關(guān)鍵字來實現(xiàn)對父類成員的訪問,用來引用當(dāng)前對象的父類。
class Animal
{
void eat()
{
System.out.println("animal : eat");
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("dog : eat");
}
void eatTest()
{
this.eat(); // this 調(diào)用自己的方法
super.eat(); // super 調(diào)用父類方法,只有在子類的成員和父類的成員同名的情況下需要用super進行區(qū)分
}
}
public class Test
{
public static void main(String[] args)
{
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
輸出結(jié)果:
animal : eat
dog : eat
animal : eat
- 使用super對父類成員進行初始化(可以避免對父類成員挨個初始化的問題)
子類是不能繼承父類的構(gòu)造方法的,它只是調(diào)用(隱式或顯式)。在子類的構(gòu)造方法中可使用語句super(參數(shù)列表)調(diào)用父類的構(gòu)造方法。
如果父類的構(gòu)造器帶有參數(shù),則必須在子類的構(gòu)造器中顯式地通過 super 關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表。
如果父類構(gòu)造器沒有參數(shù),則在子類的構(gòu)造器中不需要使用 super 關(guān)鍵字調(diào)用父類構(gòu)造器,系統(tǒng)會自動調(diào)用父類的無參構(gòu)造器。
class A
{
int i;
A()
{
System.out.println("嘿嘿");
}
A(int i)
{
this.i = i;
}
}
class B extends A
{
int j;
B()
{
super(); //調(diào)用A(),super()可不寫,不寫會隱式地調(diào)用
}
B(int k, int j )
{
super(k); //調(diào)用A(int i)顯式地調(diào)用父類中帶有參數(shù)的構(gòu)造器,對super的調(diào)用必須是構(gòu)造器中的第一個語句
this.j = j; //對子類的成員進行賦值
}
}
public class Test
{
public static void main(String[] args)
{
B b1 = new B(); /*創(chuàng)建對象時自動調(diào)用B的構(gòu)造器,因為B的構(gòu)造器中隱式地調(diào)用了A類的無參構(gòu)造器
所以創(chuàng)建B對象時,就會輸出“嘿嘿”*/
B b2 = new B(1, 2);
System.out.printf("%d, %d\n", b1.i,b1.j);
System.out.printf("%d, %d\n", b2.i,b2.j);
}
}
輸出結(jié)果:
嘿嘿
0, 0
1, 2
注意:對super的調(diào)用必須是構(gòu)造器中的第一個語句,必須在子類構(gòu)造器中才能通過super調(diào)用父類構(gòu)造器,且必須是子類構(gòu)造器中的第一個語句。
3.對super的理解
- 每個子類構(gòu)造器都會調(diào)用一個父類構(gòu)造函數(shù),如果沒有顯式的聲明,就會隱含的調(diào)用super(),相當(dāng)于調(diào)用父類的無參構(gòu)造函數(shù),如果父類沒有無參構(gòu)造函數(shù),則會報錯。
- 如果顯式的使用了super語句,super語句必須是構(gòu)造函數(shù)中第一個語句。
- 調(diào)用父類的構(gòu)造函數(shù)必須借助super實現(xiàn),每個子類構(gòu)造器只能調(diào)用一個構(gòu)造函數(shù),即在每個子類構(gòu)造函數(shù)中只能使用一次super。