假設我有以下課程:
public abstract class Crop {
}
public abstract class Fruit extends Crop {
}
public interface Edible /* ALWAYS IMPLEMENTED BY A CROP */ {
}
public class Apple extends Fruit implements Edible /* BOTH A CROP AND EDIBLE */ {
}
public class Holly extends Fruit /* NOT EDIBLE */ {
}
public class Wheat extends Crop implements Edible {
}
現在,我想確保每個Edible
(介面)都是一個Crop
(類)。
為什么我不能說:
public interface Edible implements Crop {
}
所以它Edible
本身只能由擴展的類來實作Crop
?
是否有解決方法,尤其是在Edible
作為需要的通用引數傳遞時Crop
?
uj5u.com熱心網友回復:
限制哪些類可以實作介面的唯一選擇是使用密封介面(在 Java 17 中引入),它限制了哪些類可以繼承它。但是,您的用例存在“問題”,即并非所有作物都可以食用,這使事情變得復雜。
從表面上看,你的問題是無法解決的,除非你想明確列出介面中所有可能的類。
例如,您的問題可以像這樣解決
public sealed interface Edible
permits Apple, Wheat {
}
public abstract class Crop {
}
public abstract class Fruit extends Crop {
}
public final class Apple extends Fruit implements Edible /* BOTH A CROP AND EDIBLE */{
}
public class Holly extends Fruit /* NOT EDIBLE */ {
}
public final class Wheat extends Crop implements Edible {
}
您可以通過使用以下內容來放松一些約束:
public sealed interface Edible
permits EdibleFruit, Wheat {
}
public abstract class Crop {
}
public abstract class Fruit extends Crop {
}
public non-sealed abstract class EdibleFruit extends Fruit implements Edible {
}
public class Apple extends EdibleFruit /* BOTH A CROP AND EDIBLE */{
}
public class Holly extends Fruit /* NOT EDIBLE */ {
}
public final class Wheat extends Crop implements Edible {
}
但這可能導致復雜的層次結構(例如,考慮到可食用水果的某些子型別不可食用)。
以不同方式處理可能更有意義,例如檢查可食用性或毒性,或最大安全劑量,或類似的東西。
uj5u.com熱心網友回復:
您不能在介面上實作 Java 類。介面只能是extend
其他介面。因此,通過這種方式,您可以宣告另一個介面(并在 上實作它Crop
)。然后,您可以在Editable
.
這可能是這樣的:
public abstract class Crop implements NewInterface{
}
public interface Edible extends NewInterface {
}
uj5u.com熱心網友回復:
為什么不約束Edible
?
interface Edible<T extends Crop> {}
因此,如果它是子類,則每個可食用的東西都必須實體化介面Crop
:
class A extends Crop implements Edible<A> {} // Ok
class B implements Edible<B> {} // Bad
至少每個都Edible
需要用一個類來實體化Crop
。但是你可以做一些奇怪的事情,比如:
class C implements Edible<A> {}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/477876.html
上一篇:使用系結函式進行柯里化并在TypeScript中使用泛型正確鍵入
下一篇:變數、常量、作用域(Java)