[英]Extending a non abstract class and implementing an interface with same method signatures in a class
[英]method with multiple class implementing same interface
我有一個界面:
public interface I {
getBar();
}
我有 2 class: A
和B
實現I
。
我想做的是:
public void foo(List<I> items) {
for (I item : items){
if (item instanceof A) this.append((A) item);
if (item instanceof B) this.append((B) item);
}
}
有沒有 java 8 的東西可以讓我沒有那個instanceof
列表並這樣稱呼它?
items.foreach(this::append);
注意:我可以做一些像item.add(this)
這樣的事情,它會 append 本身到this
但是然后我會在 object 上調用一個方法來修改參數(並且只有它)但是正如 Robert C 所述,這是不好的做法。馬丁的“清潔代碼”:
Arguments 最自然地被解釋為 function 的輸入。
任何強迫您檢查 function 簽名的行為都等同於雙重考慮。 這是一種認知障礙,應該避免。 在面向 object 的編程之前的日子里,有時需要 output arguments。但是,在 OO 語言中,對 output arguments 的大部分需求都消失了
只需將 instanceof 的東西移動到通用的 append func
private void append(I item) {
if (item instanceof A) ...
if (item instanceof B) ...
}
那么你可以使用
items.foreach(this::append);
如果你采取更多 OOP 方法怎么辦,
interface Appender{ void append(I item); }
for (I item: items){ appenders.getOrDefault(item.class,DEFAULT_APPENDER).append(item); }
你正在考慮它。
您的 class 獲取I
的這些實例,並根據類型具有不同的重載方法。 此重載意味着它需要了解所有實現,以便為每個實現提供不同的重載。
顯然,問題在於列表必須隨着實現的添加而增長。
解決方案是讓I
的實現負責了解它們是如何附加的。
public interface I {
Bar getBar(); /* you missed the return type, but anyway */
void appendTo(SomeType foo);
}
你的方法就變成了
public void foo(List<I> items) {
for (I item : items){
item.appendTo(this); //or instead of this, some append-able instance
}
}
如果有人添加I
的新實現,他們將被迫編寫一個 append 方法作為接口契約的一部分。
實際答案:這是一個雙重調度問題,以 Java 為中心的解決方案是訪問者模式,它有很多變化。
愚蠢的回答:只是為了好玩,這里沒有instanceof
:
private static final Map<Class<?>, Consumer<I>> DISPATCHER = Map.of(
A.class, this::appendA,
B.class, this::appendB
);
items.forEach(i -> DISPATCHER.get(i.getClass()).accept());
是的,它仍然很分支,必須運行更多的指令才能得到相同的結果:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.