Java8:我想创建一个接口(interface)如下:
public interface Ui {
abstract static void homeScreen();
abstract static void exitSplash();
}
但是我得到错误:
error: illegal combination of modifiers: abstract and static
abstract static void homeScreen();
对于static void abstract
:
error: <identifier> expected
static void abstract homeScreen();
我希望能够创建一个具有上述方法的类,我可以在其中编写自己的方法体,但它们是static
,因为我不需要在其中创建对象为了显示主屏幕或退出启动画面(当然我没有 - 或者我无知地试图强制使用非 OOP 方法?)。
我不想向接口(interface)方法添加参数,因为想象两个实现 -
- 基于文本的用户界面,以及
- 二维用户界面。
他们有什么共同点?一个将全是 Swing 或等效物,另一个将与 Swing 无关。
这里有两个问题:
我认为这真的归结为我不了解基础知识。毫无疑问,有人会指责我“没有掌握 OOP 编程的基础知识”。但是我读过——相当多的书——但是当我尝试将事情付诸实践时,它只需要——练习! 关于接口(interface)方法描述的
abstract
、static
等的允许/不允许组合,有人可以为我指出正确的方向吗?如何为不带参数的静态类方法创建接口(interface)方法。不可能吧!?那么我该如何解决我想要一个 UI 界面的小问题,它可以最好地涵盖终端和 2D UI?放弃并实例化类>我为什么要这样做?
注意:这是我想构建一个接口(interface)来覆盖的(测试)类。我喜欢它现在的样子,使用静态方法:
import java.io.IOException;
import jline.console.ConsoleReader;
class TestGameScreen2 implements Ui {
private static ConsoleReader con;
public static void homeScreen() {
try {
con.setPrompt("AwesomePrompt> ");
Screen.clear();
System.out.println("Press any key to continue...");
con.readCharacter();
Screen.clear();
System.out.println("Here is a prompt. Do something and press enter to continue...");
String line = con.readLine();
Screen.clear();
System.out.println("You typed: ");
System.out.println(line);
System.out.println("Press any key to exit. ");
con.readCharacter();
Screen.clear();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void exitSplash() {
System.out.println("Thank You. Goodbye.");
System.out.println("");
}
public static void main (String argv[]) {
try {
con = new ConsoleReader();
homeScreen();
exitSplash();
} catch (IOException e) {
e.printStackTrace();
}
}
最佳答案
不能将一个方法同时定义为static
和 abstract
的原因:
abstract
methods require implementation (via inheritance).static
members belong to the class, removing intentions of inheriting. You cannot override astatic
method, only hide it.
您绝对是在强制使用“非 OOP”方法。没有理由为此需要 static
。
短期对象在面向对象代码中很常见。堆的结构专门用于处理具有不同生命周期的对象。启动画面/欢迎画面就是一个很好的例子,只存在很短的一段时间。
至于您的设计,我看到您担心应用正确的 OOP 设计原则。以下是我能够指出的一些缺陷:
Single Responsibility :将启动和结束启动代码放入 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
用作模板方法,允许实现在启动过程中自行初始化。通过将启动画面的代码移到另一个对象中,我们降低了 UI 的责任。除此之外,您可以通过传入不同的 SplashScreen
实现(遵守 open/close principle)轻松切换启动画面,而无需修改类。
Interface Segregation :并非所有 UI 都有启动画面。这意味着某些实现可能不会使用 startSplash
和 exitSplash
。相反,您应该隔离接口(interface)。创建不同的抽象:一种支持飞溅,一种不支持:
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();
}
接口(interface)很好,但是只能抽象行为,不能抽象状态。设计时要考虑可扩展性。您可能希望向您的 UI 类型添加一些共享状态。这将迫使您重构它的所有实现,以便将其转换为抽象类。
就个人而言,我使用接口(interface)通过行为来弥合不同类型层次结构之间的差距。例如:
Entity
/ \
Humanoid Animal
| / \
Human Bird Fish
Human
和 Fish
分为 2 个不同的类型层次结构。但他们都可以 swim()
。如果我们想要一个接受任何可以游泳的东西的 SwimmingPool
类,我们有 3 个选项:
- 在
SwimmingPool
类中声明所有可以游泳的类型(accept(Person)
、accept(Fish)
等...) .但这不可扩展 - 创建一个
SwimmableEntity
类型。但是我们需要NonSwimmableEntity
。最重要的是,我们需要SwimmableAnimal
和NonSwimmableAnimal
...您将拥有一堆非常相似的接口(interface),创建比需要更多的类型层次结构。 - 让
Fish
和Human
实现一个Swimmable
接口(interface),然后允许SwimmingPool
接受该类型的对象。
关于java - 编写界面以涵盖终端和 2D UI 的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33723522/