2010-05-19 129 views
22

的最近我決定看看Java的,所以我還是很新的,並也以面向對象編程的方法,所以我想直接瞭解更多之前得到一些東西, (我想這是永遠不會很快開始的良好做法)。使用的Java [接口/抽象類]

我編程有點2D遊戲的,但我認爲我的問題適用於任何非平凡的項目。爲了簡單起見,我將提供我的遊戲示例。

我有不同種類的殭屍,但它們都具有相同的屬性(X,Y,健康,攻擊等),所以我寫了接口殭屍,我通過WalkingZombie,RunningZombie TeleportingZombie等實現這是最好的要做的事?我更喜歡抽象類嗎?或與超級? (我不打算以部分實現的功能 - 爲此我選擇了一個接口代替抽象類的)

我有一類描述主角(倖存者),並且由於它是相當大的我想用不同的函數編寫一個接口,以便我可以輕鬆查看和分享它的結構。這是不錯的做法嗎?或者這只是浪費空間和時間?

我希望這個問題不會被評爲主觀因爲我認爲有經驗的程序員不會對這類話題持不同意見,因爲接口/超類/抽象類的使用遵循邏輯規則,因此不是簡單的個人選擇。

+0

+1爲殭屍的例子 – 2010-05-19 20:51:30

回答

15

您可以將界面視爲「合同」。您正在定義一組實現此接口的類必須實現的方法。

一個抽象類,在另一方面,當你有一些代碼,可能是常見的,你要實現的所有子類使用。所以你可能有一個叫做Shape的抽象類,它有一些通用的代碼,在你的派生類(Circle,Square等)中,你可以使用特定於這些形狀的代碼(getArea就是一個例子)。但是像顏色這樣的東西可能對所有形狀都很常見,所以你可以在Shape抽象類中放置一個getColor方法。

你可以結合這兩個想法。你可以擁有實現接口的抽象類,這給你兩全其美。

這些概念被用來一遍又一遍的OO,所以瞭解他們是非常重要的。你似乎很好:)。

所以,如果你的殭屍類有適用於所有類型的殭屍的一些常見的行爲,這聽起來像一個很好的候選人是一個抽象類。如果你的遊戲中有其他角色(或許是UndeadMice或其他:)),你也可以考慮創建一個界面(也許是一個GameCharacter界面)。那麼抽象類和UndeadMouse抽象類將實現接口GameCharacter

+0

+1使用「合同」 – 2010-05-19 20:51:49

+0

謝謝:)雖然很難決定是誰給予'回答'.. 我特別喜歡你關於實現接口的抽象類的想法,提供了一個非常清晰的類型結構例如,同樣的屬性,同時允許非常不同類型的移動處理。仍然很難真正連接一切正確的方式看到所有的關係等 – Samuel 2010-05-19 21:44:58

+1

@Samuel - 當你看到如何連接的東西有問題時,它有時幫助繪製在紙上的東西,或使用一些工具,如Microsoft Visio。它可以幫助你形象地看到事物如何融合在一起,所以你可以設計適當的抽象層次。 – dcp 2010-05-19 21:48:05

0

我不認爲你的情況你的接口和類結構的現實正相符合。事實上,我相信(糾正我,如果我錯了),每個殭屍都可以走路,跑步,傳送等,這取決於它在哪裏。

因此,你應該有一個殭屍類或接口,並具有修改殭屍的政府行爲。這個動作可能是一個界面或一個抽象類,這樣你就可以將任何動作應用到殭屍而不知道確切的動作是什麼(例如action.perform(zobie))。如果你有不同種類的殭屍,比如三腿殭屍和單臂殭屍,你可能想要實現處理殭屍的不同類,比如顯示自己或者驗證狀態變化(例如特殊的有種殭屍可能不接受被傳送)。

+0

這將是一個有趣的社會學問題,看看有人將「行走」「跑步」和「傳送」解釋爲狀態而不是類型與他們一生中有多少小時丟失到便宜的殭屍射擊遊戲:) – Affe 2010-05-19 20:55:09

+0

爲什麼我有不同的類型是因爲他們有不同的方法1.移動和2.初始化,而行走殭屍走進屏幕瞬移殭屍出現在你身邊並攻擊你。可能還有一個醉酒殭屍隨機在高速投擲瓶子裏跑來跑去(例子) – Samuel 2010-05-19 21:58:23

+0

我明白了,所以他們*是*不同的殭屍類型,而不是任何殭屍可以執行的動作。在這種情況下,他們自己的實施將罰款恕我直言。 – Lucero 2010-05-19 22:09:18

0

在你的殭屍舉例而言,界面會做得很好,除非你有你想要的所有殭屍做通用代碼。假如你有一個Move的方法,那會讓行走殭屍走,運行殭屍跑等等。但是,如果你想讓「移動」讓任何一種殭屍做一些常見的事情,那麼界面會強制你重複代碼,因爲你不能在界面中放置一個物體。

1

我會寫殭屍作爲一個抽象類,以避免域X,Y,健康等的重新定義......

遺族類,我也只會聲明公用的功能使用外部。我在課堂頂部宣佈公共職能。聲明一個接口,當只有一個類實現時無用地添加一個文件來維護。躲開它。

+0

我不會說增加一個文件的維護問題。後來當你想要一個額外的東西,你會得到一個界面,但你沒有一個,並且需要付出很多努力,這是一個問題。 – JHollanti 2010-05-19 20:57:47

+0

一個文件不是問題,但如果你係統地做到這一點,你將會得到很多這樣的文件。在需要時添加接口對今天的IDE來說沒什麼大不了的。 – 2010-05-19 21:07:40

+0

對於我來說,接口文件也幫助我保持整個程序的結構清晰。與x,y,健康的好處,我可能會使用上面提到的實現與具有普通x,y,健康的殭屍的抽象類的接口的想法。 – Samuel 2010-05-19 21:50:27

1

沒有人同意關於在超級/抽象類使用接口)

主要原因使用接口和超級/抽象類是使多態。舉個例子,你的屏幕上有東西(玩家和殭屍等)。爲什麼不使用相同的方法在屏幕上移動?也許從一個名爲「Movable」或類似的東西繼承屏幕上的所有內容。

如果你真的進入這個東西你可能想在混入一下爲好。這不是Java直接支持的東西,而是爲它構建的庫。

+1

Joshua Bloch,Spring框架背後的傢伙,基本上任何不想被鎖定到單一(實現) - 延遲的人都會偏好組合(實現)繼承。這是相當多的人:) – SyntaxT3rr0r 2010-05-19 21:20:53

+0

授予,好點,但我不會開始討論這個問題;)沒有足夠的時間在這個世界上。 – JHollanti 2010-05-19 22:06:47

+0

對於常見行爲,請改用策略模式。讓接口殭屍有一個getMoveStrategy()方法,並使用zombie.getMoveStrategy()。move()調用它。可能有一個HopStrategy,一個SlouchStrategy和一個RunStrategy等可能有參數的參數(例如受傷的殭屍比較慢,生氣的殭屍比較快等等,如果沒有戰略模式,還有很多if-then-else) – 2010-05-20 12:13:28

3

是的,我認爲你正在接近抽象類接口的正確軌道。

任何具體的殭屍你可能想使可以擁有行走的任意組合,運行或隱形傳態功能,你關心實現。

我認爲現代規劃理論的繼承鼓勵儘可能多的,因爲它抑制了長期的可重用性和靈活性。相反,使用接口和組合來實現靈活性,而不是「緊密耦合」。

一種方法來重複使用代碼,而繼承,你可以應用的青睞在繼承組成「範式。

我喜歡把喬希布洛赫的「有效的Java」(第2版)可以作爲「目前的想法」 ......

http://books.google.com/books?id=ZZOiqZQIbRMC&pg=RA1-PA71&lpg=RA1-PA71&dq=%22Bloch%22+%22Effective+java:+programming+language+guide%22+&hl=de&sig=RxlDlRBWUvNAzsAFzqOcftrYI5E#v=onepage&q&f=false

所以,你可以實現你所有的行爲作爲獨立的課程,然後給每個殭屍實施自己的行爲組合,通過實施&組成..

希望有道理&幫助...

+0

是的,但是如果所有殭屍在移動時都應該做一些共同的事情呢?他們都必須有重複的代碼,不是嗎? – 2010-05-19 21:06:56

+1

@Lerxst:不,這就是構圖的要點。你只需簡單地「包裝」一個表示通用功能的類的實例,並將通用調用委託給該類。唯一重複的代碼是委託調用,但每個方法只有一行(在每個* XXXZombie *類中)。將調用委託給包裝的主題可以由好的IDE自動完成。 – SyntaxT3rr0r 2010-05-19 21:19:06

+0

嗨Lerxt&Wizard 我想巫師說我想說什麼..普通行爲將被定義在一個成員類,每個殭屍實現將委託給這個'移動行爲'成員。 當然,你最終會得到重複的代理代碼[單行],更不用說更多的類,但它提供了更多的靈活性。例如,這種常見行爲現在可以被「人」使用,而不攜帶任何與殭屍有關的行李。 – laher 2010-05-19 21:26:36

4

如果有疑問,我選擇遵循GOF範例。

封裝什麼變化: - 在自己的類中定義獨特的行爲。參照上面的例子,在單獨的課程中實施步行,跑步和遠距傳物的行爲。這樣,就實現了多態行爲。

相反,**聚合什麼是常見** - 使用抽象類來定義多態關聯中的常見行爲。在設計對象之間的關係時,我使用這些原則。

1

我有不同種類的殭屍,但它們都具有相同的屬性(X,Y,健康, 攻擊等),所以我寫了我的WalkingZombie, RunningZombie TeleportingZombie等實現一個接口殭屍這個最好的事情是做什麼?我更喜歡 抽象類嗎?或者與一個超級班?

抽象類將爲您的殭屍超級類。一個界面在某種意義上也可能是你的殭屍的超級類(超級界面?)。

公共屬性至少爲共同屬性提供了一個抽象基類。

(我不打算以部分實現的功能 - 爲此我選擇了一個接口,而不是 一個抽象類)

不知道你這是什麼意思。

如果你有不同種類的怪物(地精,獸人等),你可能會發現這些行爲通常會屬於不同的基類。這將提示一個接口。

我會從抽象基類開始,看看代碼在您編寫代碼時會告訴您什麼。

我有一類描述主角(倖存者),並且由於它是相當大的我 想寫具有不同功能的接口,這樣我可以很容易地看到和它 份額的結構。這是不錯的做法嗎?還是僅僅是浪費空間和 時間?

你的倖存者是所謂的玩家角色(相對於非玩家角色 - 某人在遊戲中通常不會攻擊你的倖存者)。

大多數遊戲把所有這些字符類型爲某種怪物,因爲他們都將有許多共同的特性(健康,魔法,寶物,武器等)

所以也許這更多的參數爲一個界面。

看到:

Using inheritance and polymorphism to solve a common game problem Class diagram examples for RPG (Role Playing Game) designing class hierarchy for typical characters in role playing game

0

我的意見是你最好使用一個叫做生物抽象類的超類的所有類型的,那麼,生物,並將其擴展到殭屍適用於所有類型的殭屍。
而且你還需要一個界面..來定義生物可以做什麼的東西..
也許,走路,或爪,或尖叫......
你需要一個抽象類的原因是要禁用生物的實例化,你不希望有一個生物不知道它是什麼生物,對嗎?

+0

技術要點:如果你想禁用實例化,抽象是不夠的,你還必須使構造函數受到保護,否則匿名實例化就像這樣:new Creature(){};是可能的。 – 2010-05-20 12:08:09