简体   繁体   English

接口中的Java实现类

[英]Java implement class in interface

Say I have the following classes:假设我有以下课程:

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 {
}

Now, I want to make sure that every Edible (interface) is a Crop (class).现在,我想确保每个Edible (接口)都是Crop (类)。

Why can I not say:为什么我不能说:

public interface Edible implements Crop {
}

So that Edible itself can only be implemented by classes that extend Crop ?所以Edible本身只能由扩展Crop的类来实现?

Is there a workaround for this, especially when passing Edible as a generic parameter that requires a Crop ?是否有解决方法,尤其是在将Edible作为需要Crop的通用参数传递时?

The only option to restrict what classes can implement an interface is using a sealed interface (introduced in Java 17), which restrict what class can inherit it.限制哪些类可以实现接口的唯一选择是使用密封接口(在 Java 17 中引入),它限制了哪些类可以继承它。 However, your use-case has the "problem" that not all crops are edible, which complicates matters.但是,您的用例存在“问题”,即并非所有作物都可以食用,这使事情变得复杂。

On the face of it, your problem is not solvable, unless you want to explicitly list all possible classes in the interface.从表面上看,你的问题是无法解决的,除非你想明确列出接口中所有可能的类。

For example, your problem could be solved like例如,您的问题可以像这样解决

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 {
}

You could relax some of the constraints by using something like:您可以通过使用以下内容来放松一些约束:

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 {
}

But that could lead to a complicated hierarchy (eg consider that some sub-types of an edible fruit are not edible).但这可能导致复杂的层次结构(例如,考虑到可食用水果的某些子类型不可食用)。

It might make more sense to handle this differently, eg a check on edibility or toxicity, or maximum safe dose, or something like that.以不同方式处理可能更有意义,例如检查可食用性或毒性,或最大安全剂量,或类似的东西。

You cannot implement a Java Class on an Interface.您不能在接口上实现 Java 类。 Interfaces can only extend other interfaces.接口只能extend其他接口。 So, in that way, you can declare another interface (and implement it on Crop ).因此,通过这种方式,您可以声明另一个接口(并在Crop上实现它)。 Then, you can extend this new interface on Editable .然后,您可以在Editable上扩展这个新接口。

This can be something like:这可能是这样的:

public abstract class Crop implements NewInterface{
}

public interface Edible extends NewInterface {
}

Why not constraint Edible ?为什么不约束Edible

interface Edible<T extends Crop> {}

so that every edible must instanciate the interface if it subclass Crop :因此,如果它是Crop的子类,则每个可食用的东西都必须实例化接口:

class A extends Crop implements Edible<A> {} // Ok
class B implements Edible<B> {} // Bad

At least every Edible needs to be instantiated with a class that is a Crop .至少每个Edible都需要用一个Crop类来实例化。 But you can do weird things like:但是你可以做一些奇怪的事情,比如:

class C implements Edible<A> {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM