我正在尝试自己创建一个小的lwjgl GUI库。我现在又开始了3次。我的问题是我无法创建一个好的OOP设计。 我查看了Swing和AWT库中内置的Java。 我读了这些代码,并研究了Swing和AWT的类设计。 但我认为这不是为lwjgl创建自己的GUI库的正确方法,因为它有很多不同之处。 我在OO中遇到的最大问题之一是我无法达到某种方法。我认为这是一个普遍的编程问题。例如,我有以下类:
class Container {
private ArrayList<Component> components = new ArrayList<Component>();
public void add(Component c) { // Accepts only Component objects, or child objects of Component
this.components.add(c);
}
public volid paintAll() {
for(int i = 0; i < this.components.size(); i++) {
// Not possible, the Component object has no method paintComponent(), the
// class which extends Component does. This can be a button, but it's stored as
// a Component. So the method paintComponent "Does not exist" in this object,
// but is does.
this.components.get(i).paintComponent(); // error
}
}
}
class Component {
private int x;
private int y;
private int width;
private int height;
/* methods of Component class */
}
class Button extends Component {
private String text;
public Button(String text) {
this.text = text;
}
public void paintComponent() {
/* Paint the button */
}
}
// In Swing, the Component class has no method like paintComponent.
// The container can only reach the methods of Component, and can not use methods of
// classes which extends Component.
// That's my problem. How can I solve this?
Container container = new Container();
Button b = new Button("This is a button");
Container.add(b); // b "Is a" Component.
答案 0 :(得分:2)
您需要确保 Component
的每个子类都有paintComponent()
方法。您可以通过在超类中将其声明为抽象来实现:
abstract class Component {
/* fields of Component class */
public abstract void paintComponent();
}
这将强制Component
的每个非抽象子类实现该方法,否则编译器将产生错误。
Swing做同样的事情:JComponent
有a method paint(Graphics)
。
除此之外:因为Component
已经存在于类的名称中,所以更常见的是命名方法paint()
。这避免了呼叫中的重复,例如myComponent.paint()
代替myComponent.paintComponent()
。
答案 1 :(得分:1)
如果您需要将按钮存储为组件,可以使用instanceof
运算符检查它们是否实际上是按钮,然后通过像这样的方式调用只有按钮的方法:
for(int i = 0; i < this.components.size(); i++) {
if(components.get(i) instanceof Button){
Button b = (Button)components.get(i);
b.paintComponent(); //or any other methods that buttons have.
}
//treat it as a normal component;
}
或者,你可以将你的按钮分别存储在不是按钮的组件上,然后不需要投射它们。