全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1877
推到 Plurk!
推到 Facebook!

super 和 this

答題得分者是:neoart
Randgris
一般會員


發表:20
回覆:30
積分:10
註冊:2007-04-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-04-15 19:32:08 IP:122.124.xxx.xxx 訂閱
class A
{
    int a1, a2;
    
    public void setA()
    {
        System.out.println("a1= "   a1   " a2= "   a2);
    }
}
 
class B extends A
{
    int b1, b2;
    
    public void setB(int b3, int b4)
    {
        this.b1 = b3;
        this.b2 = b4;
        
        super.a1 = 5;
        super.a2 = 6;
        
        super.setA();
        
        System.out.println("a1= "   this.a1   " a2= "   this.a2);
    }
}
 
public class SuperandThis {
    
    public SuperandThis() {
    }
    
    public static void main(String[] args) {
        B b = new B();
        b.setA();
        b.setB(1, 2);
    }  
}

在setB函式裡super和this印出來的a1,a2結果一樣

請問是因為

this指向b這物件 那a1 a2 b1 b2 為b物件存在記憶體裡的資料

所以不管用super回祖先那改 跟 this 都是改一樣的東西嗎?

以及class A class B的存取權限到底是什麼呢??

neoart
版主


發表:22
回覆:582
積分:425
註冊:2003-05-09

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-04-15 21:46:22 IP:220.132.xxx.xxx 訂閱
壹:先回答Class A & Class B之間的變數存取關係
如果沒有加什麼修飾字(modifiyer ,如 private,public ,protected) 的話,是package的範圍,
也就是,如 ClassB是在ClassA所在的package以外宣告的話,是不可以存取你此例中的 super.a1,super.a2 ...
(因此例你只放在同一個package中,所以觀察不出來,如果你把Class B放在不同的package中宣告,compile看看會有什麼訊息吧.)

貳: 繼承,就是擴充父類別的記憶空間加上自己本身類別的一些變數及方法(如果是方法繼承的話.會加一個vtable去做function 對映,這點你目前不知道無要緊)
但是,不同的個體/實體( Instance) ,就是不同的資料空間了(但是函數空間還是一樣,差別只是在呼叫時,會把this指標傳進去,才不會找錯資料)
ex :
B B1=new B();
B B2=new B();
B1.setB(1, 2);
B2.setB(4,5);
試看看,B1與B2的 b1 & b2 資料會一樣嗎? (a1 & a2 會是一直一樣的,因為你在set中又指定 a1 & a2值了)
-----------------------------希望這是你要的答案--------------------------
Randgris
一般會員


發表:20
回覆:30
積分:10
註冊:2007-04-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-04-16 19:25:29 IP:122.124.xxx.xxx 訂閱
請問package權限 跟 class前面再加一個default有何不同呢?

以及問題二 b這物件 擁有 a1 a2 b1 b2 這四個變數所屬記憶體空間

那因為a1 a2是繼承而來的 所以使用this.a1 跟 使用 super.a1是一樣的嗎?

===================引 用 neoart 文 章===================
壹:先回答Class A & Class B之間的變數存取關係
如果沒有加什麼修飾字(modifiyer ,如 private,public ,protected) 的話,是package的範圍,
也就是,如 ClassB是在ClassA所在的package以外宣告的話,是不可以存取你此例中的 super.a1,super.a2 ...
(因此例你只放在同一個package中,所以觀察不出來,如果你把Class B放在不同的package中宣告,compile看看會有什麼訊息吧.)

貳: 繼承,就是擴充父類別的記憶空間加上自己本身類別的一些變數及方法(如果是方法繼承的話.會加一個vtable去做function 對映,這點你目前不知道無要緊)
但是,不同的個體/實體( Instance) ,就是不同的資料空間了(但是函數空間還是一樣,差別只是在呼叫時,會把this指標傳進去,才不會找錯資料)
?ex :
B? B1=new B();
B? B2=new B();
??? B1.setB(1, 2);
??? B2.setB(4,5);
試看看,B1與B2的 b1 & b2 資料會一樣嗎? (a1 & a2 會是一直一樣的,因為你在set中又指定 a1 & a2值了)
-----------------------------希望這是你要的答案--------------------------
neoart
版主


發表:22
回覆:582
積分:425
註冊:2003-05-09

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-04-16 23:50:46 IP:220.132.xxx.xxx 訂閱
A1 :
"加個default ..." ? 不解,(還是這是jdk1.5的語法?)
我想你可能沒有玩過package,現在老身為你示範
在資料夾package_a,放兩個java檔,叫做 Class A,Class C
宣告
--------------A.java ------------
package package_a
Class A {
int a1,a2;
}

--------------C.java ------------
package package_a
Class C {
int c1,c2;
A thisIsAnA=new A();
public initA(int x,int y){
thisIsAnA.a1=x;
thisIsAnA.a2=y;
}
}

-------------------------------------
因為 A & C同屬同一個package中,故C類別中的 initA可以直接存取A的資料成員
又,在package_b中,定義一個B類別
package package_b
Class B extends A {
public initA(int x,int y){
super.a1=x;
super.a2=y;
}
}
-----------因為 ClassB是在另一個package中,就算是繼承,也不可以存取,所以你的initA函數在compile是會過不去----
怎麼解決?就是在Class A的a1 & a2 兩變數宣告為protected
ex : protected int a1;
protected int a2;
....
就可以給在不同的package中的子類別存取了

A2: 不是,我說錯了.
不過這很容易混淆,這不是好的coding style
===========================================
class TestA{
protected int a;
protected int b;
TestA(){
a=10;
b=20;
}
}
class TestB extends TestA{
protected int a;
protected int b;
TestB(){
a=30;
b=40;
System.out.println("a=" a ",b=" b " super.a=" super.a ",super.b=" super.b);
}
}
==============================================================
你呼叫了 TestB bxx=new TestB();
就可以看出 TestB::a & TestB::b 與 TestA::a & TestA::b
是不同的值...不過對後來接手你的case的人,很容易混淆
在codding時,別忘了,你是一時的,而你的code & class是永久的,要為後人設想一下

=============有時我懶的猜,就會直接寫,交給compiler去踹====================
Randgris
一般會員


發表:20
回覆:30
積分:10
註冊:2007-04-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-04-17 19:20:16 IP:122.124.xxx.xxx 訂閱
我的意思是指 a1 a2假設是由B繼承A而來的

那 B 用 super.a1去更改 跟 用 this.a1是一樣的嗎 ^^?
neoart
版主


發表:22
回覆:582
積分:425
註冊:2003-05-09

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-04-17 20:03:48 IP:220.132.xxx.xxx 訂閱
System.out.println("a="+a+",b="+b+" super.a="+super.a+",super.b="+super.b);
等同於
System.out.println("a=" this.a ",b=" this.b " super.a=" super.a ",super.b=" super.b);
this 是目前類別所在的空間
super是父類別所在的空間
Randgris
一般會員


發表:20
回覆:30
積分:10
註冊:2007-04-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-04-17 22:53:20 IP:122.124.xxx.xxx 訂閱
neoart大大 感謝你幫忙提供了這麼多意見 偶應該都懂哩^﹍^

以後還有問題 還要請你多多幫忙呀...
系統時間:2024-05-05 20:27:23
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!