Java 状态模式具有不同的实现,导致难以理解的错误

标签 java polymorphism abstract-class

为什么这个java代码不起作用。

abstract class Actor {
    Actor a = new HappyActor();
    abstract void act();
    void change() { a = new SadActor(); }
    void go() { a.act(); }
}

class HappyActor extends Actor {
    public void act() {
        System.out.println( ":)" );
    }
}

class SadActor extends Actor {
    public void act() {
        System.out.println( ":(" );
    }
}

public class TransmogrifyMe {
    public static void main( String[] args ) {
        Actor s = new HappyActor();
        s.go(); // Prints ":)"
        s.change();
        s.go(); // Prints ":("
    }
}

这是我对流行的状态模式的修改,但不幸的是没有工作: 抽象类中的赋值语句在继承它的类的每个构造函数的开头调用。因此,赋值语句尝试创建派生类的对象。即,当调用 HappyActor 类的构造函数时,会调用 Actor a = new HappyActor() ,这会导致构造函数调用永无止境的循环。这真的是正在发生的事情吗?

工作版本如下代码所示:

abstract class Actor {
    abstract void act();
}   

class HappyActor extends Actor {
    public void act() {
        System.out.println( ":)" );
    } 
}   

class SadActor extends Actor {
    public void act() {
        System.out.println( ":(" );
    } 
}   

class Stage {
    Actor a = new HappyActor();
    void change() { a = new SadActor(); }
    void go() { a.act(); }
}   

public class Transmogrify {
    public static void main( String[] args ) {
        Stage s = new Stage();
        s.go(); // Prints ":)"
        s.change();
        s.go(); // Prints ":("
    }
}

第一个代码中产生的错误消息是这两行的无休止循环:

at Actor.<init>(TransmogrifyMe.java:6)
at HappyActor.<init>(TransmogrifyMe.java:12)

是否可以使用继承来实现这种状态更改。我在 Bruce Eckel 的书 Thinking in Java 中找到了这一点 相反,你不能在运行时决定以不同的方式继承;必须在编译时完全确定

最佳答案

去掉类变量。您的方法应如下所示:

State doSomething() {
  // do something, e.g. println.
  return new NextState();
  // or return this to stay in the current state.
}

然后它们的使用方式如下:

state = state.doSomething();

即您返回下一个状态。

例如

class HappyState implements State {
  public State change() {
    return new SadState();
  }
}

关于Java 状态模式具有不同的实现,导致难以理解的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29234437/

相关文章:

c# - 更改继承类中的抽象方法签名

c++ - ADT - 迭代器 - 运算符++

java - JPanel的自定义绘画

java - 子类中是否存在父类(super class)构造函数(但不被继承)?

java - 在多态性问题上需要帮助

C++ 无法实例化抽象类子类

java - 在java swings中我可以在 Canvas 上画 Canvas 吗?

java - 在 JTable 中使 JButton 可点击

java - 在 Java 中捕获全局按键

java - 显式向下转型和向上转型之间的区别