請問java物件導向的抽象類別,是作什麼用

學了物件導向
還是沒弄懂
抽象類別是要作什麼用
抽象類別的用意是什麼
能否請大家幫忙解說一下
感激不盡
就很顧名思義,打個比方好了。

假設你今天要做個遊戲,那麼為了遊戲需要而生成的對象(不是管理系統,就是遊戲層別的那種,比如魔王和小怪),這些對象他們可能都會有個共通點,比如魔王和主角和小怪他們可能都需要被畫出來,也有可能都需要被調查他們的屬性,換句話說,他們有共通點但實作方法又不同,就可以用抽象類別來規範。

依照慣例,個人還是用C++來寫示範代碼....反正長得差不多,virtual是拿來當成抽象用的,函式後面=0意思就是完全不定義,這意味著如果這個物件需要使用的時候必要有繼承動作發生,因為自身沒有定義函式執行的細節,所以必須透過繼承者來訂定之。

class Object
{
public:
virtual void Draw()=0;
virtual Player_Data GetData()=0;
}

這時候可能會有魔王來繼承:
class 魔王:public Object
{
public:
virtual void Draw(){魔王可能要把它自己的背景特效畫出來};
virtual Player_Data GetData(){魔王可能要傳回自己的特功血量};
}

這時候可能會有勇者來繼承:
class 勇者:public Object
{
public:
virtual void Draw(){勇者可能可以畫一些被馴服小怪在旁邊};
virtual Player_Data GetData(){或許勇者有特殊的招式技術是需要被記錄的};
}

在這種情況下,我管你存的物件是甚麼,我只要知道,我要把Object派生類別的東西要畫出來就是呼叫Draw,要拿到資料就是叫GetData,詳細的實現都會隨著繼承產生不同的結果,換句話說,他是保障一種一致性的好方法,特別是用在這種情況。(當然你要自己規定自己慢慢寫也是沒意見,但....我相信你多看點書就會有感覺為甚麼要這樣做了,恩)

可愛的卡比 wrote:
就很顧名思義,打個比...(恕刪)

他們有共通點但實作方法又不同,就可以用抽象類別來規範。
這樣說明就很容易明白了
謝謝
二樓例子Object類別裡兩個方法都是純虛擬,
應該是對應到Java的interface。
因為在C++裡面 class、abstract、interface都是同一件事。

抽象類別我第一個想到的是樣板模式(template method pattern)

可以找時間看看design pattern的書,
滿多專講「程式語言」的書,在物件導向章節的舉例都怪怪的。

wes4820 wrote:
二樓例子Object...(恕刪)

謝謝
wes4820 wrote:
二樓例子Object類別裡兩個方法都是純虛擬,
應該是對應到Java的interface。
因為在C++裡面 class、abstract、interface都是同一件事。


歹勢XD,剛剛查了一下,介面和抽象類別的差別在於裡面有無實作的函式或私有變數,我舉的例子是純抽象類別,相當於interface,意思就是必須透過繼承這個介面才會被活化。

"首先,abstract class在Java語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。但是,一個類卻可以實現多個interface。也許,這是Java語言的設計者在考慮Java對於多重繼承的支持方面的一種折中考慮吧。 "摘自這裡

解說錯誤這點還是有點抱歉@@不過我想核心概念是有點類似的,吧(汗)

因為在C++裡面還可以把純虛擬對象繼承出來的實例,都可以強迫用純虛擬物件來解釋,不過JAVA沒有指標應該就沒有這種奇怪的功能了。

"其實abstract class表示的是"is a"關係,interface表示的是"like a"關係"同樣摘自這裡

我想這應該可以詳細說明兩者的差異了,不過跟虛擬有關係的東西通常都是因為有共通點但實作方法不同這點沒錯XD

可愛的卡比 wrote:
因為在C++裡面還可以把純虛擬對象繼承出來的實例,都可以強迫用純虛擬物件來解釋,不過JAVA沒有指標應該就沒有這種奇怪的功能了。...(恕刪)

OK的,JAVA可以用父類別變數指向子類別。

物件導向在設計時有個守則:
Program to an interface, not an implementation
(對介面寫程式,而非實作)

樓主如果想弄懂interface、abstract,
那或許不該將目光放在Java本身 (當然JDK內帶物件也是很好的範例),

更抽象的理論 (design pattern)才會用到兩個鬼東西,
也有助於跳脫語言的限制,成為能夠隨時利用身邊趁手武器的人。
同一張設計圖可以用各種語言來達成。

昨天無意間看到有人寫了這篇「程式師的成長的六個階段」,
在這邊分享一下:
http://www.cnblogs.com/oomusou/archive/2008/05/01/1179046.html

PS. 境界不到,越級打怪會走火入魔嗎?
wes4820 wrote:
OK的,JAVA可以用父類別變數指向子類別。


喔喔長知識了@@
C++在這邊真的是有夠暴力(虛表一樣的話甚至可以突破編譯器層級的private管理囧)
不過我印象中JAVA好像其實變數都是用reference在管理物件之類的東西,是嗎@@

然後個人是覺得還不用先接觸到Design Patterns,我覺得先累積單一語言的功力會比較重要,其實我覺得多看多想就會有點感覺了(重點是也要實作,會更能理解),等到基礎的東西搞定後再來深入該語言,接著配上設計思想之類的東西後再進入底層會比較好@@(底層都是一堆模式的運用,沒有搞清楚的話很容易會困惑)。

雖然個人也還在第一階段打滾中XD不過來日方長咩(被踹)
宣告為「抽象」的類別 Abstract Class 不能被 new 實體化,如果在程式中去 new 抽象類別,編譯階段就會出現錯誤訊息不給過。

抽象類別只是告知開發者,必須去實作那個類別,亦即:要去「繼承」抽象類別,並且實作子類別出來。

抽像類別唯一目的,就是:讓整個繼承結構更完整。讓"物件導向"更合理化。


舉個例子:

生物(界、門、綱、目、科、屬、種)

動物界、植物界

人類(動物界、脊索動物門、 哺乳綱、靈長目、人科)

abstract class 生物 {
abstract void 基因染色體 () ;
}

// 這個「生物」類別,被宣告為抽象的,無法直接 new,一定要繼承並實作才能使用。

// 它預先宣告了一個「抽象方法」:基因染色體。

// 抽象類別可以整個空白,也可以預先定義一些成員屬性、方法。


class 動物 extends 生物 { }

// 「動物」類別,繼承「生物」抽象類別

// 雖然這個「動物」類別沒有宣告 abstract 抽象,但因為沒有實作「抽象方法」,所以會自動成為「抽象類別」,亦即無法直接 new。

// 凡是子類別繼承「抽象類別」,沒有實作它裡面的「抽象方法」,就會自動成為抽象類別。


class 人類 extends 動物 {
void 基因染色體 (numOfDna) {
System.out.println ( "染色體有" + numOfDna + "對");
}
}

// 「人類」類別 繼承「動物」類別,並且實作了「抽象方法」,這個類別是可以 new 的。



也許你會覺得奇怪,沒事搞這麼複雜幹嘛?

直接一個「人類」類別不就得了,幹嘛上層還用什麼「生物」「動物」抽象類別?吃飽撐著?

這樣講也是沒錯,所以抽象類別一般很少使用....

但有些人比較龜毛,非得要整個 OO 結構合理完整化。這有助於邏輯思路。

不過其實這才是真正意義上的 OO,因此 JAVA 提供了抽象類別。

另一種用途是:大團隊合作,起先企劃的人,想到一些點子,但是如何實作,企劃的人不管,他只是先行企劃一個大概方向,實作的細節交給其他合作的夥伴去解決。所以企劃就先宣告一些抽象類別,合作的夥伴再去實作細節。分工合作這樣子。


fedora wrote:
宣告為「抽象」的類別...(恕刪)

非常容易懂
真是太好了
謝謝
關閉廣告

今日熱門文章 網友點擊推薦!

文章分享
評分
複製連結