JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java 新手區 » Object/物件導向  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 給新手 - 抽象函式、抽象類別 [精華]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-08 20:44 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
這篇教學可以說明一些抽象類別與抽象函式的觀念與應用。

函式、方法等名詞我經常混用,這是中文或翻譯名詞表現的問題,無法像英文method、function等一樣的明確,如果不習慣的,可以自行將這些名詞轉換過來。

這些文章中的觀念較為複雜,也有一些討論的空間,如果有謬誤,請多多指定,以利我進行修改,以免誤導新手

=========================================================================

在談抽象類別之前,我們必須先知道,一個基底類別的物件參考,可以用來指向其衍生類別物件而不會發生錯誤,例如若基底類別是foo1,而衍生類別是foo2,則下面這個指定是可以接受的:
1
2
3
foo1 fref;
foo2 f2 = new foo2();
fref = f2;


然而由於fref仍是foo1類型的參考,它只能存取foo1中有定義而繼承至foo2的成員,它並不認得foo2中新定義的成員。

注意將衍生類別型態的參考指向基底類別的物件基本是不可行的,雖然可以使用型態轉換的方式來勉強通過編譯器的檢查,但執行時會發生ClassCastException例外。

當一個基底類別型態的參考指向一個衍生類別物件,我們就可以使用這個參考來存取衍生類別中的函式,下面這個例子是個簡單的示範:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class foo1 {
    public void showMsg() {
        System.out.println("foo1's showMsg()");
    }
}
 
class foo2 extends foo1 {
    public void showMsg() {
        System.out.println("foo2's showMsg()");
    }
}
 
public class Polymorphism {
    public static void main(String[] args) {
        foo1 fref;
        foo1 f1 = new foo1();
        foo2 f2 = new foo2();
 
        fref = f1;
        fref.showMsg();
 
        fref = f2;
        fref.showMsg();
 
        System.out.println();
 
        f1.showMsg();
        f2.showMsg();
    }
}


執行結果:
1
2
3
4
5
6
$ java Polymorphism
foo1's showMsg()
foo2's showMsg()
 
foo1's showMsg()
foo2's showMsg()


在上面這個程式中,我們看到我們可以使用一個fref參考,就可以呼叫foo1或是foo2中的showMsg()方法。

我們都知道Java的函式重載(overload)功能,重載可以使用一個函式名稱來執行不同的實作,這是實現「多型」(polymorphism)的一種方法,也就是「一個介面,多種函式」,使用函式重載來實現多型,是一種「編譯時期」就需決定的方式,這是「早期繫結」(early binding),因為我們在編譯時就可以決定函式的呼叫對象,它們的呼叫位址在編譯時就可以得知。

Java可以實現「執行時期」的多型支援,一個「晚期繫結」(late binding)物件的功能,也就是指這個物件必須在執行時期才會得知引發它的事件,不過上面這個例子不能看出執行時期的晚期繫結功能,下面這個例子或許可以進一步的表現這個功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.io.*;
 
// 抽象類別
abstract class Employee {
    abstract public void dealSalary();  // 抽象函式
}
 
class PartTimeEmployee extends Employee {
    public void dealSalary() {
        System.out.println("Now, deal part-time employee's salary");
    }
}
 
class FullTimeEmployee extends Employee {
    public void dealSalary() {
        System.out.println("Now, deal full-time employee's salary");
    }
}
 
public class Polymorphism {
    public static void main(String[] args) throws IOException {
        Employee employee = null;
        PartTimeEmployee partTimeEmployee = new PartTimeEmployee();
        FullTimeEmployee fullTimeEmployee = new FullTimeEmployee();
        int option;
        BufferedReader buf = new BufferedReader(
                  new InputStreamReader(System.in));
 
        System.out.print("1 for part-time\n2 for full-time\noption? ");
        option = Integer.parseInt(buf.readLine());
 
        switch(option) {
            case 1:
                employee = partTimeEmployee;
                break;
            case 2:
                employee = fullTimeEmployee;
                break;
            default:
                System.out.println("Unknown option");
        }
 
        employee.dealSalary();
        
    }
}


執行結果:
1
2
3
4
5
6
7
8
9
10
11
$ java Polymorphism
1 for part-time
2 for full-time
option? 1
Now, deal part-time employee's salary
 
$ java Polymorphism
1 for part-time
2 for full-time
option? 2
Now, deal full-time employee's salary


這個程式簡單的示範了Java的執行時期繫結功能,我們依不同的選項而決定該繫結哪一個衍生類別物件,並執行指定的函式;在這個例子中,我們的基底類別定義了「抽象函式」,也就是沒有定義任何實作內容的函式,這必須使用abstract來宣告,它告訴編譯器這個函式是抽象函式,並沒有實作任何的內容,繼承這個類別的衍生類別必須實作它的內容。

一個含有抽象函式的類別被視為「抽象類別」(abstract class),由於它是個未完成的類別,所以它不能被用來生成物件,它只能被繼承,宣告抽象類別時也必須加上abstract關鍵字。

當您在基底類別中宣告抽象函式,並在衍生類別中重新定義了該函式,當基底類別參考指向衍生類別物件時,程式就可以根據參考所指向的物件來得知,它要執行的是衍生類別中重新定義的函式,這有些類似超載函式,但不同的是這種決定是在執行時期時進行的。

抽象類別的作用在於規定出一個統一的介面,所有繼承它的都必須實作當中尚未實作的抽象方法,舉個例子來說,您定義了一個Thread類別,這個類別可以提供多執行緒的支援,然而多執行緒的執行實作則留得繼承這個類別的程式設計人員來完成,所以您可以定義一個run()抽象函式,所有繼承Thread的衍生類別,都要實作run()函式,以完成各自所需的執行方法。


caterpillar edited on 2005-08-21 19:20
reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
UndeadJ

UX & UI Design



發文: 384
積分: 3
於 2003-09-08 21:08 user profilesend a private message to usersend email to UndeadJreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
總覺得這裡怪怪的...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Polymorphism {
    public static void main(String[] args) {
        foo1 fref;
        foo1 f1 = new foo1();
        foo2 f2 = new foo2();
 
        fref = f1;
        f1.showMsg();<--是不是應該改成fref.showMsg();
 
        fref = f2;
        f2.showMsg();<--是不是應該改成fref.showMsg();
 
        System.out.println();
 
        f1.showMsg();
        f2.showMsg();
    }


如果沒有改,這二行不就白打了Big Smile
1
2
 fref = f1;
 fref = f2;

而且也看不到你所說的"使用一個fref參考,就可以呼叫foo1或是foo2中的showMsg()方法"Wink


UndeadJ edited on 2003-09-08 21:17
reply to postreply to post
我們是懷抱各自的夢想,買了車票的乘客,不過就像列車一定會有終點,人生有時會碰到必須換車的時候...

我們站在名為「今天」的車站,在名為「昨天」的列車下車,轉搭為「明天」的列車

不過,若沒及時搭上的話....
作者 Re:給新手 - 抽象函式、抽象類別 [Re:UndeadJ]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-08 21:20 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
程式寫的太快,沒有看到,謝謝更正。。。。

caterpillar edited on 2004-11-24 09:42
reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
immanuel





發文: 6
積分: 0
於 2003-09-08 22:44 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
潛水很久 第一次浮出水面 問題若問得不好 請多多包涵與指教
畢竟 學問學問 不就是學習怎麼問問題嗎?

caterpillar大大文中提到幾句話正是我近日注意到的問題 容我引述如下:
"...一個基底類別的物件參考,可以用來指向其衍生類別物件而不會發生錯誤......將衍生類別型態的參考指向基底類別的物件基本是不可行的(雖然可以使用型態轉換的方式來勉強達成,但並不鼓勵),衍生類別的參考並不能存取基底類別的成員..."
我想問的是在什麼情況下(延伸的或具體的應用) 我們會需要用一個superclass的object reference viriable指到其subclass的object?

請不吝賜教
謝謝!!


reply to postreply to post
作者 Re:給新手 - 抽象函式、抽象類別 [Re:immanuel]
Yoshi

塵世中一個迷途小書僮

版主

發文: 874
積分: 22
於 2003-09-08 22:50 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
immanuel wrote:
我想問的是在什麼情況下(延伸的或具體的應用) 我們會需要用一個superclass的object reference variable指到其subclass的object?

請不吝賜教
謝謝!!


Vector中的add不就是了?
public void add(Object o)
你要是不用Object來做type, 這個vector會很遜

--
你的variable拼錯了...


reply to postreply to post
YOSHI!
作者 Re:給新手 - 抽象函式、抽象類別 [Re:immanuel]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-08 23:01 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
immanuel wrote:
潛水很久 第一次浮出水面 問題若問得不好 請多多包涵與指教
畢竟 學問學問 不就是學習怎麼問問題嗎?

caterpillar大大文中提到幾句話正是我近日注意到的問題 容我引述如下:
"...一個基底類別的物件參考,可以用來指向其衍生類別物件而不會發生錯誤......將衍生類別型態的參考指向基底類別的物件基本是不可行的(雖然可以使用型態轉換的方式來勉強達成,但並不鼓勵),衍生類別的參考並不能存取基底類別的成員..."
我想問的是在什麼情況下(延伸的或具體的應用) 我們會需要用一個superclass的object reference viriable指到其subclass的object?

請不吝賜教
謝謝!!


我剛寫好的另一篇「給新手 - Object類別」中有個簡單的範例,而就如Yoshi所言,Vector類別也是一例,您在寫視窗程式時,也很容易看得到這些例子。


reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
iampoya

Speculator

版主

發文: 169
積分: 8
於 2003-09-08 23:16 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
caterpillar wrote:
注意將衍生類別型態的參考指向基底類別的物件基本是不可行的(雖然可以使用型態轉換的方式來勉強達成,但並不鼓勵),衍生類別的參考並不能存取基底類別的成員。

1
2
3
4
5
6
7
8
9
10
11
12
13
class AAA  
{
  int i = 10;
}
 
class BBB extends AAA
{
  public static void main(String[] args) 
  {
    System.out.println(((AAA)(new BBB())).i);
  }
 
}

呀…那醬子要怎麻講


iampoya edited on 2003-09-08 23:20
reply to postreply to post
Japan Adult Video Album
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
immanuel





發文: 6
積分: 0
於 2003-09-08 23:17 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
謝謝兩位大大
因為我是菜的不能再菜的新手 所以還沒真正碰到Vector與視窗的問題呢
以後若遇到相關領域 一定會多加注意 再把我的心得分享出來
謝謝啦!!

p.s 是variable沒錯 謝謝Yoshi大大


immanuel edited on 2003-09-08 23:19
reply to postreply to post
作者 Re:給新手 - 抽象函式、抽象類別 [Re:iampoya]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-08 23:39 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
iampoya wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
class AAA  
{
  int i = 10;
}
 
class BBB extends AAA
{
  public static void main(String[] args) 
  {
    System.out.println(((AAA)(new BBB())).i);
  }
 
}

呀…那醬子要怎麻講


Sorry,我自首我寫錯了,這句應該刪掉並更新,我的意思是在表達這個是不可行的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class foo1 {
    public void showMsg() {
        System.out.println("foo1's showMsg()");
    }
}
                                                                                
class foo2 extends foo1 {
    public void showMsg() {
        System.out.println("foo2's showMsg()");
    }
}
                                                                                
public class Polymorphism {
    public static void main(String[] args) {
        foo2 fref;
        foo1 f1 = new foo1();
                                                                                
        fref = (foo2) f1;
    }
}


腦袋有些不清楚了。。。。 Sad 還麻煩大家幫我除錯。。。。Sorry


caterpillar edited on 2003-09-08 23:43
reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
iampoya

Speculator

版主

發文: 169
積分: 8
於 2003-09-08 23:48 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
caterpillar wrote:
Sorry,我自首我寫錯了,這句應該刪掉並更新,我的意思是在表達這個是不可行的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class foo1 {
    public void showMsg() {
        System.out.println("foo1's showMsg()");
    }
}
                                                                                
class foo2 extends foo1 {
    public void showMsg() {
        System.out.println("foo2's showMsg()");
    }
}
                                                                                
public class Polymorphism {
    public static void main(String[] args) {
        foo2 fref;
        foo1 f1 = new foo1();
                                                                                
        fref = (foo2) f1;
    }
}


腦袋有些不清楚了。。。。 Sad 還麻煩大家幫我除錯。。。。Sorry

呣…你上面這段是講base class不能向下轉型為sub class
跟原來那段好像沒啥關係耶

不過你原來那段
我只是覺得好像大概應該可能改成衍生類別的參考並不能存取基底類別的private成員。

醬∼好像就對了吧
不會解釋…誰要幫忙解釋一下:P


reply to postreply to post
Japan Adult Video Album
作者 Re:給新手 - 抽象函式、抽象類別 [Re:iampoya]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-08 23:57 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
iampoya wrote:
呣…你上面這段是講base class不能向下轉型為sub class
跟原來那段好像沒啥關係耶

不過你原來那段
我只是覺得好像大概應該可能改成衍生類別的參考並不能存取基底類別的private成員。

醬∼好像就對了吧
不會解釋…誰要幫忙解釋一下:P


看得懂您的意思啦!

其實。。。。其實。。。 。後來我看我自已寫的那句,也忘了我為何要寫那句話了,所以才改掉。。。。。。

所以才說我腦袋不清楚了。。。。。Big SmileBig SmileBig Smile


reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
Yoshi

塵世中一個迷途小書僮

版主

發文: 874
積分: 22
於 2003-09-09 00:01 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
caterpillar wrote:
看得懂您的意思啦!

其實。。。。其實。。。 。後來我看我自已寫的那句,也忘了我為何要寫那句話了,所以才改掉。。。。。。

所以才說我腦袋不清楚了。。。。。Big SmileBig SmileBig Smile


我覺得寫, superclass type來做subclass instance的type
不能存取subclass中所定義的method, 應該比較需要講吧

--
老實說我這篇文章看不太懂...我很怕中文的詞...
衍生類別...基底類別...原生類別...OH MY GOD Black Eye


reply to postreply to post
YOSHI!
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Yoshi]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-09 00:05 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Yoshi wrote:
我覺得寫, superclass type來做subclass instance的type
不能存取subclass中所定義的method, 應該比較需要講吧

--
老實說我這篇文章看不太懂...我很怕中文的詞...
衍生類別...基底類別...原生類別...OH MY GOD Black Eye


這就是寫作的兩難了,所以我一開始就先表明了名詞會有問題,用中文會有中文的難處,保留原文也會有原文中文夾雜的難以閱讀。

嗯!老實說不要生氣喔!您寫的這段我也看不太懂。。。。能不能指引一下?。。。。

您是不是指這樣?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class foo1 {
    // ..
}
 
class foo2 extends foo1 {
    public void newMethod() {
         // ..
    }
}
 
//.  ... 
 
    public static void main(String[] args) {
        foo1 f = new foo2();
 
        f.newMethod();  // 這個不可行
        
    }


caterpillar edited on 2003-09-09 00:11
reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
Yoshi

塵世中一個迷途小書僮

版主

發文: 874
積分: 22
於 2003-09-09 00:08 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
caterpillar wrote:
這就是寫作的兩難了,所以我一開始就先表明了名詞會有問題,用中文會有中文的難處,保留原文也會有原文中文夾雜的難以閱讀。

嗯!老實說不要生氣喔!您寫的這段我也看不太懂。。。。能不能指引一下?。。。。


看程式最快了
1
2
3
4
5
6
7
8
9
10
11
class A {
}
public class Test extends A {
  public void method() {
    System.out.println("Method");
  }
  public static void main(String[] args) {
    A obj = new Test();
    obj.method();
  }
}


我的意思是obj.method()不行


reply to postreply to post
YOSHI!
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Yoshi]
UndeadJ

UX & UI Design



發文: 384
積分: 3
於 2003-09-09 00:09 user profilesend a private message to usersend email to UndeadJreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Yoshi wrote:
老實說我這篇文章看不太懂...我很怕中文的詞...
衍生類別...基底類別...原生類別...OH MY GOD Black Eye

的確很多中文摻雜在一起有時候會看起來很累
如果可以的話,希望關鍵字能夠盡量用英文就用英文
如果怕中英夾雜的問題,可以將關鍵字用粗體表示Smile


reply to postreply to post
我們是懷抱各自的夢想,買了車票的乘客,不過就像列車一定會有終點,人生有時會碰到必須換車的時候...

我們站在名為「今天」的車站,在名為「昨天」的列車下車,轉搭為「明天」的列車

不過,若沒及時搭上的話....
作者 Re:給新手 - 抽象函式、抽象類別 [Re:caterpillar]
iampoya

Speculator

版主

發文: 169
積分: 8
於 2003-09-09 00:09 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class foo1 {
}
                                                                                
class foo2 extends foo1 {
    public void showMsg() {
        System.out.println("foo2's showMsg()");
    }
}
                                                                                
public class Polymorphism {
    public static void main(String[] args) {
        foo1 f1 = new foo2();
        f1.showMsg();
    }
}

yoshi講的應該要強調的地方
是醬子吧

--
靠∼二個人都回這麻快幹嘛
我連copy-paste都趕不上 \_/


iampoya edited on 2003-09-09 00:27
reply to postreply to post
Japan Adult Video Album
作者 Re:給新手 - 抽象函式、抽象類別 [Re:iampoya]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-09 00:17 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
iampoya wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class foo1 {
}
                                                                                
class foo2 extends foo1 {
    public void showMsg() {
        System.out.println("foo2's showMsg()");
    }
}
                                                                                
public class Polymorphism {
    public static void main(String[] args) {
        foo1 f1 = new foo1();
        fref = f1.showMsg();
        ^^^^^^^^^^^^^^^^^^^
    }
}



哈哈!這種東西討論太久好像會真的腦袋不清楚喔!。。。。。Big SmileBig SmileBig Smile

另一篇對Object類別的討論我有提到這個了,只不過沒有明確指出這個觀念而已,總之要轉型。。。。

====

PS......暴走是每個上BBS的人之天性。。。。。


reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 抽象函式、抽象類別 [Re:iampoya]
Yoshi

塵世中一個迷途小書僮

版主

發文: 874
積分: 22
於 2003-09-09 00:20 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
iampoya wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class foo1 {
}
                                                                                
class foo2 extends foo1 {
    public void showMsg() {
        System.out.println("foo2's showMsg()");
    }
}
                                                                                
public class Polymorphism {
    public static void main(String[] args) {
        foo1 f1 = new foo1();
        fref = f1.showMsg();
    }
}

yoshi講的應該要強調的地方
是醬子吧


這個程式和我講的還是有點不一樣...就是foo1 f1 = new foo1()這一行
我想強調的是, 即使是foo2的instance, 但是type為foo1
則無法透過type為foo1的變數去呼叫foo2 instance's method
也就是
1
2
  foo1 f1 = new foo2();
  f1.showMsg();

這樣子是不行的


reply to postreply to post
YOSHI!
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Yoshi]
iampoya

Speculator

版主

發文: 169
積分: 8
於 2003-09-09 00:30 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Yoshi wrote:
這個程式和我講的還是有點不一樣...就是foo1 f1 = new foo1()這一行
我想強調的是, 即使是foo2的instance, 但是type為foo1
則無法透過type為foo1的變數去呼叫foo2 instance's method
也就是
1
2
  foo1 f1 = new foo2();
  f1.showMsg();

這樣子是不行的

呀...對喔∼這個才真是tricky的地方

--
講到爆走...
爆走熊怎麼沒來加入我們 @_@


reply to postreply to post
Japan Adult Video Album
作者 Re:給新手 - 抽象函式、抽象類別 [Re:iampoya]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-09-09 00:52 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
iampoya wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
class AAA  
{
  int i = 10;
}
 
class BBB extends AAA
{
  public static void main(String[] args) 
  {
    System.out.println(((AAA)(new BBB())).i);
  }
 
}

呀…那醬子要怎麻講


這樣並沒有轉型。我希望各位能注意到一點,並不是 (type) 這樣子寫法就是轉型。

其實 Java 根本沒有轉型這玩意兒,你沒有辦法把一個物件轉成另一型態的物件(我指本質上),你只能把一個物件以其所相容的某個規格(型別)般地操作。一般我(或是其他的人)如果提到轉型指的是需要以 checkcast instruction 來確認某個物件是否符合某規格(當物件在各個 method 間傳遞,編譯器通常只能以 method 的 signature 所描述的型別來對待物件,如果你要以有別於 method signature 所指定的型別來操作物件,那麼編譯器必須產生 checkcast instruction 好在 runtime 時確保被操作的物件的確符合你要的規格。
比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class foo implements Cloneable{
  public static void main(String[] args)
  {
    foo obj = (foo) new foo(87).clone(); // 因為 foo::clone method 的 signature 訂 return type 為
  // java.lang.Object,這時候編譯器一定要產生 checkcast instruction 好在 runtime 時能保證以
  // foo 觀點來操作 clone 傳回的物件一定沒問題。
  // 雖然在這一點,你會覺得用肉眼看"已經"可以確定 clone 傳回的物件一定是 foo object。
  System.out.println(obj);
  }
 
  public foo(int n)
  {
    data = n;
  }
 
  public Object clone()
  {
    return new foo(data);
  }
  private int data;
}


Java 沒有轉型(轉化)物件的功能是肇因於 Java 除了 primitive type 之外對所有的物件只有"參考"的概念,你只能以某種觀點來參考某個物件,不像 C++ 能以絕對的型別來對待資料。(type) 只是表示你將以不同的型別觀點來參考某個物件,但不一定需要 checkcast 來作檢驗,被參考的物件還是原來的物件,沒有動到半根汗毛,也沒有中間產物出現(即暫時物件,這是 C++ 物件轉型的策略之一)。

回頭來看:
1
System.out.println(((AAA)(new BBB())).i);

在這裡(以其所在的 context 來說) (AAA)告訴編譯器你要把新建構的物件當作 AAA 物件來看,因為 field 沒有 polymorphism 的特性,每個型別各自保持一份 field 實體,所以在這裡編譯器懂得(認為)你的意思是要存取 new BBB() object 裡的 AAA sub-object 的 field i(這個 i 是屬於 AAA object 的)。存取 field 的 instruction: getfield 的參數會指明要取得的 field 是屬於(定義在)哪個 class,所以編譯器可以直接產生指明 AAA::i 的 instruction。比如:
1
2
3
4
new BBB
dup
invokespecial BBB/<init>()V    ;初始化 BBB object
getfield AAA/i I        ; I 是 int 的 type descriptor 寫法


Duncan edited on 2003-09-09 01:03
reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Duncan]
iampoya

Speculator

版主

發文: 169
積分: 8
於 2003-09-09 01:05 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
喔耶...傳說已久的電人之王終於又出現了

--
雖然被電,但我還是覺得很爽
感謝糾正我模糊不清的錯誤觀念 ^_^


reply to postreply to post
Japan Adult Video Album
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Duncan]
Yoshi

塵世中一個迷途小書僮

版主

發文: 874
積分: 22
於 2003-09-09 01:09 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
這樣並沒有轉型。我希望各位能注意到一點,並不是 (type) 這樣子寫法就是轉型。

其實 Java 根本沒有轉型這玩意兒,你沒有辦法把一個物件轉成另一型態的物件(我指本質上),你只能把一個物件以其所相容的某個規格(型別)般地操作。


哇塞...每次看Duncan的文章都很害怕, 擔心被幹礁的人會不會是自己Tongue

我從以前就一直覺得是轉型, 可能因為我沒有接觸過其它的語言 (只有一點C)
我也不懷疑轉型這個詞的翻譯, 剛剛查了一下譯典通, Cast這個字有著"扮演", "投射", "選派"等意思

那麼JLS中的Cast Conversion翻譯為"扮演變換"(很難聽)不知道會不會比較合乎意義?
還有一個疑問, 轉型這個字在programming中有定義嗎?
一定要把東西實質變化了才能稱做轉型?
像我們也會說某個藝人轉型走歌唱路線...但是這個藝人身體也沒有變, 只是換了扮演的角色
所以我很好奇, 轉型有定義? 我們不能把Java這種行為就稱做轉型嗎?


reply to postreply to post
YOSHI!
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Yoshi]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-09-09 01:46 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Yoshi wrote:
哇塞...每次看Duncan的文章都很害怕, 擔心被幹礁的人會不會是自己Tongue

我有幹礁過人嗎?Oh My God "詌譙" 和 "幹礁" 是不一樣的。

Yoshi wrote:
我從以前就一直覺得是轉型, 可能因為我沒有接觸過其它的語言 (只有一點C)
我也不懷疑轉型這個詞的翻譯, 剛剛查了一下譯典通, Cast這個字有著"扮演", "投射", "選派"等意思

那麼JLS中的Cast Conversion翻譯為"扮演變換"(很難聽)不知道會不會比較合乎意義?
還有一個疑問, 轉型這個字在programming中有定義嗎?
一定要把東西實質變化了才能稱做轉型?
像我們也會說某個藝人轉型走歌唱路線...但是這個藝人身體也沒有變, 只是換了扮演的角色
所以我很好奇, 轉型有定義? 我們不能把Java這種行為就稱做轉型嗎?


我也不清楚"轉型"的定義是什麼,在論壇裡常可看到這個詞,但是很少有人針對其定義來作討論,轉型似乎慢慢變成一種 conventional 說法,但是其概念蠻模糊的,就像 design pattern 裡的 pattern 名稱許多人都能朗朗上口,但是並不一定都很清楚他的本質,只能大概說出大概是什麼樣的東西。

在 Java 裡我認為以不同的觀點來對待一個原本以另一個觀點對待的物件就可以算是轉型,這也是一般 Java programmer 認為的。但以我個人對 C/C++ 的一些經驗來說,其實真正的轉型(in Java)應該是對 primitive type 的轉型動作:
1
2
int i = 10;
System.out.pintln((long)i);


這裡的 operator (long) 除了讓編譯器據以在 PrintStream 眾多的 overlaoding method - println 之中挑出一個較適當的這個用途之外,也真的把原本存在 local variable i 中的值作了本質上的轉變:int -> long(4 bytes -> 8 bytes),但不是真的更動 local variable 的內容,而是把 local variable 的 value push 到堆疊(原本是一個 4 bytes long 的資料),然後透過 instruction i2l(I to L) 把放在堆疊最頂端的 4 bytes 拿出來轉換成 8 bytes 長的 long 格式再放進堆疊,這種作法和 C/C++ 的型態轉換的精神與作法都很類似,都是在堆疊產生一暫時物件/data block(在上面 Java 的例子裡是在 stack 產生 primitive type value,但你也可以把 primitive type 當作物件)。

我所以說以不同觀點來對待物件也算是轉型,是因為 C++ 有四種轉型的 operator const_cast/static_cast/dynamic_cast/reinterpret_cast,其中的 reinterpret_cast 最接近 Java 中 (ClassType) 這種轉型,都是以程式員想要的觀點來對待某個地方某個數量的 data(型態本身就點出物件的大小),不同的是 Java 會確保這個以其他觀點來對待物件的動作會是正確的,否則便丟出 exception,而 C++ 則不然,純粹以 reinterpret_cast 參數所指定的觀點來對待指定位址上的資料,你要把檸檬(黃的,綠的叫萊姆?)當作柳丁吃,後果自己負責。

--
其實我也很怕被人家兔槽,希望 william 大哥不要到 J2SE 和新手版來。


Duncan edited on 2003-09-09 15:45
reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Duncan]
Biologic

生物學下的產物



發文: 524
積分: 4
於 2003-09-09 18:58 user profilesend a private message to usersend email to Biologicreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
--
其實我也很怕被人家兔槽,希望 william 大哥不要到 J2SE 和新手版來。


不好意思...
這是討論 casting, 還是 轉型?
還是討論用詞不當?

另外我才剛被 william 電...
哦... 再電一次... 喔.... 越電越爽....


reply to postreply to post
作者 Re:給新手 - 抽象函式、抽象類別 [Re:Biologic]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-09-09 23:25 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Biologic wrote:
不好意思...
這是討論 casting, 還是 轉型?
還是討論用詞不當?

另外我才剛被 william 電...
哦... 再電一次... 喔.... 越電越爽....


一般人不是把 "轉型" 看成 "casting" 的譯文?

--
被電會上癮嗎?


reply to postreply to post

給我
辣味豆腐 其餘免談
go to first page go to previous page  1   2  go to next page go to last page
» JWorld@TW »  Java 新手區 » Object/物件導向

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8