关于继承Java类的性质的问题
所以我想我有一个非常基本的问题。假设有一个名为 com.cow.moo 的开源 Java 程序,您将其包含在项目 com.bee.buzz 中。
moo 有很多很棒的类,其中大部分是你不想碰的,但也有一些是你愿意碰的。现在,最好的办法就是扩展您想要修改的类,对吧? (我知道有很多关于扩展与实现的说法,但这些类都不是接口,所以这是不可能的。)
我的问题是,假设这是 moo 中的类:
package com.cow.moo;
public class Milk {
private float currentMilk;
public int getMilk() { /* Stuff */ }
public float convertToGallons (float liquid) { /* More Stuff */ }
}
现在,假设我想要只需在我扩展 Milk 的新类中使用 getMilk 即可。但是,Milk 中的 getMilk 依赖于私有变量(如 currentMilk)和我不会包含的其他函数(如 ConvertToGallons)。如果我希望我的新函数正常工作,我是否必须包含这些其他变量和函数?我不想大量修改该功能,只需添加一点点即可。最好的方法是什么?
一般来说,构建大型项目的技巧也很有用。我想这里的一些 Java 专家甚至不会花五秒钟就能给出答案。感谢您抽出时间。
So I think I have a pretty basic question. Say there's an open source Java program called com.cow.moo that you include in your project com.bee.buzz.
moo has a bunch of great classes, most of which you don't want to touch, but there are a couple you do. Now at this point, the best thing to do would be to extend the classes you want to modify, right? (I know there's been a lot said of extends vs. implements, but none of these classes are interfaces, so that's kind of out of the question.)
My question is, say this is the class in moo:
package com.cow.moo;
public class Milk {
private float currentMilk;
public int getMilk() { /* Stuff */ }
public float convertToGallons (float liquid) { /* More Stuff */ }
}
Now, say I want to just use getMilk in my new class that extends Milk. However, getMilk in Milk relies on private variables (like currentMilk) and other functions I won't be including (like convertToGallons.) Will I have to include those other variables and functions if I want my new function to work correctly? I don't want to heavily modify the function, just add a little bit to it. What's the best way to do this?
Tips in general in building off a larger project would be useful, too. I figure it won't even take five seconds for some of the Java experts here to come up with an answer. Thanks for your time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一般建议是优先考虑组合而不是继承。
比如说,您有一个接口和一个最适合您需求的现有实现,就像
并且需要另一个自定义实现,您可以这样编码:
The general recommendation is to favor composition over inheritance.
Say, you have an interface and an existing implementation that mostly fits you needs, like
and need another custom implementation, you could code it like that:
您不必包含公共函数和变量。继承的核心概念是,作为子类,您可以免费获得包含在子类中的所有父类的公共(和受保护)成员。因此,您的子类(比方说 HoneyMilk)可以从一开始就调用
convertToGallons
。在这种情况下,重写 getMilk 会更加棘手,因为它依赖于私有变量(您的子类无法访问该变量)。我的建议是转变你的思维方式,从将课堂视为“白盒子”到“黑盒子”。我的意思是,您应该实现
getMilk
的重写版本,就好像您实际上无法看到 Milk 的源代码一样。虽然它看起来像是一个迂回的解决方案(我的意思是,为什么我不能在这里调整这一行?!),这将迫使您仅使用父类公开公开的内容来实现您的子类。它还强调了抽象的重要性,这在开发大型项目时绝对是至关重要的。You won't have to include the public functions and variables. The core concept of inheritance is that, as a subclass, you get all of your parent class's public (and protected) members included in your subclass for free. So your subclass (let's say HoneyMilk) can call
convertToGallons
right from the get-go.Overriding
getMilk
in this case is a lot trickier, since it relies on a private variable (which your subclass cannot access). My advice is to shift your mindset from treating the class as a "white box" to a "black box". What I mean by that is that you should implement your overridden version ofgetMilk
as if you weren't actually able to see Milk's source code. While it may seem like a roundabout solution (I mean, why can't I just go tweak this line here?!), this will force you to implement your subclass using only what the parent class exposes publicly. It also heavily emphasizes the importance of abstraction, which is absolutely crucial to utilize when developing large-scale projects.我认为在这种情况下更好的解决方案是多态性(静态多态性),或者您可以使用反射(不要使用这种方式)来访问私有变量。
I think in this case better solution will be polymorphism (static polymorphism), or you can use reflection (do not use this way) to reach to the private variable.
您可以扩展类并通过方法访问器(getter 和 setter)访问实例变量(如果它们是公共的)。
您可以使用 AOP(面向方面编程) 在运行时更改您的 moo 类,而无需更改它的来源。
也可以考虑阅读一些组合与继承主题。
希望这会对您有所帮助。
You can extend the class and access instance variables throught method accessors (getters & setters) if they are public.
You can use AOP (Aspect Oriented Programming) to change your moo classes at runtime without changing its sources.
Consider too read some Composition vs. Inheritance topics.
Hope this will help you.
除非使用 Java 反射,否则您将无法使用私有类成员,这有点难看。如果我是你(并且更改不太重,在这种情况下我会分叉原始项目),我会考虑在运行时修改代码或静态使用方面编织(面向方面的编程)。 AspectJ 可能看起来有一个尖锐的学习曲线,但它是您工具箱中的一个很棒的工具,并且完全满足您的需求。
You won't be able to use private class members unless you use Java reflection which will be kind of ugly. If I were you (and the changes are not too heavy, in which case I'd fork the original project), I'd look at modifying the code at runtime or statically using aspect weaving (aspect oriented programming). AspectJ may look as if it had a sharp learning curve, but it's a great tool to have in your toolbox and perfectly matches your needs here.