要講super就不能不提t(yī)his,下面從4個角度講解一下super(需要對比的時候拿this對比一下,加深理解)
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),鹽池企業(yè)網(wǎng)站建設(shè),鹽池品牌網(wǎng)站建設(shè),網(wǎng)站定制,鹽池網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,鹽池網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
1. super關(guān)鍵字表示超(父)類的意思。this變量代表對象本身。
2. super訪問父類被子類隱藏的變量或覆蓋的方法。當前類如果是從超類繼承而來的,當調(diào)用super.XX()就是調(diào)用基類版本的XX()方法。其中超類是最近的父類。
3.調(diào)用super() 父類構(gòu)造函數(shù)的時候只能調(diào)用在子類構(gòu)造函數(shù)的第一行
4.this只能在類中的非靜態(tài)方法中使用,靜態(tài)方法和靜態(tài)的代碼塊中絕對不能出現(xiàn)this。并且this只和特定的對象關(guān)聯(lián),而不和類關(guān)聯(lián),同一個類的不同對象有不同的this
例如:
class Person {
protected void print() {
System.out.println("The print() in class Person.");
}
}
public class DemoSuper extends Person {
public DemoSuper(){
super(); //調(diào)用父類的構(gòu)造方法,而且放第一行,如果不寫,系統(tǒng)自動加
}
public void print() {
System.out.println("The print() in class DemoSuper.");
super.print();// 調(diào)用父類的方法
}
public static void main(String[] args) {
DemoSuper ds = new DemoSuper();
ds.print();
}
}
java中子類繼承父類程序執(zhí)行順序問題
Java中,new一個類的對象,類里面的靜態(tài)代碼塊、非靜態(tài)代碼、無參構(gòu)造方法、有參構(gòu)造方法、類的一般方法等部分,它們的執(zhí)行順序相對來說比較簡單,用程序也很容易驗證。比如新建一個測試父類。
public class FatherTest {
private String name;
FatherTest(){
System.out.println("--父類的無參構(gòu)造函數(shù)--");
}
FatherTest(String name){
this.name=name;
System.out.println("--父類的有參構(gòu)造函數(shù)--"+this.name);
}
static{
System.out.println("--父類的靜態(tài)代碼塊--");
}
{
System.out.println("--父類的非靜態(tài)代碼塊--");
}
public void speak(){
System.out.println("--父類的方法--");
}
}
加入一個main程序后
public static void main(String[] args) {
System.out.println("--父類主程序--");
FatherTest father=new FatherTest("父親的名字");
father.speak();
}
執(zhí)行結(jié)果為:
--父類的靜態(tài)代碼塊--
--父類主程序--
--父類的非靜態(tài)代碼塊--
--父類的有參構(gòu)造函數(shù)--父親的名字
--父類的方法—
可以很明顯的看出來執(zhí)行順序:靜態(tài)代碼塊—主程序—非靜態(tài)代碼塊—構(gòu)造函數(shù)—一般方法。
如果加入子類的繼承以后,情況就會變得復(fù)雜些。比如我們再新建一個測試子類。
public class SonTest extends FatherTest {
private String name;
static{
System.out.println("--子類的靜態(tài)代碼塊--");
}
{
System.out.println("--子類的非靜態(tài)代碼塊--");
}
SonTest(){
System.out.println("--子類的無參構(gòu)造函數(shù)--");
}
SonTest(String name){
this.name=name;
System.out.println("--子類的有參構(gòu)造函數(shù)--"+this.name);
}
@Override
public void speak(){
System.out.println("--子類Override了父類的方法--");
}
}
然后再加入一個main函數(shù)
public static void main(String[] args) {
System.out.println("--子類主程序--");
FatherTest father=new FatherTest("父親的名字");
father.speak();
SonTest son=new SonTest("兒子的名字");
son.speak();
}
執(zhí)行結(jié)果為:
--父類的靜態(tài)代碼塊--
--子類的靜態(tài)代碼塊--
--子類主程序--
--父類的非靜態(tài)代碼塊--
--父類的有參構(gòu)造函數(shù)--父親的名字
--父類的方法--
--父類的非靜態(tài)代碼塊--
--父類的無參構(gòu)造函數(shù)--
--子類的非靜態(tài)代碼塊--
--子類的有參構(gòu)造函數(shù)--兒子的名字
--子類Override了父類的方法--
加入了子類以后,執(zhí)行順序有了新的變化,我們可以總結(jié)一下。首先第一部分執(zhí)行的是父類的靜態(tài)代碼塊—子類的靜態(tài)代碼塊—主程序。這一部分都是執(zhí)行一次,與建立多少對象沒有關(guān)系。第二部分new了一個父類對象,并調(diào)用了方法。執(zhí)行了它的非靜態(tài)代碼塊—構(gòu)造函數(shù)—一般方法。第三部分new了一個子類的對象,并調(diào)用了方法。執(zhí)行順序為父類的非靜態(tài)代碼塊—父類的無參構(gòu)造函數(shù),然后是子類的非靜態(tài)代碼塊—子類構(gòu)造函數(shù)—子類的方法。
關(guān)鍵字super明確顯式地指出一個類可以它父類的構(gòu)造函數(shù)、方法和變量。
關(guān)鍵字super和繼承一起建立類和它的父類的緊密聯(lián)系。繼承隱含地指出子類對父類所擁有的訪問權(quán)限。例如,當我們要調(diào)用一個實例方法時,如果實例本身并沒有定義該方法,那我們自然地會得到它的父類中定義的同名方法。盡管會因為方法的覆蓋或者使用定義與父類一樣的實例或類變量(叫做“隱藏”)而失去這種訪問的權(quán)力。這就是為什么要使用super這個關(guān)鍵字,它顯式地指出子類可以直接訪問父類中的某些部分,盡管有時這種訪問會因為種種原因被屏蔽了的方法在其父類中的原始代碼。
Super在構(gòu)造函數(shù)的使用中是非常重要的,和方法不同,構(gòu)造函數(shù)是不能繼承的;因此super是訪問父類中構(gòu)造函數(shù)的惟一途徑。在子類的構(gòu)造函數(shù)中,使用super(...)和適當?shù)膮?shù)表可以觸發(fā)對父類構(gòu)造函數(shù)的一個調(diào)用,如果父類沒有相應(yīng)的構(gòu)造函數(shù),編譯器會報錯,這就是每個實例實現(xiàn)的初始化的過程鏈。實例先把自己作為一個Object實例進行初始化,然后從它的直接子類開始按照繼承鏈依次調(diào)用構(gòu)造函數(shù)直到最后將與當前類直接相關(guān)的內(nèi)容初始化完畢。
舉例說明:
例一、
class Base...{Base()...{
System.out.println("Base");
}
}
public class Checket extends Base...{ Checket()...{
System.out.println("Checket");
super();
} public static void main(String argv[])...{
Checket c = new Checket();
// super();
}
}
A.Compile time error
B.Checket followed by Base
C.Base followed by Checket
D.runtime error
解析:這是一個考查super構(gòu)造函數(shù)的面試例題。子類的構(gòu)造函數(shù)如果要引用super的話,必須把super放在函數(shù)的首位,不然會出現(xiàn)這樣的報錯:
Checket.java:10: call to super must be first statement in constructor
super();
如果一定要引用super構(gòu)造函數(shù),則必須把super()放在前面,代碼如下。
class Base...{Base()...{
System.out.println("Base");
}}
public class Checket extends Base...{ Checket()...{
super();
System.out.println("Checket");
} public static void main(String argv[])...{
Checket c = new Checket();
// super();
}
}
例二、[]里在類中用super調(diào)用父類構(gòu)造函數(shù)時,為什么調(diào)用語句必須是子類的第一條語句?
答案:如果想用super繼承父類構(gòu)造的方法,但是沒有放在第一行的話,那么在super之前的語句,肯定是為了滿足自己想要完成某些行為的語句,但是又用了super繼承父類的構(gòu)造方法。那么以前所做的修改就都回到以前了,就是說又成了父類的構(gòu)造方法了。如下面的程序所示。
class Father
...{
public Father()
...{String name=null;
int age=0;}
}
class Son extends Father
...{
public Son()
...{String name="學(xué)生";
super();
}
}
擴展知識(Java中的super類)
在Java中, 有時還會遇到子類中的成員變量或方法與超類(有時也稱父類)中的成員變量或方法同名。因為子類中的成員變量或方法名優(yōu)先級高,所以子類中的同名成員變量或 方法就隱藏了超類的成員變量或方法,但是我們?nèi)绻胍褂贸愔械倪@個成員變量或方法,就需要用到super。請看下面的類。
class Country
...{
String name;
void value()
...{
name="China";
}
}
在下面的子類中,子類的成員變量和方法隱藏了超類的成員變量name和方法value()。
class City extends Country
String name;
void value()
...{
name="Hefei";
super.value();
System.out.println(name);
System.out.println(super.name);
}
為了在子類中引用超類中的成員變量name和方法value(),在代碼中使用了super、super.name和super.value(),所以顯示的結(jié)果為:
Hefei
China
如果想要使用超類的構(gòu)造函數(shù),則應(yīng)當使用super(參數(shù)列表)的形式
面試例題3:給定下面的代碼,哪個選項在替代"http://Here"后可以被編譯并且改變變量oak的值?
class Base...{
static int oak=99;
}
public class Doverdale extends Base...{
public static void main(String argv[])...{
Doverdale d = new Doverdale();
d.amethod();
}
public void amethod()...{
//Here
}
}
A.super.oak=1;
B.oak=33;
C.Base.oak=22;
D.oak=50.1;
解析:因為變量oak被聲明是靜態(tài)的,如果它存在只能有一個本體,則它可以通過本類的名字或者通過定義本類的任何一個實例被改變。
答案:A、B、C
面試例題4:當編譯和運行下列代碼時會發(fā)生下列哪種情況?
class Base...{
Base()...{
System.out.println("Base");
}
}
public class Checket extends Base...{
public static void main(String argv[])...{
Checket c = new Checket();
super();
}
Checket()...{
System.out.println("Checket");
}
}
A.Compile time error
B.Checket followed by Base
C.Base followed by Checket
D.runtime error
解析:
用Sun的JDK運行會出現(xiàn)下列出錯信息。
"Only constructors can invoke constructors"
Checket作為一個構(gòu)造方法應(yīng)該在調(diào)用時從最老的祖先類開始向下調(diào)用,調(diào)用super會引起程序在編譯和運行時間上的錯誤。
Java中的關(guān)鍵字super:調(diào)用父類的屬性,一個類中如果有int x屬性,如果其子類中也定義了int x屬性的話,在子類中調(diào)用父類的x屬性時應(yīng)用super.x=6,表示該x是引用的父類的屬性,而要表示子類中的x屬性的話,使用this.x。
this和super:在Java中,this通常指當前對象,super則指父類的對象。若想要引用當前對象的某種東西,比如當前對象的某個方法,或當 前對象的某個成員,便可以利用this來實現(xiàn)這個目的。當然,this的另一個用途是調(diào)用當前對象的另一個構(gòu)造函數(shù)。如果想引用父類的某種東西,則非 super莫屬。
Java里在子類中用super調(diào)用父類構(gòu)造函數(shù)時,調(diào)用函數(shù)必須放在子類的第一條語句的位置,如果想用super繼承父類構(gòu)造的方法,但是沒有放在第一 行的話,那么在super之前的語句,也許是為了滿足自己想要完成某些行為的語句,但是又用了super繼承父類的構(gòu)造方法,以前所做的修改就都回到以前 了,也就是說又成了父類的構(gòu)造方法了。
“-”是Java 8新增的Lambda表達式中,變量和臨時代碼塊的分隔符,即:
(變量)-{代碼塊}
如果代碼塊只有一個表達式,大括號可以省略。如果變量類型可以自動推斷出來,可以不寫變量類型。
本文標題:java代碼塊繼承 java 構(gòu)造代碼塊
標題網(wǎng)址:http://vcdvsql.cn/article28/ddsegcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、營銷型網(wǎng)站建設(shè)、網(wǎng)站排名、全網(wǎng)營銷推廣、域名注冊、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)