1.接口介紹
今天是你獲取知識的一天。另一個有趣的新話題是接口。
接口的概念是抽象和多態性原則的產物。接口非常類似於抽像類,其中所有方法都是抽象的。它的聲明方式與類相同,但我們使用關鍵字interface
。
interface Feline
{
void purr();
void meow();
void growl();
}
以下是有關接口的一些有用事實:
1. 聲明一個接口
interface Drawable
{
void draw();
}
interface HasValue
{
int getValue();
}
class
我們寫interface
.- 它只包含抽象方法(不要寫關鍵字
abstract
) - 事實上,接口擁有所有的
public
方法
接口只能繼承接口。但是一個接口可以有很多父母。另一種說法是,Java 具有接口的多重繼承。例子:
interface Piece extends Drawable, HasValue
{
int getX();
int getY();
}
3. 從接口繼承類
一個類可以繼承多個接口(只能從一個類繼承)。這是使用implements
關鍵字完成的。例子:
abstract class ChessItem implements Drawable, HasValue
{
private int x, y, value;
public int getValue()
{
return value;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
ChessItem 類被聲明為抽像類:它實現了除draw
. 換句話說,該類ChessItem
包含一個抽象方法—— draw()
.
extends
和關鍵字的技術含義implements
是一樣的:都是繼承。進行區分是為了提高代碼的可讀性。我們還說類是繼承的(通過extends
),接口是實現的(通過implements
)
4.變量
最重要的是:普通變量不能在接口中聲明(儘管靜態變量可以)。
但是為什麼我們需要接口呢?它們什麼時候使用?與類相比,接口有兩個強大的優勢:
2. 將“方法描述”與其實現分開。
前面我們說過,如果你想讓你的類的方法可以被其他類調用,那麼你的方法就需要標記關鍵字public
。如果您希望其中一些方法僅在您的類中調用,則需要用關鍵字標記它們private
。也就是說,我們把類的方法分為兩類:“供大家使用”和“只供自己使用”。
接口有助於進一步加強這種劃分。我們將創建一個特殊的“供所有人使用的類”以及“僅供我們自己使用”的第二個類,它將繼承第一個類。大致如下所示:
前 | 後 |
---|---|
|
|
|
|
我們將我們的類分成兩部分:一個接口和一個繼承該接口的類。這裡的優勢是什麼?
許多不同的類可以實現(繼承)同一個接口。每個人都可以有自己的行為。例如,ArrayList
LinkedList
是接口的兩種不同實現List
。
因此,我們不僅隱藏了各種實現,還隱藏了實現類本身(因為我們只需要代碼中的接口)。這讓我們變得非常靈活:就在程序運行時,我們可以用一個對象替換另一個對象,改變對象的行為而不影響使用它的所有類。
當與多態性結合時,這是一種非常強大的技術。目前,您應該這樣做的原因還很不明確。您首先需要遇到包含數十個或數百個類的程序,以便理解接口可以使您的生活比沒有它們要容易得多。
3.多重繼承
在Java中,所有類只能有一個父類。在其他編程語言中,類通常可以有多個父類。這很方便,但也帶來了很多問題。
Java 的創造者達成了妥協:他們禁止類的多重繼承,但允許接口的多重繼承。一個接口可以有多個父接口。 一個類可以有多個父接口,但只有一個父類。
為什麼他們禁止類的多重繼承而允許接口的多重繼承?由於所謂的鑽石繼承問題:

B類繼承A類時,對C、D類一無所知。所以它使用它認為合適的 A 類的變量。C 類做同樣的事情:它使用 A 類的變量,但方式不同。而這一切,導致了D班的一場衝突。
讓我們看看下面這個簡單的例子。假設我們有 3 個類:
class Data
{
protected int value;
}
class XCoordinate extends Data
{
public void setX (int x) { value = x;}
public int getX () { return value;}
}
class YCoordinate extends Data
{
public void setY (int y) { value = y;}
public int getY () { return value; }
}
Data 類存儲value
變量。它的 XCoordinate 後代類使用該變量來存儲x
值,YCoordinate
後代類使用它來存儲y
值。
它有效。分別地。但是如果我們希望 XYCoordinates 類同時繼承XCoordinate
和YCoordinate
類,那麼我們就會得到錯誤的代碼。此類將具有其祖先類的方法,但它們無法正常工作,因為它們具有相同的value variable
.
但是因為接口不能有變量,所以不能有這種衝突。因此,允許接口的多重繼承。
GO TO FULL VERSION