當抽象類提供您需要的並且抽象類無法提供的內容時,應該在抽象類後面使用接口。
創建一個沒有具體原因的接口,但因爲你認爲interface==OOP
帶來開銷並證明你誤解了OOP是什麼。對於你的情況,如果在應用代碼中,你注意到你可以刪除抽象類後面的接口,並且在編譯時沒有真正的影響,你可能想知道接口的抽象不僅僅是一個高架。這可能是有用的,因爲沒用。我會開發它。
使用抽象類後面的接口打開實現的可能性:您可能受益於與接口相關的這個抽象類,但是您也可以在具體類中實現接口而無需受益於抽象類,因此如您所願。根據我們的需要,編寫從A到Z的實現可能是不合適的。
我個人認爲,該接口是一個抽象類,後面有用的有兩種情況:
- 接口是很常見的,在所有類型的目標具體類的,但 抽象類是相關的並不是所有目標具體類的類型。
例如,當您實現裝飾器時,您有一個共同的接口來表示裝飾類和裝飾器類。
裝飾類有不同的裝飾類的邏輯和數據。所以,我們的裝飾類或裝飾類的抽象類可能會有所不同。
這裏有一個簡單的例子來表示文件的裝飾器。
通用接口:
public interface IDocumentInput {
void read();
byte[] getBytes();
String getStringContent();
}
裝飾文件:
public class DocumentInput implements IDocumentInput {
private byte[] bytes;
public DocumentInput(byte[] bytes) {
this.bytes = bytes;
}
public byte[] getBytes() {
return bytes;
}
public void read() {
}
public String getStringContent() {
return new String(getBytes(),StandardCharsets.UTF_8);
}
}
用於裝飾抽象類:
public abstract class AbstractDocumentInputDecorator implements IDocumentInput {
protected IDocumentInput document;
protected byte[] bytes;
public AbstractDocumentInputDecorator(IDocumentInput document) {
this.document = document;
}
public byte[] getBytes() {
return bytes;
}
public final String getStringContent() {
return new String(getBytes(),StandardCharsets.UTF_8);
}
}
混凝土裝飾:
public class SecuredDocumentInputDecorator extends AbstractDocumentInputDecorator {
public SecuredDocumentInputDecorator(IDocumentInput document) {
super(document);
}
@Override
public void read() {
document.read();
processUnsecuring();
}
private void processUnsecuring() {
byte[] originalBytes = document.getBytes();
bytes = Base64.decodeBase64(originalBytes);
}
}
在這種情況下,引入接口似乎是合乎邏輯的,因爲抽象類不足以表示所有具體類的常見行爲和/或數據。
您希望爲開發人員提供在不依賴抽象類實現的情況下創建自己的接口實現的可能性。一般來說,當你創建一個開放的API時是可取的。 JDK類中的集合很好地說明了這一點。事實上,如果你想創建接口/契約來提高可擴展性,那麼當你只提供一個抽象類時,那些想要創建它們的實現的開發者即使不想要,也被迫使用這個抽象類。這是不可取的。
您使用強制您使用接口的庫。例如,在EJB 3.0和Spring的第一個版本中,使用抽象類或類不允許從其某些功能中受益。
其實際使用這種接口的良好做法。在接口上查找一些信息。 –
好習慣????對於API類是的,否則,只是開銷。 – davidxxx
@davidhxxx這正是我在想太多.. –