【问题标题】:Marker Interface vs Enums标记接口与枚举
【发布时间】:2021-07-12 03:57:57
【问题描述】:

我正在尝试为动物园建模。

假设我在动物园的区域有以下结构(省略了一些细节)

public abstract class AnimalHabitat{

   private ArrayList<Animal> animals = new ArrayList<>();

   public void setAnimal(Animal animal) {
      animals.add(animal)
   }
}
public class Enclosure extends AnimalHabitat{}
public class Aquarium extends AnimalHabitat{}
public class Cage extends AnimalHabitat{}

那么我有以下动物结构

public abstract class Animal{}
public class Lion extends Animal{}
public class Zebra extends Animal{}
public class Shark extends Animal{}
public class Starfish extends Animal{}
public class Parrot extends Animal{}
public class Eagle extends Animal{}

我想将动物添加到其相应的适当栖息地。为了简化代码,我想使用标记接口,例如

public interface TerrestrialAnimal{}
public class Lion extends Animal implements TerrestrialAnimal{}
public class Zebra extends Animal implements TerrestrialAnimal{}

然后我就可以了

public class Zoo{

   public boolean addAnimal(AnimalHabitat habitat, Animal animal) {
      if (animal instanceOf TerrestrialAnimal && habitat instanceOf Enclosure) {
         habitat.set(animal);
         return true;
      }
      if (animal instanceOf AquaticAnimal && habitat instance of Aquarium) {
          habitat.set(animal);
          return true;
      }
      // So for aerial
   }
}

然而另一种方法是使用枚举。例如假设我有

public enum AnimalType{
   Terrestrial, Aquatic, Aerial;
   
   //getter
}

然后在我可以定义的Animal抽象类中

public abstract class Animal{
   private AnimalType type;
   // Initialise in the constructor depending on the animal instance
}

我会在 Zoo 的 addAnimal() 方法中做同样的事情。

每种方法的优缺点是什么?谢谢!

【问题讨论】:

  • 在事物数量有限的情况下使用枚举。动物和栖息地(实际上)有无限多的东西,所以不能用枚举很好地建模。

标签: java oop enums interface


【解决方案1】:

我会使用枚举。您不需要所有这些 if 语句。

只需在AnimalAnimalHabitat 中都有type 属性,然后比较它们。

if (animal.getType() == habital.getType()) { // can add to habitat

如果您想在特定于动物类型的接口中添加一些方法,请切换到接口。

【讨论】:

  • 该死的太干净了!这实际上是一个作业,所以我无法在截止日期(昨天)之前发布问题:) 感谢您的回答!
【解决方案2】:

枚举

优点

  • 易于扩展:您可以轻松增加价值
  • 更简洁:您只需一个文件即可定义所有 AnimalType
  • 更具可读性:绝对可读
  • 更灵活:您可以在 Enum 上定义方法,并且可以使用枚举值打印 AnimalType
  • Comparable:您可以进行简单的比较,而不是使用 instanceof

使用枚举方法我没有发现任何缺点。

界面

专业人士

  • 方法:您可以定义常用方法签名
  • 您可以在同一个 Animal 中使用 2 个接口(一个动物可能有更多的栖息地?或者更多的类型?)
  • 您可以在集合/类变量中使用接口作为超类型

缺点

  • 昂贵:绝对昂贵,每种类型一个接口

在您的示例中,我更喜欢 Enums,因为您使用接口来定义动物类型,并且可以使用 Enums 轻松完成。如果您需要定义通用方法签名或希望使用接口作为超类型,请使用接口,如下所示:

List&lt;TerrestrialAnimal&gt; terrestrialAnimal = new ArrayList&lt;&gt;();可以包含所有陆生动物。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 2017-07-09
    • 2021-12-22
    • 2021-06-29
    • 1970-01-01
    相关资源
    最近更新 更多