從屌絲到架構(gòu)師的飛越(面向?qū)ο笃?繼承中的構(gòu)造方法

一偿短、介紹

在繼承中欣孤,我們子類繼承了父類,并沒(méi)有繼承他的構(gòu)造方法昔逗,所以我們要了解的是子類與父類的構(gòu)造方法的處理降传。

二、知識(shí)點(diǎn)介紹

1纤子、繼承關(guān)系內(nèi)存解釋

2搬瑰、父類對(duì)象優(yōu)于子類對(duì)象產(chǎn)生

3、super關(guān)鍵字

4控硼、this關(guān)鍵字

5泽论、super與this比較

6、對(duì)多態(tài)向上向下轉(zhuǎn)型的內(nèi)存解釋

三卡乾、上課視頻對(duì)應(yīng)說(shuō)明文檔

1翼悴、繼承關(guān)系內(nèi)存解釋

實(shí)際上在面向?qū)ο蟮谝惶斓闹v解當(dāng)中,我們對(duì)內(nèi)存方面做了一些隱瞞幔妨。因?yàn)槌薕bject類鹦赎,所有的類都是有父類的。但是我們?cè)诳紤]內(nèi)存圖時(shí)忽略了這點(diǎn)误堡,現(xiàn)在古话,我們來(lái)簡(jiǎn)單描述加入了子父類關(guān)系后的對(duì)象內(nèi)存圖。

以Person類為例:

//定義父類

public class Person {

private String name;

private int age;

public Person(){}

public Person(String name,int age) {

this.name = name;

this.age = age;

}

//get/set方法

}

//定義子類

public class Chinese extends Person{

private Stirng address;

public Chinese(){}

public Chinese(String name,int age,String address) {

super(name,age);

this.address = address;

}

//對(duì)address的get/set

}

//定義測(cè)試類,使用子類創(chuàng)建對(duì)象

public class Test{

Chinese c = new Chinese(“AngelaBaby”,18,”北京海淀區(qū)上地7街晉福公寓”);

}

對(duì)象內(nèi)存圖

代碼示例:

/*

* 自定義類型Person 類

*

* name? age

*

* 吃? 睡

*/

public abstract class Person {

private String name;

int age;

//定義無(wú)參構(gòu)造方法

public Person(){

//方法邏輯

System.out.println("我是Person的無(wú)參構(gòu)造");

}

//定義帶參構(gòu)造一般都是為了給成員變量賦值

public Person(String name ,int age){

System.out.println("我是Person帶參構(gòu)造給成員變量賦值");

this.name = name;

this.age = age;

}

private void eat(){

System.out.println("吃");

}

public void sleep(){

System.out.println("睡");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

/*

* 自定義Studnet繼承Person類

*/

public class Student extends Person{

private String number;

/*

* 無(wú)參構(gòu)造

*/

public Student() {

System.out.println("Studnet的無(wú)參構(gòu)造");

}

//帶參構(gòu)造

public Student(String number,String name,int age) {

System.out.println("Studnet的帶參構(gòu)造");

this.number = number;

}

public String getNumber() {

return number;

}

public void setNumber(String number) {

this.number = number;

}

}

/*

* 測(cè)試有繼承關(guān)系的構(gòu)造方法

*/

public class Test {

public static void main(String[] args) {

//Student s = new Student();

Student s2 = new Student("2016");

}

}?

2锁施、父類對(duì)象優(yōu)于子類對(duì)象產(chǎn)生

在每次創(chuàng)建子類對(duì)象時(shí)陪踩,我們均會(huì)先創(chuàng)建父類對(duì)象杖们,再創(chuàng)建其子類對(duì)象本身。目的在于子類對(duì)象中包含了其對(duì)應(yīng)的父類對(duì)象肩狂,便可以包含其父類對(duì)象的成員摘完,如果父類成員非private修飾,則子類可以隨意使用父類成員傻谁。

反之孝治,如果沒(méi)有先創(chuàng)建父類對(duì)象就使用了子類對(duì)象,則子類無(wú)法使用父類的成員审磁。抽象類包含構(gòu)造方法的原因就在于其僅僅是為了給成員變量賦值谈飒,供子類使用。

這里我們需要注意的是力图,內(nèi)存當(dāng)中實(shí)際是存在抽象類的對(duì)象空間的步绸,我們無(wú)法直接創(chuàng)建抽象類對(duì)象,但是子類可以吃媒,在子類的內(nèi)存空間中包括了這個(gè)抽象父類對(duì)象瓤介。

3、super關(guān)鍵字

3.1赘那、super關(guān)鍵字概念

super代表本類對(duì)象中包含的父類對(duì)象空間的引用刑桑。

當(dāng)有了繼承關(guān)系后,創(chuàng)建一個(gè)子類對(duì)象時(shí)募舟,會(huì)先在子類中創(chuàng)建其父類對(duì)象祠斧,則子類對(duì)象包含了父類的所有方法與屬性,而其非私有的方法一般都可以訪問(wèn) (在完成訪問(wèn)權(quán)限的學(xué)習(xí)后拱礁,會(huì)有進(jìn)一步認(rèn)識(shí)) 琢锋。

3.2、super訪問(wèn)普通成員

在子類的任意位置呢灶,均可以使用super.屬性名或者super.方法名()的方式訪問(wèn)父類空間的非私有成員吴超。

代碼示例:

/*

* 自定義類型Person 類

*

* name? age

*

* 吃? 睡

*/

public abstract class Person {

private String name;

int age;

//定義無(wú)參構(gòu)造方法

public Person(){

//方法邏輯

System.out.println("我是Person的無(wú)參構(gòu)造");

}

//定義帶參構(gòu)造一般都是為了給成員變量賦值

public Person(String name ,int age){

System.out.println("我是Person帶參構(gòu)造給成員變量賦值");

this.name = name;

this.age = age;

}

private void eat(){

System.out.println("吃");

}

public void sleep(){

System.out.println("睡");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

/*

* 自定義Studnet繼承Person類

*

* super訪問(wèn)父類構(gòu)造方法

*? 在子類的所有構(gòu)造方法的第一行 都默認(rèn)調(diào)用了父類的無(wú)參構(gòu)造? super()?

*? 我們通過(guò)super(參數(shù))調(diào)用父類的帶參構(gòu)造 給父類的成員變量賦值

* super訪問(wèn)普通成員

*? 在子類的任意位置,均可以使用super.屬性名或者super.方法名()的方式訪問(wèn)父類空間的非私有成員鸯乃。

*

*/

public class Student extends Person{

private String number;

/*

* 無(wú)參構(gòu)造

*/

public Student() {

super();

System.out.println("Studnet的無(wú)參構(gòu)造");

}

//帶參構(gòu)造

public Student(String number,String name,int age) {

super(name,age);

System.out.println("Studnet的帶參構(gòu)造");

this.number = number;

}

public void method(){

//super.屬性名可以訪問(wèn)父類的非私有成員變量

//System.out.println(super.name);

System.out.println(super.age);

//super.方法名()可以訪問(wèn)父類的非私有成員方法

//? super.eat();

super.sleep();

}

public String getNumber() {

return number;

}

public void setNumber(String number) {

this.number = number;

}

}

/*

* 測(cè)試有繼承關(guān)系的構(gòu)造方法

*/

public class Test {

public static void main(String[] args) {

//? Student s = new Student();

Student s2 = new Student("2016","柳巖",38);

System.out.println(s2.getNumber());

System.out.println(s2.getName());

System.out.println(s2.getAge());

}

}

3.3鲸阻、super調(diào)用父類構(gòu)造方法

在子類的每個(gè)構(gòu)造方法中,第一行具有默認(rèn)調(diào)用父類空參構(gòu)造代碼缨睡,即super().所以在每次創(chuàng)建子類對(duì)象時(shí)鸟悴,會(huì)先創(chuàng)建父類的構(gòu)造。

使用super(參數(shù))可以訪問(wèn)父類任意參數(shù)的構(gòu)造奖年,當(dāng)手動(dòng)調(diào)用父類任意的構(gòu)造方法后细诸,Java將不再提供默認(rèn)調(diào)用父類空參的構(gòu)造方法。

/*

* 自定義類型Person 類

*

* name? age

*

* 吃? 睡

*/

public abstract class Person {

private String name;

Private int age;

//定義無(wú)參構(gòu)造方法

public Person(){

//方法邏輯

System.out.println("我是Person的無(wú)參構(gòu)造");

}

//定義帶參構(gòu)造一般都是為了給成員變量賦值

public Person(String name ,int age){

System.out.println("我是Person帶參構(gòu)造給成員變量賦值");

this.name = name;

this.age = age;

}

Public void eat(){

System.out.println("吃");

}

public void sleep(){

System.out.println("睡");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

/*

* 自定義Studnet繼承Person類

*

* super訪問(wèn)父類構(gòu)造方法

*? 在子類的所有構(gòu)造方法的第一行 都默認(rèn)調(diào)用了父類的無(wú)參構(gòu)造? super()?

*? 我們通過(guò)super(參數(shù))調(diào)用父類的帶參構(gòu)造 給父類的成員變量賦值

* super訪問(wèn)普通成員

*? 在子類的任意位置陋守,均可以使用super.屬性名或者super.方法名()的方式訪問(wèn)父類空間的非私有成員震贵。

*

*/

public class Student extends Person{

private String number;

/*

* 無(wú)參構(gòu)造

*/

public Student() {

super();

System.out.println("Studnet的無(wú)參構(gòu)造");

}

//帶參構(gòu)造

public Student(String number,String name,int age) {

super(name,age);

System.out.println("Studnet的帶參構(gòu)造");

this.number = number;

}

public String getNumber() {

return number;

}

public void setNumber(String number) {

this.number = number;

}

}

/*

* 測(cè)試有繼承關(guān)系的構(gòu)造方法

*/

public class Test {

public static void main(String[] args) {

//? Student s = new Student();

Student s2 = new Student("2016","柳巖",38);

System.out.println(s2.getNumber());

System.out.println(s2.getName());

System.out.println(s2.getAge());

}

}

4鹏浅、this關(guān)鍵字

4.1、this關(guān)鍵字概念回顧

this代表本類一個(gè)對(duì)象的引用屏歹,當(dāng)創(chuàng)建了一個(gè)子類對(duì)象時(shí),子類自己的空間可以使用this訪問(wèn)到之碗。

4.2蝙眶、this調(diào)用普通成員

在子類的任意位置,均可以使用this.屬性名或者this.方法名()的方式訪問(wèn)子類自身空間的成員褪那。

4.3幽纷、this調(diào)用本類其他構(gòu)造

使用this(參數(shù))可以訪問(wèn)子類任意其他參數(shù)的構(gòu)造方法,當(dāng)手動(dòng)調(diào)用子類任意的構(gòu)造方法后博敬,Java將不再提供默認(rèn)調(diào)用父類空參的構(gòu)造方法友浸。

this調(diào)用構(gòu)造方法與super調(diào)用構(gòu)造方法不能同時(shí)出現(xiàn)。

無(wú)論以哪種方式完成構(gòu)造方法的定義偏窝,均會(huì)先創(chuàng)建父類對(duì)象收恢,再創(chuàng)建子類對(duì)象。

package cn.javahelp3;

/*

* 自定義類型Person 類

*

* name? age

*

* 吃? 睡

*/

public abstract class Person {

private String name;

int age;

//定義無(wú)參構(gòu)造方法

public Person(){

//方法邏輯

System.out.println("我是Person的無(wú)參構(gòu)造");

}

//定義帶參構(gòu)造一般都是為了給成員變量賦值

public Person(String name ,int age){

System.out.println("我是Person帶參構(gòu)造給成員變量賦值");

this.name = name;

this.age = age;

}

private void eat(){

System.out.println("吃");

}

public void sleep(){

System.out.println("睡");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

package cn.javahelp3;

/*

* 自定義教師

*

* this

*

* this調(diào)用本類其他構(gòu)造

*? this(參數(shù))可以調(diào)用本來(lái)當(dāng)中其他構(gòu)造方法

*

* this訪問(wèn)本來(lái)的普通成員

*? 在子類的任意位置祭往,均可以使用this.屬性名或者this.方法名()的方式訪問(wèn)子類自身空間的成員伦意。

*

*/

public class Teacher extends Person{

//id

private String id;

public Teacher() {

//this(參數(shù))可以調(diào)用本來(lái)當(dāng)中其他構(gòu)造方法

this("90213");

}

public Teacher(String name, int age,String id) {

super(name, age);

this.id = id;

}

public Teacher(String id){

super();

this.id = id;

}

public void method(){

//在子類的任意位置,均可以使用this.屬性名或者this.方法名()的方式訪問(wèn)子類自身空間的成員硼补。

System.err.println(this.id);

this.teach();

}

public void teach(){

System.out.println("教學(xué)生的方法");

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

}

5驮肉、this與super的使用對(duì)比及注意事項(xiàng)

(1)訪問(wèn)子類區(qū)域的成員使用this,訪問(wèn)父類區(qū)域的成員使用super已骇。

this:

(2)訪問(wèn)本類對(duì)象成員變量:this.變量名

(3)調(diào)用本類普通方法:this.方法名(參數(shù))

(4)本類構(gòu)造方法調(diào)用本類其他構(gòu)造:本類構(gòu)造方法第一行this(參數(shù))

super:

(5)訪問(wèn)本類對(duì)象當(dāng)中的父類對(duì)象成員變量:super.變量名

(6)調(diào)用本類對(duì)象當(dāng)中的父類普通方法:super.方法名()

(7)本類構(gòu)造方法調(diào)用父類構(gòu)造:本類構(gòu)造方法第一行super(參數(shù))

變量訪問(wèn)的就近原則:

(8)當(dāng)多個(gè)位置出現(xiàn)相同名稱的變量時(shí)离钝,訪問(wèn)時(shí)會(huì)根據(jù)就近原則依次訪問(wèn)其先后順序?yàn)椋?/p>

局部位置>本類成員位置>父類成員位置 >父類的父類成員位置 …

package cn.javahelp4;

/*

* 變量的就近訪問(wèn)原則

*/

public class Fu {

String name = "父類名字";

}

package cn.javahelp4;

public class Zi extends Fu {

String name = "子類名字";

public void method(){

String name = "局部名字";

System.out.println(name);

System.out.println(this.name);

System.out.println(super.name);

}

}

package cn.javahelp4;

/*

* 當(dāng)多個(gè)位置出現(xiàn)相同名稱的變量時(shí),訪問(wèn)時(shí)會(huì)根據(jù)就近原則依次訪問(wèn)褪储。其先后順序?yàn)椋?/p>

局部位置 >? 本類成員位置 >? 父類成員位置? >? 父類的父類成員位置? …

*/

public class Test {

public static void main(String[] args) {

Zi zi = new Zi();

zi.method();

}

}

注意:

this與super在調(diào)用構(gòu)造方法時(shí)卵渴,均必須在第一行,只能調(diào)用其中的一個(gè)乱豆。

父類多個(gè)構(gòu)造奖恰,子類調(diào)用父類某個(gè)參數(shù)的構(gòu)造時(shí),必須保證父類有這個(gè)構(gòu)造宛裕,否則報(bào)錯(cuò)瑟啃。

package cn.javahelp5;

/*

* 自定義Person類

*

*? name age

*/

public class Person {

private String name;

private int age;

public Person(){

}

public Person(String name, int age) {

super();

this.name = name;

this.age = age;

}

public Person(int age){

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

package cn.javahelp5;

/*

* 學(xué)生類

*

*this與super在調(diào)用構(gòu)造方法時(shí),均必須在第一行揩尸,只能調(diào)用其中的一個(gè)蛹屿。

* 父類多個(gè)構(gòu)造,子類調(diào)用父類某個(gè)參數(shù)的構(gòu)造時(shí)岩榆,必須保證父類有這個(gè)構(gòu)造错负,否則報(bào)錯(cuò)坟瓢。

*/

public class Student extends Person{

public Student() {

super();

}

public Student(String name, int age) {

super(name, age);

}

public Student(int age){

super(age);

}

}

6、對(duì)多態(tài)向上向下轉(zhuǎn)型的內(nèi)存解釋

向上轉(zhuǎn)型:

如圖所示犹撒,當(dāng)出現(xiàn)多態(tài)時(shí)折联,引用為Person類型,對(duì)象為Chinese對(duì)象识颊,此時(shí)诚镰,由于Chinese中包含了父類所有成員,所以可以訪問(wèn)父類非私有的一切祥款。對(duì)外表現(xiàn)的就”像個(gè)父類對(duì)象一樣”清笨。僅僅在調(diào)用方法時(shí),會(huì)調(diào)用子類重寫后的方法刃跛。

向下轉(zhuǎn)型:

當(dāng)出現(xiàn)多態(tài)后抠艾,父類Person引用指向子類對(duì)象,當(dāng)強(qiáng)轉(zhuǎn)為子類引用時(shí)桨昙,由于堆內(nèi)存當(dāng)中存儲(chǔ)的仍為子類對(duì)象检号,包含子類的一切成員。所以可以轉(zhuǎn)型成功绊率。

但是谨敛,如果沒(méi)有出現(xiàn)多態(tài),僅僅創(chuàng)建父類對(duì)象(如果父類不是抽象類的話)滤否,則為? ? 父類Person的引用指向Person的對(duì)象脸狸,沒(méi)有子類的對(duì)象。此時(shí)如果強(qiáng)轉(zhuǎn)為子類對(duì)象藐俺,則不包含子類的一些屬性與功能炊甲,所以強(qiáng)轉(zhuǎn)失敗。

思考:

當(dāng)子父類中有相同名稱的成員變量時(shí)欲芹,強(qiáng)轉(zhuǎn)前與強(qiáng)轉(zhuǎn)后訪問(wèn)的是相同的屬性值么卿啡?

代碼示例:

/*

* 變量的就近訪問(wèn)原則

*/

public class Fu {

String name = "父類名字";

}

package cn.javahelp4;

public class Zi extends Fu {

String name = "子類名字";

public void method(){

String name = "局部名字";

System.out.println(name);

System.out.println(this.name);

System.out.println(super.name);

}

}

public class Test1 {

public static void main(String[] args) {

Fu fu = new Zi();

System.out.println(fu.name);

Zi zi = (Zi)fu;

System.out.println(zi.name);

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市菱父,隨后出現(xiàn)的幾起案子颈娜,更是在濱河造成了極大的恐慌,老刑警劉巖浙宜,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件官辽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡粟瞬,警方通過(guò)查閱死者的電腦和手機(jī)同仆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)裙品,“玉大人俗批,你說(shuō)我怎么就攤上這事俗或。” “怎么了岁忘?”我有些...
    開(kāi)封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵辛慰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我干像,道長(zhǎng)昆雀,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任蝠筑,我火速辦了婚禮,結(jié)果婚禮上揩懒,老公的妹妹穿的比我還像新娘暗甥。我一直安慰自己惜颇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著殖属,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铅乡。 梳的紋絲不亂的頭發(fā)上宏怔,一...
    開(kāi)封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音阔蛉,去河邊找鬼弃舒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛状原,可吹牛的內(nèi)容都是我干的聋呢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼颠区,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼削锰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起毕莱,我...
    開(kāi)封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤器贩,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后朋截,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蛹稍,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年质和,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稳摄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饲宿,死狀恐怖厦酬,靈堂內(nèi)的尸體忽然破棺而出胆描,到底是詐尸還是另有隱情,我是刑警寧澤仗阅,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布昌讲,位于F島的核電站,受9級(jí)特大地震影響减噪,放射性物質(zhì)發(fā)生泄漏短绸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一筹裕、第九天 我趴在偏房一處隱蔽的房頂上張望醋闭。 院中可真熱鬧,春花似錦朝卒、人聲如沸证逻。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)囚企。三九已至,卻和暖如春瑞眼,著一層夾襖步出監(jiān)牢的瞬間龙宏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工伤疙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留银酗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓徒像,卻偏偏與公主長(zhǎng)得像花吟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子厨姚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容