0

我对构造函数有一些疑问。

有一个类“Foo”可以创建为三种不同的“状态”,我们可以称它们为“年轻”、“成人”和“老”。

我想强调它们不能被视为不同的类,因为对象会进化,如果它被创建为“年轻”,它将变成“成人”,然后是“老”等等。

我的问题是:如何定义一个或多个构造函数来使这三种类型多样化?

我看到了一些可能性,但没有一个是“优雅”的解决方案。

1)创建一个以 int 为输入的构造函数

public Foo(int i)
{
    switch (i)
    {
         case 0:
         .
         .
         .
         case 1:
         .
         .
         .
         case 2:
         .
         .
         .
    }
}

但我不喜欢它,因为如果其他人看到此代码,则不太清楚。

2)创建一个空白构造函数,然后创建三个不同的方法,如

public Foo()
{

}

public void setYoungFoo()
{
    .
    .
    .
}

public void setAdultFoo()
{
    .
    .
    .
}

public void setOldFoo()
{
    .
    .
    .
}

这可能是解决问题的明确方法,但我会在构造函数中解决这个问题..

3)静态变量在这种情况下有用吗?

public static final String "YOUNG";
public static final String "ADULT";
public static final String "OLD";


public Foo(String field)
{

}

我不知道如何填充这个构造函数,因为我从未使用过静态最终变量(我已经看到它们在一些 Java 类中使用,例如 Calendar,即使没有在构造函数中使用)。

您能否评论这三个选项以强调它们的缺点是什么,因为我很确定它们不是一个好的解决方案。

4

2 回答 2

7

使用方法 1,但使用枚举而不是 int。您甚至可以在类中内联枚举,只需将其设为公共静态即可。

class Foo {
    public static enum fooState {
       young, adult, old;
    }

    public Foo(fooState i) {
        switch(i) {
        case young: ... break;
        case adult: ... break;
        case old: ... break;
        default: throw new InvalidStateException();
    }
    ...
}

编辑:您就您的 3 个选项征求意见,这是我的:

  1. 选项 1 在技术上与我的版本相同,但使用幻数(即没有指定名称的数字),这使得它更难理解(对于其他人和你未来的自己)
  2. 选项 2 在创建对象和调用 set*Foo() 之间使类处于未定义甚至无效状态。如果您可以随时转换到 Young/Adult/Old,则可以选择在构造函数中将 Object 设置为例如 Young 状态,并让用户使用已经必要的功能来切换到另一个状态。如果这是一个不错的选择,则取决于具体情况,但它是一个有效的选择。
  3. 选项 3 与选项 1 基本相同,只是速度较慢,因为它涉及字符串比较。如果您调用“new Foo(Foo.YOUNG)”,则代码更易于阅读,但您必须以这种方式编写它并不直观。此外,可以编写“new Foo("Alligator")”,这在最好的情况下会产生运行时错误。
于 2013-01-25T22:22:42.707 回答
0

你真的不应该为 Young、Adult 和 Old 三个类,并且它们都可以实现一个通用接口或扩展一个抽象类以将它们联系在一起吗?

在创建所需子类的对象并将其返回的父抽象类中创建一个静态工厂方法?你为什么不想做三个班?它们将从父类的引用类型中引用,因此它们“看起来”像同一个类。

于 2013-01-25T23:18:10.973 回答