Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.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 在抽象类中的默认函数中使用类字段_Java_Software Design - Fatal编程技术网

Java 在抽象类中的默认函数中使用类字段

Java 在抽象类中的默认函数中使用类字段,java,software-design,Java,Software Design,我正在尝试建立一个可以占据三个州的类。在这三种状态下,对象的行为将完全不同。我不能简单地为此创建三个类,因为对象将在状态之间转换,并且我无法控制类的初始化方式。所有这三个状态必须在一个类定义下运行 现在,从当前开始,我将执行以下操作 enum ServerType { primary, backup, idle } class ImportantClass { State myState; // Other fields void commonCla

我正在尝试建立一个可以占据三个州的类。在这三种状态下,对象的行为将完全不同。我不能简单地为此创建三个类,因为对象将在状态之间转换,并且我无法控制类的初始化方式。所有这三个状态必须在一个类定义下运行

现在,从当前开始,我将执行以下操作

enum ServerType {
    primary,
    backup,
    idle
}
class ImportantClass {
   State myState;

   // Other fields

   void commonClassFunc() {
     if (state == idle) {
       idleFoo();
     } else if (state == primary) {
       primaryFoo();
     }
     ....
   }

   // Helper functions for State primary
   void primaryFoo() {
     // Access and mutate fields
   }
   ...

   // Helper functions for State backup
   void backupFoo() {
     // Access and mutate fields
   }
   ...

   // Helper functions for State idle
   void idleBar() {
     // Access and mutate fields
   }
   ...

}
您可以看到这将如何导致一个非常大的类定义,其中特定于状态的部分将仅由注释分隔

我的目标是以更雄辩的方式做到这一点。 例如,我可以创建一个主类、备份类和空闲类,并让ImportantClass保存其中一个类,但这将不允许这些方法访问公共字段。我想使用一些接口,这些接口允许我像
类ImportantClass实现Primary{}
一样,但不幸的是,即使我可以在这个接口中定义primaryFoo方法,该方法仍然无法访问ImportantClass的字段


你知道我有什么方法可以构造这段代码,这样我就可以在仍然访问ImportantClass的字段时中断ImportantClass切换的这三种状态的行为了吗?

我的一般感觉是,也许你应该在与三个国家:

public class ImportantClass {
    private State myState;

    // other common metadata + getters and setters
}

public class PrimaryClass extends ImportantClass {
    // fields specific to this class

    // Helper functions for State primary
    private void primaryFoo() {
    }
}
以此类推,为其他两个州设置类


三个子类中的每一个子类虽然不能直接访问私有父类
ImportantClass
状态,但至少能够调用getter和setter来访问和修改该状态。这里的基本思想是将不属于一起的行为(读取:方法)移动到单独的类中。

解决此问题的一个选项如下: 创建一个新类(例如
ImportantInfo
)来保存在状态之间共享的字段:您希望从
ImportantClass
和状态访问的公共字段。
然后,您可以根据需要为每个状态创建类,并使它们采用
ImportantInfo
作为构造函数参数,每个方法都可以对这些字段进行操作。因此,
ImportantInfo
的属性应该具有公共访问权限。但是,您没有破坏封装,因为您可以将
ImportantInfo
实例设置为私有。
为了在与当前状态相关的所需操作之间切换,您应该拥有使操作从公共抽象类继承的类。例如,
StateImplementor
是一个抽象类,它是由
ImportantInfo
对象构造而成的,而
IdleImplementor
PrimaryImplementor
等都是子类
StateImplementor
将有一个在这些类中实现的抽象方法
Foo
。要在实现之间切换,您应该在
ImportantClass
中有一个
currentImplementor
对象,并进行如下切换:

void switchState(ServerType newState) {
    if (newState == ServerType.Idle)
        this.currentImplementor = new IdleImplementor(this.importantInfo);
}

我大体上完全同意。我唯一的问题是我不负责这里的初始化。有一个框架可以做到这一点,据我所知,我不能强迫超类构造函数作为子类构造,或者从一个子类切换到另一个子类。在某种程度上,类同时也是所有三种状态。同一个对象在改变状态时如何在这些类之间切换?你是对的,我将编辑我的答案来解释这一点。@TheJavatar,如果需要访问已经存在的实例怎么办?@Maria如果你愿意,在创建
ImportantClass
时,可以为每个实现者创建一个实例。然后,您可以在更改状态时在这些实例之间切换,这样就不必为每个状态创建多个对象。