1.訪問(wèn)父類成員的三種方法
- 在子類內(nèi)部訪問(wèn)。
- 通過(guò)子類創(chuàng)建的對(duì)象,用對(duì)象名.成員名訪問(wèn)。
- 如果成員是靜態(tài)的,通過(guò)子類名.成員名或者父類名.成員名訪問(wèn)。
class A
{
public int i;
public static int j;
}
class B extends A
{
public void f()
{
i = 1; //在子類內(nèi)部訪問(wèn)父類成員
}
}
public class Test
{
public static void main(String[] args)
{
B b1 = new B();
A.j = 1; //通過(guò)父類名訪問(wèn)靜態(tài)成員
b1.i = 2; //通過(guò)子類對(duì)象名訪問(wèn)
B.j = 3; //通過(guò)子類名訪問(wèn)靜態(tài)成員
}
}
2.在子類中對(duì)父類成員初始化
- 子類中沒(méi)有與父類同名的成員
class A
{
int i;
}
class B extends A
{
int j;
B()
{
}
B(int i, int j)
{
this.i = i; //對(duì)父類成員賦值,如果父類成員有很多,使用這種方法效率太低
this.j = j; //對(duì)子類的成員進(jìn)行賦值
}
}
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來(lái)區(qū)分)
class A
{
int i;
}
class B extends A
{
int i; //子類中有與父類同名的成員,需要用this和super來(lái)區(qū)分
int j;
B()
{
}
B(int i, int j, int k)
{
this.i = i; //對(duì)子類自身成員賦值,this說(shuō)明成員是子類的
this.j = j; //對(duì)子類的成員進(jìn)行賦值
super.i = k; //對(duì)父類成員賦值,因?yàn)樽宇愔杏信c父類同名的成員,就需要用super來(lái)說(shuō)明當(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的使用
- 通過(guò)super關(guān)鍵字來(lái)實(shí)現(xiàn)對(duì)父類成員的訪問(wèn),用來(lái)引用當(dāng)前對(duì)象的父類。
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進(jìn)行區(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對(duì)父類成員進(jìn)行初始化(可以避免對(duì)父類成員挨個(gè)初始化的問(wèn)題)
子類是不能繼承父類的構(gòu)造方法的,它只是調(diào)用(隱式或顯式)。在子類的構(gòu)造方法中可使用語(yǔ)句super(參數(shù)列表)調(diào)用父類的構(gòu)造方法。
如果父類的構(gòu)造器帶有參數(shù),則必須在子類的構(gòu)造器中顯式地通過(guò) super 關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表。
如果父類構(gòu)造器沒(méi)有參數(shù),則在子類的構(gòu)造器中不需要使用 super 關(guān)鍵字調(diào)用父類構(gòu)造器,系統(tǒng)會(huì)自動(dòng)調(diào)用父類的無(wú)參構(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()可不寫,不寫會(huì)隱式地調(diào)用
}
B(int k, int j )
{
super(k); //調(diào)用A(int i)顯式地調(diào)用父類中帶有參數(shù)的構(gòu)造器,對(duì)super的調(diào)用必須是構(gòu)造器中的第一個(gè)語(yǔ)句
this.j = j; //對(duì)子類的成員進(jìn)行賦值
}
}
public class Test
{
public static void main(String[] args)
{
B b1 = new B(); /*創(chuàng)建對(duì)象時(shí)自動(dòng)調(diào)用B的構(gòu)造器,因?yàn)锽的構(gòu)造器中隱式地調(diào)用了A類的無(wú)參構(gòu)造器
所以創(chuàng)建B對(duì)象時(shí),就會(huì)輸出“嘿嘿”*/
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
注意:對(duì)super的調(diào)用必須是構(gòu)造器中的第一個(gè)語(yǔ)句,必須在子類構(gòu)造器中才能通過(guò)super調(diào)用父類構(gòu)造器,且必須是子類構(gòu)造器中的第一個(gè)語(yǔ)句。
3.對(duì)super的理解
- 每個(gè)子類構(gòu)造器都會(huì)調(diào)用一個(gè)父類構(gòu)造函數(shù),如果沒(méi)有顯式的聲明,就會(huì)隱含的調(diào)用super(),相當(dāng)于調(diào)用父類的無(wú)參構(gòu)造函數(shù),如果父類沒(méi)有無(wú)參構(gòu)造函數(shù),則會(huì)報(bào)錯(cuò)。
- 如果顯式的使用了super語(yǔ)句,super語(yǔ)句必須是構(gòu)造函數(shù)中第一個(gè)語(yǔ)句。
- 調(diào)用父類的構(gòu)造函數(shù)必須借助super實(shí)現(xiàn),每個(gè)子類構(gòu)造器只能調(diào)用一個(gè)構(gòu)造函數(shù),即在每個(gè)子類構(gòu)造函數(shù)中只能使用一次super。