关于继承Java类的性质的问题

发布于 2024-09-14 00:12:51 字数 674 浏览 4 评论 0原文

所以我想我有一个非常基本的问题。假设有一个名为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

断肠人 2024-09-21 00:12:51

一般建议是优先考虑组合而不是继承

比如说,您有一个接口和一个最适合您需求的现有实现,就像

public interface MilkProvider { public float getMilk(); }
public class Milk implements MilkProvider { // same as you example }

并且需要另一个自定义实现,您可以这样编码:

public class MyMilk implements MilkProvider {
  private MilkProvider milk; 

  public MyMilk(int someValue) {
    milk = new Milk(someValue);  // unfortunatly we can't get rid of a depencency
                                 // to the concrete class because we need to create
                                 // something. An existing factory could help, but
                                 // but usually there's none implemented.
  }

  public float getMilk() {
    float result = milk.getMilk();
    // do somethink with the result
    return float;
  }
}

The general recommendation is to favor composition over inheritance.

Say, you have an interface and an existing implementation that mostly fits you needs, like

public interface MilkProvider { public float getMilk(); }
public class Milk implements MilkProvider { // same as you example }

and need another custom implementation, you could code it like that:

public class MyMilk implements MilkProvider {
  private MilkProvider milk; 

  public MyMilk(int someValue) {
    milk = new Milk(someValue);  // unfortunatly we can't get rid of a depencency
                                 // to the concrete class because we need to create
                                 // something. An existing factory could help, but
                                 // but usually there's none implemented.
  }

  public float getMilk() {
    float result = milk.getMilk();
    // do somethink with the result
    return float;
  }
}
离线来电— 2024-09-21 00:12:51

现在,假设我只想在扩展 Milk 的新类中使用 getMilk。但是,Milk 中的 getMilk 依赖于私有变量(如 currentMilk)和其他我不会包含的函数(如 ConvertToGallons)。如果我希望我的新函数正常工作,我是否必须包含这些其他变量和函数?

您不必包含公共函数和变量。继承的核心概念是,作为子类,您可以免费获得包含在子类中的所有父类的公共(和受保护)成员。因此,您的子类(比方说 HoneyMilk)可以从一开始就调用 convertToGallons

在这种情况下,重写 getMilk 会更加棘手,因为它依赖于私有变量(您的子类无法访问该变量)。我的建议是转变你的思维方式,从将课堂视为“白盒子”到“黑盒子”。我的意思是,您应该实现 getMilk 的重写版本,就好像您实际上无法看到 Milk 的源代码一样。虽然它看起来像是一个迂回的解决方案(我的意思是,为什么我不能在这里调整这一行?!),这将迫使您仅使用父类公开公开的内容来实现您的子类。它还强调了抽象的重要性,这在开发大型项目时绝对是至关重要的。

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?

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 of getMilk 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.

过期情话 2024-09-21 00:12:51

我认为在这种情况下更好的解决方案是多态性(静态多态性),或者您可以使用反射(不要使用这种方式)来访问私有变量。

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.

风透绣罗衣 2024-09-21 00:12:51

您可以扩展类并通过方法访问器(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.

尾戒 2024-09-21 00:12:51

除非使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文