Java:“类重载”
Posted
技术标签:
【中文标题】Java:“类重载”【英文标题】:Java: "Class Overloading" 【发布时间】:2012-03-08 08:29:58 【问题描述】:好的,假设我有一个名为 Orange 的类文件,然后是两个单独的类文件 Color 和 Fruit。
Orange内部有颜色、大小、成熟度等属性,还有setSize(int size)方法。
在 Fruit 中,有一些属性:名称、水果类型、是否有种子、从哪里导入等,然后是方法 setName(String name)、eat()、wash() 和 give (个人)。
在 Color 内部有一些属性名称、RGB 值、十六进制值、Alpha 值等,然后是方法 setName()、setAlpha(int alpha)、setRGB(int r, int g, int b) 和 setHex(十六进制)。
上面提到的大部分信息都是无关紧要的,只是为了帮助您理解。 Orange Class 文件中有一个名为“Parent”的对象。我需要知道的是,对象“父母”是否可以设置为水果或颜色?稍后在主类文件中会出现 myOrange.Parent.setName("Bob") 发生的地方,并且在这两种情况下(无论 Parent 是 Fruit 还是 Color)都是可能的,因为 Fruit 有一个名为 setName 的方法, Color 也一样。
谢谢
【问题讨论】:
除了可以顺便调用相同的 setName 方法之外,以什么方式对待颜色和水果对您有好处? 您是否尝试过用 Java 编写并编译它?成员 parent 应该是什么类型,以便您可以为其分配 Fruit 实例或 Color 实例? 那么当橙色(水果)呈橙色时会发生什么? 【参考方案1】:类型继承(“类重载”?)表示“is-a”关系。
橙子是一种水果。不需要额外的变量;通过this
访问继承的成员。
Composition 表示“具有”关系。
橙色有颜色。使用此模式时会声明一个单独的变量,因此这显然是用于 Parent
的变量。
因此,Parent
(一个可怕的变量)是 Color 的一个实例。
【讨论】:
【参考方案2】:这真的取决于您的用例。如果“Orange”类表示橙色,那么从“Color”类继承它可能是有意义的。如果它代表水果,那么从“Fruit”类继承可能是有意义的。
但是,在这两种情况下(至少根据给出的信息),我都没有看到“Orange”类具有“Parent”引用的原因。正如我之前所说,让您的“Orange”类扩展 Color 或 Fruit 会更有意义(同样,取决于您的用例)。
【讨论】:
【参考方案3】:如果“parent
”是指“inherits from
”,那么答案是否定的。
Orange
可以继承自 Fruit
,但不能继承自 Color
。继承必须是“is-a”关系。
Orange
"is-a" Fruit
,这是正确的。
Orange
"is-a" Color
mmmm 听起来不对。
【讨论】:
【参考方案4】:您可能希望做的是让 Color 和 Orange 实现一个名为“NameHolder”(如果您想同时公开 getter 和 setter)或“NameSetter”(如果您只想公开 setter)的接口。
例如这样(我将使用 NameHolder 作为最常见的情况):
interface NameHolder
String getName();
void setName(String name);
class Color implements NameHolder
// methods and fields, setter and getter implemented
class Fruit implements NameHolder
// methods and fields, setter and getter implemented
以这种方式,Orange 可以不将其“父”对象作为对象(行为很少),而是作为 NameHolder 的实例。这就是你指出的那一行:
private NameHolder Parent;
myOrange.Parent.setName("Bob");
这行代码编译不会出错(当然,如果 Parent 为 null,它会在运行时导致 NullPointerException)。我还应该指出,Java 的编码指南建议字段为小写,因此应符合约定:
private NameHolder parent;
myOrange.parent.setName("Bob");
【讨论】:
【参考方案5】:在像 Java 这样的静态类型语言中,您不能在变量上调用方法,除非变量的类型声明了所述方法。变量的类型限制了您对变量指向的对象的访问;它就像一个窗口,让您只能看到它背后的对象的一部分。
这与动态类型语言不同;变量类型不限制对对象的访问。只要对象有你调用的方法,你就可以开始了。
所以在 Java 中你需要:
-
创建一个声明
setName
方法的新类型。最灵活的方法是创建一个interface
。那你
在实际具有setName
方法的类中声明该接口为“implement
”,并且
使用您创建的接口来声明变量parent
。
例如:
interface Nameable void setName(String name);
class Color implements Nameable
public void setName(String name)
/* implement other Color methods */
class Fruit implements Nameable
public void setName(String name)
/* implement other Fruit methods */
class Orange Nameable parent; /* call parent.setName at some point */
【讨论】:
【参考方案6】:如果 Orange 实际上通过继承具有父级,则它应该已经可以访问其成员函数。听起来您正试图通过解决方法让 Orange 同时从 Color 和 Fruit 继承,因为 Java 不支持多重继承。这可能不是您真正想要做的。你最好的选择是建立一个已经暗示过的正确关系。
public class Colormethods
public class Fruitmethods
public class Orange extends Fruit
private Color orangeColor;
//Other member variables and functions.
这样,橙色是-一种水果并且具有-一种颜色。如果您希望橙色能够成为水果或颜色,您需要重新考虑您想要什么。总是有可能有一个名称为“Orange”的水果和一个名称为“橙色”的颜色,但实际上它们并不属于同一个类。
【讨论】:
【参考方案7】:如果您想以这种方式对其进行编程,您可以在执行方法之前检查“Parent”是否引用了 Fruit 或 Color 的实例,然后执行适当的方法调用。
【讨论】:
以上是关于Java:“类重载”的主要内容,如果未能解决你的问题,请参考以下文章