Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的类C枚举_Java_C++_Arrays_Enums - Fatal编程技术网

Java中的类C枚举

Java中的类C枚举,java,c++,arrays,enums,Java,C++,Arrays,Enums,为了在C++中提供以下便利,我正在尝试找到一个Java等价物: enum { ANIMAL_CAT = 0, ANIMAL_RAT, ANIMAL_BAT, ... NUM_ANIMALS }; Animal animals[NUM_ANIMALS]; animals[ANIMAL_CAT].mNumLegs = 4; animals[ANIMAL_RAT].mNumLegs = 4; ... 我知道这不是世界上最漂亮的东西,但我可以在枚举的任何地方添加一个新的ANIMAL

为了在C++中提供以下便利,我正在尝试找到一个Java等价物:

enum {
  ANIMAL_CAT = 0,
  ANIMAL_RAT,
  ANIMAL_BAT, ...
  NUM_ANIMALS
};

Animal animals[NUM_ANIMALS];

animals[ANIMAL_CAT].mNumLegs = 4;
animals[ANIMAL_RAT].mNumLegs = 4; ...
我知道这不是世界上最漂亮的东西,但我可以在枚举的任何地方添加一个新的ANIMAL_xxx,下面的所有条目都会自动调整。在Java中有没有一种干净的方法可以做到这一点


谢谢你的回答,但我可能暗示了比我预想的更简单的问题

我正在做一个游戏,里面有一个物理、人工智能引擎等。我试图整合每种实体类型所需的所有信息(有些实体只有物理显示,而有些实体同时有物理和人工智能等),以便我可以轻松添加/修改类型(因此,动物是一个坏例子,因为我可能需要岩石、植物等)

我使用一个类来存储类型信息,而其他类依赖该类来查找属性(维度、位图索引、hasAi等)。最后,我尝试清理类似于以下内容的内容,同时允许我轻松添加新类型:

class UnitTypeInfo {
  UnitTypeInfo() {
    mTypes = new TypeInfo[NUM_TYPES];

    // and allocate...

    // initialize TypeInfos here
    mTypes[TYPE_CAT].mType = TYPE_CAT;
    mTypes[TYPE_CAT].mMass = 10.0f;
    mTypes[TYPE_CAT] ...

    mTypes[TYPE_ROCK].mType = TYPE_ROCK;
    ...
  }

  public class TypeInfo {
    public int mType;
    public int mRawResourceHandle;
    public float mMass;
    public Vector2d mDimensions;
    public float mHealth;
    public boolean mHasAi;
    ...
  }

  public static final int TYPE_CAT = 0;
  public static final int TYPE_ROCK = 1;
  public static final int TYPE_TREE = 2; ...
  public static final int NUM_TYPES = ???; // the last TYPE_ + 1

  public TypeInfo mTypes[];
}
现在看来,某种XML实现可能是“正确”的做法,但我不确定如何做到这一点(Java新手)。无论如何,其他类可以很容易地使用unitTypeInfo.mTypes[unitTypeInfo.TYPE\u CAT].mMass(实例化)来查找CAT的质量。但是,如果我想在TYPE_CAT定义下面添加一个TYPE_DOG,我必须更新它下面的所有内容(lazy,我知道,但是让我们想想还有一些类型。)

枚举提供了C++中这个问题的简单解决方案,但是在Java中,我现在可以解决的最简单的解决方案需要类似的东西:UNITType信息。MyType(UNITType信息。MyType No.Engyjava。它确实增加了相当多的间接性和实际的方法调用(对于大多数源代码似乎不鼓励的方法)

还有一件事是,我希望能够调用一个开关(类型),因此这也可能会限制可能的解决方案

无论如何,我开始有了一个想法,那就是必须有一个更好的办法来解决整个问题。有什么建议吗?

“经典”java在这种情况下总是使用“static final int ANIMAL\u CAT=0”

JDK 1.5引入了“类型安全枚举”:

您现在可以这样做(一种非常常见的做法):

或者您可以这样做:

/**
  * Example 2 - adding a constructor to an enum.
  *
  * If no constructor is added, then the usual default constructor
  * is created by the system, and declarations of the
  * enum constants will correspond to calling this default constructor.
  */
  public enum Lepton {
    //each constant implicity calls a constructor :
    ELECTRON(-1, 1.0E-31),
    NEUTRINO(0, 0.0);

    /* 
    * This constructor is private.
    * Legal to declare a non-private constructor, but not legal
    * to use such a constructor outside the enum.
    * Can never use "new" with any enum, even inside the enum 
    * class itself.
    */
    private Lepton(int aCharge, double aMass){
      //cannot call super ctor here
      //calls to "this" ctors allowed
      fCharge = aCharge;
      fMass = aMass;
    }
    final int getCharge() {
      return fCharge;
    }
    final double getMass() {
      return fMass;
    }
    private final int fCharge;
    private final double fMass;
  }
以下是官方文件:

为什么不简单地说:

public enum Animal {
    CAT(4), RAT(4), BAT(4), CHICKEN(2), ..., ANT(6), SPIDER(8);

    // A simple attribute, like any other java class.
    // Final to ensure it will never change.
    private final int legs;

    // Note that this constructor is private.
    private Animal(int legs) {
        this.legs = legs;
    }

    // A method, like any other class.
    public int getLegs() {
        return legs;
    }
}
要使用它:

// How to get all the animals in the enum.
Animal[] animals = Animal.values();

// How to get the number of animals.
int numAnimals = animals.length;

// How to get the number of legs of some animal.
int howManyLegsHaveTheAnt = Animal.ANT.getLegs();
int howManyLegsHaveTheFirstAnimal = animals[0].getLegs();

// How to get the name of a given animal.
String theFirstAnimalName = animals[0].name(); // Will return "CAT".

// How to get the position in the enum of some animal.
int antPositionInTheEnum = Animal.ANT.ordinal();

// How to get an animal given its name.
Animal rat = Enum.valueOf(Animal.class, "RAT");
Animal someAnimal = Enum.valueOf(Animal.class, animalName);

在您的情况下,使用枚举不是一个好主意。枚举本质上是不可变的,是一个固定的集合,在这个集合中,不可能发明新的元素,也不可能破坏现有的元素。工作日、月份和卡片套装是枚举的一个很好的例子,现有的集合是固定不变的,不会创建新元素,也不会销毁现有元素。动物类型、音乐类型、瓷砖等不遵循这些规则

更好的是最明显的:定义一个接口或抽象类。并将所有动物类型定义为一个子类型

开关就像goto一样邪恶,它们简单,易于使用,看起来很无辜,但最终会在意大利面条丛林中转换代码。不要使用您想要的开关,而是使用多态性。即:

// Don't:
public class SomeClass {
    public void myMethod() {
        switch (animal.id) {
            case TYPE_CAT:
                doSomethingThatCatDoes();
                doSomethingElse();
                anotherThing();
                break;

            case TYPE_DOG:
                bark();
                doSomethingThatDogDoes();
                otherThing();
                break;
        }
    }
}
当您这样做时,代码往往会变得更大,但这并不意味着更复杂。相反,它变得更有条理,因为SomeClass不再需要知道确切的动物类型,每个动物类型的特定逻辑都在一个地方,如果你需要改变动物的行为,你就不需要搜索和改变很多非常遥远的地方。此外,添加新的动物类型变得更加容易。正如您应该看到的,您的项目对于未来的更改变得更加灵活(即,更容易更改,更难中断)


您应该注意,我没有使用显式ID。避免使用ID,因为它们是恶意的,并且您已经拥有了它们。每个对象都有一个唯一的内存地址,该内存地址就是id字段将成为一个
公共类简单的答案:没有Java没有类C的枚举。尽管通过如下一系列语句可以在java中实现这一点:

public static final int GREEN = 1;
public static final int RED   = 2;
public static final int BLUE  = 3;

Java枚举是不同的。

这里的相关问题可能会有所帮助:没有理由一开始就拥有一个所有枚举的数组——Java的枚举是它最好的特性之一,在C++/C中,我总是很遗憾地错过它,在C++/C中,它只是围绕着“int”的语法糖。虽然在这种特殊情况下,我不会首先使用枚举,而是使用类-似乎是更好的体系结构(尽管这可能取决于确切的用法等…)+1来选择示例。但是你应该注意,因为轻子。中微子可能比光速快。谢谢你的回答,但我可能暗示了比我预想的更简单的东西。Java是一种冗长的语言。java中的简单性并不意味着代码小。相信它,这个代码很简单。此外,我已经阅读了你对这个问题的编辑,这把它变成了一个非常不同的问题,所以我将发布另一个答案。
// Do:
public interface Animal {
    public void myMethodAction();
    // Other methods.
}

public class Cat implements Animal {
    @Override
    public void myMethodAction() {
        doSomethingThatCatDoes();
        doSomethingElse();
        anotherThing();
    }
}

public class Dog implements Animal {
    @Override
    public void myMethodAction() {
        bark();
        doSomethingThatDogDoes();
        otherThing();
    }
}

public class SomeClass {
    public void myMethod() {
        animal.myMethodAction();
    }
}
public static final int GREEN = 1;
public static final int RED   = 2;
public static final int BLUE  = 3;