第三次学JAVA再学不好就吃翔(part31)--super关键字
學習筆記,僅供參考
文章目錄
- 面向?qū)ο?/li>
- 繼承
- 繼承中成員變量的關(guān)系
- this和super的區(qū)別
- 繼承中構(gòu)造方法的關(guān)系
- 繼承中構(gòu)造方法的注意事項
- 繼承中的成員方法關(guān)系
面向?qū)ο?/h2>
繼承
繼承中成員變量的關(guān)系
我們看下面這段代碼,猜測一下輸出內(nèi)容是啥:
class ExtendsTest2 {public static void main(String[] args) {Son s = new Son();s.print();} }class Father {int num1 = 10;int num2 = 30; }class Son extends Father {int num2 = 20;public void print() {System.out.println(num1);System.out.println(num2);} }輸出:
10 20可以看到,根據(jù)就近原則,print()方法里的num2代表的是子類的成員變量,而不是父類的成員變量。
那么我們怎樣才能在print()方法中輸出父類的成員變量呢?
下面我們介紹來一下關(guān)鍵字super。
this和super的區(qū)別
- this和super都代表什么
- this: 代表當前對象的引用,誰來調(diào)用我,我就代表誰
- super: 代表當前對象父類的引用
- this和super的使用區(qū)別
- 調(diào)用成員變量
- this.成員變量 調(diào)用本類的成員變量,也可以調(diào)用父類的成員變量
- super.成員變量 調(diào)用父類的成員變量
- 調(diào)用構(gòu)造方法
- this(…) 調(diào)用本類的構(gòu)造方法
- super(…) 調(diào)用父類的構(gòu)造方法
- 調(diào)用成員方法
- this.成員方法 調(diào)用本類的成員方法,也可以調(diào)用父類的方法
- super.成員方法 調(diào)用父類的成員方法
- 調(diào)用成員變量
- 舉個例子
輸出:
10 20 30繼承中構(gòu)造方法的關(guān)系
子類中所有的構(gòu)造方法默認都會訪問父類中空參數(shù)的構(gòu)造方法,因為子類會繼承父類中的數(shù)據(jù),可能還會使用父類的數(shù)據(jù)。所以,子類初始化之前,一定要先完成父類數(shù)據(jù)的初始化。
- 舉個例子
輸出:
Father 的構(gòu)造方法 Son 的構(gòu)造方法我們看到,當我們創(chuàng)建Son類的對象時,它不僅會調(diào)用本類的空參構(gòu)造方法,而且會自動調(diào)用父類的空參構(gòu)造方法,且JAVA先執(zhí)行父類的構(gòu)造方法,再執(zhí)行子類的構(gòu)造方法。
對于每一個類來說,在初始化本類之前,都會先初始化父類。
那么Father類的父類是誰呢?
是Object類。Object類是最頂層的類,對于所有類來說,Object類直接或間接的是它們的父類,如果一個類沒有人為的繼承任何其他類,那么它的直接父類就是Object類。
上面的代碼也可以寫成:
class Demo5_Extends {public static void main(String[] args) {Son s = new Son();} }class Father extends Object { //public Father() {super();System.out.println("Father 的構(gòu)造方法");} }class Son extends Father {public Son() {super(); //先執(zhí)行父類的構(gòu)造方法,再執(zhí)行子類的構(gòu)造方法System.out.println("Son 的構(gòu)造方法");} }輸出:
Father 的構(gòu)造方法 Son 的構(gòu)造方法繼承中構(gòu)造方法的注意事項
- 父類中沒有無參構(gòu)造方法,子類該怎么辦?
我們首先看一段代碼:
class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();System.out.println("--------");Son s2 = new Son("Huang", 9);} }class Father {String name;int age;public Father() {System.out.println("Father空參構(gòu)造方法");}public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有參構(gòu)造方法," + name + ":" + age);} }class Son extends Father {public Son() {System.out.println("Son空參構(gòu)造方法");}public Son(String name, int age) {this.name = name;this.age = age;System.out.println("Son有參構(gòu)造方法," + name + ":" + age);} }輸出:
Father空參構(gòu)造方法 Son空參構(gòu)造方法 -------- Father空參構(gòu)造方法 Son有參構(gòu)造方法,Huang:9我們看到,不管我們走Son的空參還是有參構(gòu)造方法,都會執(zhí)行Father的空參構(gòu)造方法。
那么如果父類中沒有空參構(gòu)造方法,會發(fā)生什么事情呢?
我們把上面代碼中Father類的空參構(gòu)造去掉:
class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();System.out.println("--------");Son s2 = new Son("Huang", 9);} }class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有參構(gòu)造方法," + name + ":" + age);} }class Son extends Father {public Son() {System.out.println("Son空參構(gòu)造方法");}public Son(String name, int age) {this.name = name;this.age = age;System.out.println("Son有參構(gòu)造方法," + name + ":" + age);} }報錯:
---------- javac ---------- Demo5_Extends.java:23: 錯誤: 無法將類 Father中的構(gòu)造器 Father應用到給定類型;public Son() {^需要: String,int找到: 沒有參數(shù)原因: 實際參數(shù)列表和形式參數(shù)列表長度不同 Demo5_Extends.java:27: 錯誤: 無法將類 Father中的構(gòu)造器 Father應用到給定類型;public Son(String name, int age) {^需要: String,int找到: 沒有參數(shù)原因: 實際參數(shù)列表和形式參數(shù)列表長度不同 2 個錯誤Output completed (4 sec consumed) - Normal Termination可以看到,報錯了!這是因為我們的父類中只有有參構(gòu)造方法,沒有空參構(gòu)造方法,而這段代碼中,Son的構(gòu)造方法調(diào)用的是父類的空參構(gòu)造方法。
那現(xiàn)在該咋整呢?
- 通過super解決
首先改Son的有參構(gòu)造:
class Demo5_Extends {public static void main(String[] args) {//Son s1 = new Son();//System.out.println("--------");Son s2 = new Son("Huang", 9);} }class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有參構(gòu)造方法," + name + ":" + age);} }class Son extends Father {public Son(String name, int age) {super(name, age);this.name = name;this.age = age;System.out.println("Son有參構(gòu)造方法," + name + ":" + age);} }輸出:
Father有參構(gòu)造方法,Huang:9 Son有參構(gòu)造方法,Huang:9很好,沒有報錯!
再改Son的空參構(gòu)造:
class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();//System.out.println("--------");//Son s2 = new Son("Huang", 9);} }class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有參構(gòu)造方法," + name + ":" + age);} }class Son extends Father {public Son() {super("Bai", 10);System.out.println("Son空參構(gòu)造方法");} }輸出:
Father有參構(gòu)造方法,Bai:10 Son空參構(gòu)造方法可以看到,這樣改代碼雖然沒有報錯,但是我們在空參構(gòu)造時,就把name和age定死了。
- 利用this解決
我們看下面這段代碼:
class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();System.out.println("--------");Son s2 = new Son("Huang", 9);} }class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有參構(gòu)造方法," + name + ":" + age);} }class Son extends Father {public Son() {this("Bai", 10); //本類的構(gòu)造方法System.out.println("Son空參構(gòu)造方法");}public Son(String name, int age) {super(name, age); //父類的構(gòu)造方法this.name = name;this.age = age;System.out.println("Son有參構(gòu)造方法," + name + ":" + age);}}輸出:
Father有參構(gòu)造方法,Bai:10 Son有參構(gòu)造方法,Bai:10 Son空參構(gòu)造方法 -------- Father有參構(gòu)造方法,Huang:9 Son有參構(gòu)造方法,Huang:9我們可以通過在Son的空參構(gòu)造方法中設(shè)置this("Bai", 10);指向Son的有參構(gòu)造,來解決父類中沒有空參構(gòu)造的問題。
同時,我們需要注意的是,super()和this()都必須是構(gòu)造器中的第一條語句,所以如果我們想使用,就只能使用super()和this()中的一個。
比如,如果我們同時使用super()和this()則會報錯:
class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();//System.out.println("--------");//Son s2 = new Son("Huang", 9);} }class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有參構(gòu)造方法," + name + ":" + age);} }class Son extends Father {public Son() {super("Tim", 6);this("Bai", 10);System.out.println("Son空參構(gòu)造方法");}public Son(String name, int age) {super(name, age);this.name = name;this.age = age;System.out.println("Son有參構(gòu)造方法," + name + ":" + age);}}報錯:
---------- javac ---------- Demo5_Extends.java:25: 錯誤: 對this的調(diào)用必須是構(gòu)造器中的第一個語句this("Bai", 10);^ 1 個錯誤Output completed (2 sec consumed) - Normal Termination繼承中的成員方法關(guān)系
當父類中存在子類沒有的方法,而我們通過子類的對象去調(diào)用該方法時,會執(zhí)行父類的方法:
class Demo7_Extends {public static void main(String[] args) {Son s = new Son();s.print();s.method();} }class Father {public void print() {System.out.println("Father print");} }class Son extends Father {public void method() {System.out.println("Son Method");}}輸出:
Father print Son Method但當子類有與父類重名的方法時,我們再通過子類的對象去調(diào)用該方法時,就會執(zhí)行子類的方法:
class Demo7_Extends {public static void main(String[] args) {Son s = new Son();s.print();s.method();} }class Father {public void print() {System.out.println("Father print");} }class Son extends Father {public void method() {System.out.println("Son Method");}public void print() {System.out.println("Son print");}}輸出:
Son print Son Method那如果在子類有與父類重名的方法時,我想調(diào)用父類的方法,該咋整呢?
我們可以用super.方法名()去調(diào)用:
class Demo7_Extends {public static void main(String[] args) {Son s = new Son();s.print();s.method();} }class Father {public void print() {System.out.println("Father print");} }class Son extends Father {public void method() {System.out.println("Son Method");}public void print() {super.print();}}輸出:
Father print Son Method總結(jié)
以上是生活随笔為你收集整理的第三次学JAVA再学不好就吃翔(part31)--super关键字的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《答安福乡进士周君得之所问八条后赋此》作
- 下一篇: 第三次学JAVA再学不好就吃翔(part