这是一个非常简单的问题,我为这么无趣而道歉:/
我是Java的新手(ish)。我在市场上有一款运行良好的游戏,但代码都是垃圾。基本上,我写的就像我在编写JavaScript一样。我正在尝试更多地了解面向对象编程。所以,在我的新游戏中,我一直在创建从自定义类扩展的对象。例如(这实际上不是我正在做的):
public class Color{
public final int STROKE_WIDTH = 3;
public Color(){}
}
public class Orange extends Color{
public int alpha = 30;
public Orange(){
super();
}
}
现在,在我的游戏主线程中说我实例化了很多颜色(橙色,红色,紫色),并将它们存储在ArrayList<Color>
中。我在游戏的另一个点迭代这个列表,我想访问Color
的alpha。我的问题是,因为它们都包含在超类中,所以我不能只说colorObj.alpha
,但我可以访问colorObj.STROKE_WIDTH
。同样,我也无法访问Orange类中的任何方法。
必须有办法做到这一点,我只是新的。我不指望有人坐在这里并输出解释..我不想浪费你的时间。但是,如果有人可以只是粘贴一些初学者教程的链接或者可以帮我解决这个问题的东西,我会很感激!
答案 0 :(得分:1)
如果你写:
Color c = new Orange();
c.alpha = 10; // Won't compile
这不会编译,因为alpha被包装,但你必须在超类中定义它。类似地,在上面的声明中无法访问Orange中定义的所有方法,因为,当您引用'c'时,它表示它是一个Color,但它不一定是Orange。总结一下,上面声明中的'c'允许您访问Color的所有公共成员,但不能访问Orange中的那些成员。
学习OOP并不容易,特别是来自Script dev的人。我建议你不要只是阅读在线资料,而是要从中获取一本关于OOP或Java的好书。 The Head First Series是我强烈推荐的其中之一。
答案 1 :(得分:1)
我在游戏的另一个点迭代这个列表,我想访问Color的alpha。我的问题是,因为他们都被包裹在超类中,我不能只说colorObj.alpha
如果你的所有实际颜色都有alpha,那么把它放在Color类中。它应该包含所有颜色共有的属性和行为。
旁注:面向对象编程的其中一个是 enscapsulation 。公共数据成员公开您的类的内部表示。通常,您在访问者方法后隐藏该表示,例如:
class Color {
private int alpha;
public int getAlpha() { return alpha; }
}
现在没人知道你的代表;没有人可以将alpha更改为对Color没有意义的值,您可以将其设置为只读或只写,甚至可以将其更改为计算值,并且不会影响使用它的客户端。< / p>
事实上,OOP中的“最佳实践”是将这种方式带到极端并对接口进行编程,而不是类。您将为Colors定义接口,它没有数据成员,实际上无法实例化。它代表了颜色将遵守的合同,仅此而已。例如:
interface Color {
int getR();
int getG();
int getB();
int getA();
}
class Red implements Color {
...
当然,这对像Color这样的东西来说太过分了。我知道这是一个人为的例子,但是颜色不具有不同的行为,只是不同的值,所以不是有红色,橙色等等,你会有实例一个Color类,代表每个。
同样,我无法访问Orange类中的任何方法。
真。但是这个想法是,处理Colors的代码不需要知道它们是什么样的实际颜色。这就是多态性的力量。如果 需要进行一些特殊情况处理,您可以将颜色“向下投射”到特定的子类型,但是需要这样做通常是设计草率的症状。
答案 2 :(得分:0)
那么你必须将继承层次结构中所有类的所有变量和方法都移动到基类,所以在你的情况下我会将变量alpha移动到基类。
如果你想访问特定于继承类的方法或变量,你必须进行强制转换,以防你有一个List myColors;并且假设列表中的第i个对象是橙色,并且它有一个名为mix(Color otherColor)的方法,那么你必须简单地这样做:
((Orange)myColors.get(i)).mix(someOtherColor);
最后一件事,不要使用公共类成员变量,总是给他们尽可能低的可见性(私有,受保护),并始终使用getters访问它们和setter来修改它们,因为这是一个非常基本的OO概念:)