-1

对不起,如果我的问题有点不清楚;我发现很难找到措辞。我花了几个小时在 Eclipse 中玩转,浏览 JavaDoc、Google 以及 SO。我学到了很多,但没有找到答案。

我想做的是定义一个枚举,例如:

public enum Animals {
    Cow,
    Chicken,
    Sheep,
    Horse;
}

并让每个枚举常量定义一个非本地类的可实例化类。下面的工作吗?如果不是,为什么,会怎样?

在某些文件中:

abstract public class Animal {

    private String nameString;

    public String getName() {
        return nameString;
    }

}

在另一个:

public enum Animals {

    Cow ((new Animal() {
        private boolean hasMilk;
        {
            nameString = "Cow";
            hasMilk = false;
        }
        public boolean hasMilk() {
            return hasMilk;
        }
    }).getClass()),

    Chicken ((new Animal() {
        private boolean hasFeathers;
        {
            nameString = "Chicken";
            hasFeathers = true;
        }
        public boolean hasFeathers() {
            return hasFeathers;
        }
    }).getClass()),

    Sheep ((new Animal() {
        private boolean isShorn;
        {
            nameString = "Cow";
            isShorn = false;
        }
        public boolean isShorn() {
            return isShorn;
        }
        public void Shear() {
            isShorn = true;
        }
    }).getClass()),

    Horse ((new Animal() {
        {
            nameString = "Cow";
        }
    }).getClass());


    private Class<? extends Animal> animalClass;

    private Animals(Class<? extends Animal> a) {
        animalClass = a;
    }

    public Class<? extends Animal> getAnimalClass() {
        return animalClass;
    }
}

然后,在其他类的其他方法中,能够做到这一点:

Animal farmAnimal;
farmAnimal = Animals.Sheep.getAnimalClass().newInstance();
boolean shorn = farmAnimal.isShorn();

(此时此刻的价值shornfalse

farmAnimal.shear();
shorn = farmAnimal.isShorn();

( shorn == true)

farmAnimal = Animals.Sheep.getAnimalClass().newInstance();
shorn = farmAnimal.isShorn();

( shorn == false)

显然,这不是我在这里所做的最好的方法,但这不是重点。我知道我可以为枚举常量指定行为,但这并不能使它们作为不同的实例多次实例化。我希望能够创建各种枚举常量的多个实例(或副本),具有不同的实例变量(以及不同数量/类型的实例变量),具有不同的访问器方法,然后我可以对其进行处理(更改实例变量)无需修改枚举常量。

我知道枚举常量被设计为不可变的。这与我的想法并不冲突;我希望每个枚举常量都代表一个可变类的不可变定义。

4

1 回答 1

2

你可以这样做:

public enum AnimalType {
    COW {
        @Override
        public Animal createNew() {
            return new Cow();
        }
    },
    HORSE {
        @Override
        public Animal createNew() {
            return new Horse();
        }
    };

    public abstract Animal createNew();
}

public abstract class Animal {
    private final AnimalType type;
    private final String nameString;

    public Animal(final AnimalType type, final String nameString) {
        super();
        this.type = type;
        this.nameString = nameString;
    }

    public String getName() {
        return nameString;
    }

    public AnimalType getType() {
        return type;
    }
}

public class Horse extends Animal {
    public Horse() {
        super(AnimalType.HORSE, "Horse");
    }
}

public class Cow extends Animal {
    private boolean milk;

    public Cow() {
        super(AnimalType.COW, "Cow");
    }

    public boolean hasMilk() {
        return milk;
    }

    public void setMilk(final boolean milk) {
        this.milk = milk;
    }
}

@Test
public void testEnum() {
    Cow cow = (Cow) AnimalType.COW.createNew();
    Horse horse = (Horse) AnimalType.HORSE.createNew();

    System.out.println("cow  : " + cow.getType() + ", has milk: " + cow.hasMilk());
    System.out.println("horse: " + horse.getType());
}
于 2012-07-07T08:44:04.677 回答