Java 编写同时涵盖终端和2D UI的界面的最佳方法

Java 编写同时涵盖终端和2D UI的界面的最佳方法,java,Java,Java8:我想创建一个接口,如下所示: public interface Ui { abstract static void homeScreen(); abstract static void exitSplash(); } 但我有错误: error: illegal combination of modifiers: abstract and static abstract static void homeScreen(); 对于静态无效摘要: error: &

Java8:我想创建一个接口,如下所示:

public interface Ui {
    abstract static void homeScreen();
    abstract static void exitSplash();
}
但我有错误:

error: illegal combination of modifiers: abstract and static
    abstract static void homeScreen();
对于
静态无效摘要

error: <identifier> expected
        static void abstract homeScreen();

正如您链接的文章中所述,静态方法属于指定它们的类,而不是对象,因此不能被重写。 在接口中使用静态方法的原因是支持抽象方法的默认实现

为类指定一个run方法,并在主方法中创建该类的实例

public static void main(String[] args{
     // create an instance of TestGameScreen2
     TestGameScreen2 tgs = new TestGameScreen2(); 
     // do whatever you want inside a start() method you define.
     tgs.start();
}

在java中,为了获得一个全局实例,单例模式最好不要使用带有静态方法的类

接口不能有静态接口。在java中不能重写静态方法


只要使用这种方法,业务逻辑就可以从GUI resp中分离出来。控制台(视图)。也许你想从这里开始。

为什么不能将方法同时定义为
static
abstract

error: <identifier> expected
        static void abstract homeScreen();
abstract
方法需要实现(通过继承)<代码>静态成员属于该类,删除继承意图。不能重写
静态
方法,只能将其隐藏

您肯定是在强制采用“非面向对象”方法。没有理由为此需要
静态

短期对象在面向对象代码中非常常见。堆的结构专门用于处理具有不同生存期的对象。启动/欢迎屏幕就是这样一个很好的例子,只存在很短的时间


至于您的设计,我看到您担心应用适当的OOP设计原则。以下是我能够指出的一些缺陷:

:将启动和结束启动的代码推送到UI类型中,使UI负责启动。您应该通过允许
SplashScreen
类型来处理此类事件,从而降低责任。然后,您可以让UI请求一个SplashScreen:

abstract class UI {
    private SplashScreen splash;

    public UI(SplashScreen splash) {
        this.splash = splash;
    }

    public void start() {
        splash.start();
        init();
        splash.end();
    }

    public abstract void init();
}
init
用作模板方法,允许实现在启动期间自行初始化。通过将splashscreen的代码移动到另一个对象中,我们降低了UI的责任。除此之外,您还可以通过传递不同的
SplashScreen
实现(遵守规则)轻松切换启动屏幕,而无需修改类

:并非所有UI都有启动屏幕。这意味着一些实现可能不使用
startSplash
exitSplash
。相反,您应该隔离接口。创建不同的抽象:一个支持splash,一个不支持:

abstract class UI {
    public abstract void start();
}

abstract class SplashableUI {
    private SplashScreen splash;

    public SpashableUI(SplashScreen splash) {
        this.splash = splash;
    }

    public final void start() {
        splash.start();
        init();
        splash.end();
    }

    public abstract void init();
}
接口很好,但它们只能抽象行为,不能抽象状态。设计时考虑可伸缩性。您可能希望向UI类型添加一些共享状态。这将迫使您重构它的所有实现,以便将其转换为抽象类

就我个人而言,我使用接口通过行为弥合不同类型层次结构之间的差距。例如:

              Entity
            /           \
Humanoid    Animal
         |               /     \
   Human    Bird    Fish
Human
Fish
分为两个不同的类型层次结构。但是他们都能游泳。如果我们想要一个
SwimmingPool
类,它可以接受任何可以游泳的东西,我们有3个选项:

  • 声明可以在游泳池中游泳的所有类型(
    accept(Person)
    accept(Fish)
    ,等等…)。但这是不可伸缩的
  • 创建一个
    SwimmableEntity
    类型。但是我们需要
    非对称性
    。除此之外,我们还需要
    SwimmableAnimal
    NonSwimmableAnimal
    。。。您将拥有一组非常相似的接口,创建比需要更多的类型层次结构
  • Fish
    Human
    实现一个
    Swimmable
    界面,然后允许
    swimingpool
    接受该类型的对象

  • 对不起,不是真的。这就是为什么我的问题的第一个字符是“Java8”:你不能有一个
    抽象的
    静态的
    (忘记了Java8的更新)的方法,你认为这可能是事实。那么,如果它不是抽象的,它一定有一个主体?这似乎很愚蠢,因为添加方法体有点违背了接口的概念。如果我想要一个带有主体的方法,我会在类中编写它。很多人认为,向接口添加默认/静态方法会扼杀接口的想法(Java 9中的私有方法更是如此)。但是抽象方法需要实现(通过继承)<代码>静态
    成员属于该类,删除继承意图。你不能重写一个
    static
    方法,只能隐藏它。但是如果我删除static修饰符,我将不得不实例化实现类。这看起来不那么整洁(参见我的课堂示例)。实例化类比不实例化类更常见吗?就像我说的,我想知道我是否反对OOP:)是的。接口不应在静态上下文中使用。OK。我一直认为实例化是绝对适合的,例如
    类学生(字符串名…
    (有很多东西,肯定是一个对象)。少一点,更抽象,只是其中之一。但正如另一张海报所说,也许我应该读一读关于辛格尔顿的书,我以前见过辛格尔顿。我会仔细考虑的,谢谢。