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. 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 (e.g. consider that some sub-types of an edible fruit are not edible).
It might make more sense to handle this differently, e.g. a check on edibility or toxicity, or maximum safe dose, or something like that.
interfaceextendfrom otherinterfaces ;). Classesimplementinterfacespublic abstract class Crop implements Edible, the reverse is not possible (and wouldn't make sense in a logical sense). If you only want subclasses ofCropto extendEdible, you should probably use sealed classes (Java 17 or higher).public interface Edible implements Cropshould bepublic interface Edible extends Crop