Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.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_Android_Oop_Subclass_Visibility - Fatal编程技术网

Java 子类中的可变可见性

Java 子类中的可变可见性,java,android,oop,subclass,visibility,Java,Android,Oop,Subclass,Visibility,这是一个非常简单的问题,我很抱歉这么粗鲁:/ 我是Java新手。我有一个市场上的游戏,工作得很好,但代码都是垃圾。基本上,我写它就像写JavaScript一样。我正在努力学习更多关于面向对象编程的知识。所以,在我的新游戏中,我一直在创建从自定义类扩展而来的对象。例如(这不是我正在做的): 现在,假设在我的游戏主线程中,我实例化了许多颜色(橙色、红色、紫色),并将它们存储在ArrayList中。我在游戏的另一个点上反复浏览这个列表,我想访问颜色的alpha。我的问题是,由于它们都被包装到超类中,

这是一个非常简单的问题,我很抱歉这么粗鲁:/

我是Java新手。我有一个市场上的游戏,工作得很好,但代码都是垃圾。基本上,我写它就像写JavaScript一样。我正在努力学习更多关于面向对象编程的知识。所以,在我的新游戏中,我一直在创建从自定义类扩展而来的对象。例如(这不是我正在做的):


现在,假设在我的游戏主线程中,我实例化了许多颜色(橙色、红色、紫色),并将它们存储在
ArrayList
中。我在游戏的另一个点上反复浏览这个列表,我想访问
颜色的alpha。我的问题是,由于它们都被包装到超类中,我不能只说
colorObj.alpha
,但我确实可以访问
colorObj.STROKE\u WIDTH
。类似地,我将无法访问Orange类中的任何方法

一定有办法做到这一点,我只是个新手。我不希望有人坐在这里解释。。我不想浪费你的时间。但是,如果有人可以粘贴一个链接到一些初学者的教程或一些可以帮助我解决这个问题的东西,我将不胜感激

如果你写:

Color c = new Orange();
c.alpha = 10; // Won't compile
这不会编译,不是因为alpha被包装,而是您必须在超类中定义它。类似地,在上面的声明中,橙色中定义的所有方法都不可访问,因为当您引用“c”时,它意味着它是一种颜色,但不一定是橙色。总而言之,上述声明中的“c”允许您访问所有颜色的公共成员,但不能访问橙色的公共成员


学习OOP并不容易,特别是对于来自脚本开发人员的人来说。与其只是阅读在线材料,我建议你从一本关于OOP或Java的好书开始。是我极力推荐的方法之一。

您必须将继承层次结构中所有类的相同变量和方法移动到基类,因此在您的情况下,我会将变量alpha移动到基类

稍后,如果您想访问特定于继承类的方法或变量,您必须执行强制转换,以防您有一个myColors列表;假设列表中的第i个对象是橙色,它有一个名为mix(color otherColor)的方法,那么您只需执行以下操作:

((Orange)myColors.get(i)).mix(someOtherColor);
最后一件事,不要使用公共类成员变量,总是给它们尽可能低的可见性(私有、受保护),总是使用getter访问它们,setter修改它们,因为这是一个非常基本的OO概念:)

我在游戏中的另一个点上迭代这个列表,我想访问颜色的alpha。我的问题是,因为它们都被包装到超类中,所以我不能只说colorObj.alpha

如果你所有的实际颜色都有alpha,那么把它放在Color类中。它应该包含所有颜色共有的属性和行为

旁注:面向对象编程的重点之一是封装。公共数据成员公开类的内部表示形式。通常将该表示隐藏在访问器方法后面,例如:

class Color {
   private int alpha;
   public int getAlpha() { return alpha; }
}
现在没有人知道你的陈述;没有人可以将alpha更改为对颜色没有意义的值,可以将其设置为只读或只读,甚至可以将其更改为计算值,并且使用它的客户机都不会受到影响

事实上,OOP中的一个“最佳实践”就是将这一点发挥到极致,并对接口而不是类进行编程。您将为没有数据成员且实际上无法实例化的颜色定义一个接口。它代表了颜色将遵守的合同,仅此而已。例如:

interface Color {
   int getR();
   int getG();
   int getB();
   int getA();
}

class Red implements Color {
   ...
当然,对于像颜色这样的东西来说,这太过分了。我知道这是一个人为的例子,但颜色并没有不同的行为,只是不同的值,所以与其使用类Red、Orange等,不如使用表示每个颜色的颜色类的实例

类似地,我将无法访问Orange类中的任何方法


对。但是这个想法是,处理颜色的代码不需要知道它们是什么实际颜色。这就是多态性的力量。如果需要一些特殊情况处理,您可以将颜色“向下投射”到特定的子类型,但这样做通常是设计不严谨的症状。

我将
alpha
放在Orange类中的原因是因为我希望所有橙子都有30个
alpha
和(作为示例)所有的Purples都有100个alpha。感谢你提供了关于使用低可见性的提示,我想知道我是否应该这样做(我已经将子类中的所有变量设置为
public
lol)使用getter对OO总是有好处的。但有趣的是,Android不鼓励内部getter/setter,因为它说这会影响性能P算了吧!我不在乎。@Snailer,以你的alpha为例,你应该在你的超类(Color)中定义一个公共的void抽象getAlpha(),然后在每个子类中重写它。所以你是说,如果不将任何
Color
转换成像
Orange
这样的子类,就无法做到这一点。我认为这又回到了设计问题上。在大多数情况下,您不应该使用类型转换,因为它实际上执行起来比较慢,而且最重要的是,它不是一种好的设计实践。如果认为所有颜色都需要alpha,为什么不在颜色超类中声明GETalpha和StAlpha。这就是OOP的美妙之处,您可以在不同的子类中重写alpha的行为。
class Color {
   private int alpha;
   public int getAlpha() { return alpha; }
}
interface Color {
   int getR();
   int getG();
   int getB();
   int getA();
}

class Red implements Color {
   ...