當我們談論的概念層次的面向對象編程的概念, 假設我們要創建汽車Object.therefore我們需要設計父class.Suppose如果你打算做的那一部分,如何會怎麼做?爲什麼我們在上課時需要抽象類?
你會使用類或接口或抽象類嗎? 那麼你爲什麼要使用接口?爲什麼我們不能用類/抽象類來做同樣的事情? 使用界面作爲父項有哪些優點?
當我們談論的概念層次的面向對象編程的概念, 假設我們要創建汽車Object.therefore我們需要設計父class.Suppose如果你打算做的那一部分,如何會怎麼做?爲什麼我們在上課時需要抽象類?
你會使用類或接口或抽象類嗎? 那麼你爲什麼要使用接口?爲什麼我們不能用類/抽象類來做同樣的事情? 使用界面作爲父項有哪些優點?
當您不想實例化超類時,您需要抽象類,但您想實現某些的功能。需要
接口,當你有一個單親繼承,並且不能使用抽象類。如果Java中存在多重繼承,我假設您根據您使用的術語討論的內容,接口將是多餘的。
好,使用Car對象,我會嘗試用現實世界的例子來解釋這個概念。
試想一下,你是一個小公司(A),這使得汽車碎片,你讓他們一個更大的公司(B),這是你的客戶,該作品將被其他車的構造函數中使用。
公司B 必須請確保您的作品將遵循標準,並將在所有汽車製造商內兼容。
這是你的界面。
接口被用來定義一些標準化的方法或屬性,以我們的例子中,我們可以定義一個件具有4個孔中的每個角部被固定在由另一家公司製造另一片。
一個抽象的有一點不同,抽象比接口更具體的(當然我同意這是一種無感),但他們是形而下,因爲他們直接實現(例如接口),而一個功能抽象類可以從不被實例化。
抽象類大多用於定義一些基本的或共享功能,使之乾燥。
因此,你可能會創造出延伸一個抽象類,工具接口的類。
下面是一個例子:
interface Vehicle {
protected $engine;
protected $wheels;
public function startUp();
public function stop();
}
您的車輛接口定義哪些需要有一個發動機和車輪(任何數量)的車輛。
abstract class Car implements Vehicle {
protected $wheels = 4;
public function startUp() {
$this->engine->startUp();
}
public function stop() {
$this->engine->stop();
}
}
因爲startUp()
和stop()
只是一個代理來Engine對象,我們可以把他們在抽象類中的所有擴展的類可以重複使用。 我們設置我們的汽車類有4個車輪。
class Renault extends Car {
protected $color = 'yellow';
}
在這裏,我們只需要擴展汽車的抽象類,我們添加一些顏色,因爲它很酷。
現在,假設我們想把雷諾帶到洗車站,因爲我們正在實施一個已知的界面,洗車站將能夠在不知道我們的車輛是雷諾的情況下開展工作,但是隻知道它是一輛車。
這是一個非常基本的例子,它可以更好地設計,但它應該告訴你它是如何工作的。
接口是不需要,至少PHP不需要任何類然而,實現任何接口,你應該使用它們,它往往是一個很好的做法,它可以幫助你編寫API,單元測試或共享時一些其他開發者的代碼。
當你有一些概念來概括其他實體,但沒有「現實世界」的化身時,抽象類是有用的。
假設你在你的程序Car
類和你將不得不從Car
衍生HummerH2
,ToyotaCamry
和DaewooMatiz
類。 Car
是Some-Abstract-Car,任何車都屬於Car
班,但Car
班本身並不代表任何真車。
所以,你可以定義Car
類,如下所示:
abstract class Car
{
public abstract void Move();
public abstract void Stop();
public abstract int GetMaximumSpeed();
public int GetVehicleID()
{
return vehicleID;
}
protected int vehicleID;
}
然後得出你HummerH2
,ToyotaCamry
和DaewooMatiz
從Car
和實施Move()
,Stop()
和GetMaximumSpeed()
那裏。請注意,Car
類將強制它的子類具有vehicleID
字段。
接口就像抽象類不同的是,你不能在接口中聲明的領域。接口用於聲明該類必須實現的一些公共功能。
在我們的例子中,我們可以宣佈接口IMovable:
interface IMovable
{
void Move();
void Stop();
abstract int GetMaximumSpeed();
}
,然後繼承IMovable車類:
abstract class Car: IMovable
{
public int GetVehicleID()
{
return vehicleID;
}
protected int vehicleID;
}
需要注意的是,現在的Car
子類必須實現Move()
和Stop()
方法。
而比我們可以定義一些Ship
類將實現IMovable
接口。在這種情況下,Ship
和Car
都可以作爲IMovable
對象移動,而不管它是否是汽車或輪船,或者不管是否實現IMovable
接口。
P.S.:當然,當你寫一些只有一種類型的汽車的簡單遊戲時,你可以定義非抽象類Car
並使用它。
在風險變得太深和可能過於戲劇化的情況下,我會盡力用我的能力回答您的問題。
在你介紹的例子的上下文中,帶有抽象'Vehicle'類的'Car'類是最合適的解決方案。這是因爲如果你允許的話,汽車可以變成一個非常複雜的物體。與其將所有東西裝入汽車類中,您可能希望編寫一個車輛類來抽象出一些任意的更高級別的數據。如果您打算稍後實施更多功能或創建其他類型的車輛,例如:飛機,這可能非常方便。抽象類允許您的應用程序更靈活;如果你覺得需要,你也可以抽象出車輛類。從概念上講,面向對象是關於代碼與我們在思考抽象和分類方面所有人聯繫的方式。但是,如果您正在實現簡單的功能集,那麼簡單的類就足夠了。
接口是一個完全不同的野獸。一個接口(就計算而言)是一個概念工具,它允許程序員在實現和應用程序之間創建一個分離層。例如,如果你想創建一些程序來與聲卡進行通信,你應該創建一個接口類。事實上,這實質上就是設備驅動程序。一些語言,如Java,有一個內置的接口構造來表示相同的概念。然而,理論上你可以用任何語言創建一個接口。
對於簡單的功能,您可以使用簡單的類。請記住:一個類用於實例化對象;抽象(或基本)類用於從類中抽象數據以創建基本功能。在這兩種情況下,他們都處理與應用程序實現無關的代碼。但是,這些概念工具不能互換使用。這是軟件工程師和程序員之間的區別。知道何時使用正確的工具,而不知道如何使用它們。
正如我前面提到的,應該使用一個接口來將實現與應用程序分開。如果您與設備驅動程序進行通信,則不想混入GUI代碼中。界面就像兩者之間的聯繫。從技術上講,一個接口是「實現的」不是繼承自;然而,在沒有明確接口構造的語言中,類被用來模擬這個概念,因此會被繼承。
我有一個簡單的解釋,假設你有一個B類擴展A. 現在你想在B類中做克隆或者你想做排序。所以現在你會做什麼? 如果你已經創建了一個Clonable類/ Comparable類,那麼你如何在B中使用它,因爲B已經擴展了A。所以你的解決方案是創建另一個擴展可克隆類的類D.創建另一個擴展D的類E(使用克隆方法),然後....意味着因爲Java不支持多重繼承,你必須使類沒有dis .. 但是,當你已經定義了Clonable作爲一個接口,你不得不做什麼只是實現它在Ur B class.ie不需要額外的編碼。 這是我爲什麼做接口的解釋。 如果我在某處錯了,請糾正我。 謝謝。
爲什麼我們在句子中需要多個問號? – michael667
這與程序員中的這個問題幾乎完全相同。SE:[我爲什麼要將類聲明爲抽象類?](http://programmers.stackexchange.com/questions/96947/why-should-i- declare-a-class-as-an-abstract-class) – amit
[Interface vs Abstract Class(general OO)]的可能重複](http://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo) –