Java 将方法添加到 class

Java add method to class

早上好,我有一个扩展 class BigDecimal 的自定义 class cBigDecimal。我的目标是同时使用 BigDecimal 和 cBigDecimal class 中的方法(例如 "add" 或 "multiply",以及自定义函数 "percentage")。问题是 "add" & co。 return BigDecimal,显然我不能将它转换为 cBigDecimal ...有什么想法吗? 提前致谢, 洛伦佐

不延长BigDecimal

BigDecimal class 不打算被覆盖。 class 应该被标记为 final 以在编译器中强制执行此限制,但遗憾的是,它并没有如此标记(不幸的疏忽)。所以,不要覆盖 BigDecimal.

如果想到 BigDecimal/BigInteger 之外的其他 class,您可以继续阅读我的答案的其余部分。

多态性

了解 polymorphism in Object-Oriented Programming

如果您将对类型 Dog 的对象的引用分配给 superclass Animal 类型的变量,并且您的 subclass 覆盖方法 eat,然后调用方法 eat 导致执行 subclass 上的方法。这就是 late-binding or dynamic-dispatch 的魔力(这种找到正确的实现行为的各种术语)。

Animal x = new Dog( … ) ;   // Polymorphism: Viewing a `Dog` object as an `Animal` object.
x.eat( … ) ;                // Results in Dog::eat method being invoked, *not* Animal::eat.

警告:确保您的 superclass 及其方法旨在被覆盖。如果标记为 final,则它们不是。

命名

提示:遵循命名约定。 class 总是以大写字母开头。使用 MySubClass,而不是 mySubClass 作为 class 名称。

你的 cBigDecimal class 究竟做了哪些 BigDecimal 没有做的事情?

完全可以扩展 BigDecimal 是设计疏忽。 Josh Bloch 在 Effective Java 3rd Ed Item 17 中说:"Minimize mutability":

It was not widely understood that immutable classes had to be effectively final when BigInteger and BigDecimal were written, so all of their methods may be overridden. Unfortunately, this cannot be corrected after the fact while preserving backwards compatibility.

如果你只想"add a method"到BigDecimal,你可以简单地创建一个辅助方法:

static BigDecimal percent(BigDecimal b) {
  return b.divide(100);  // Or whatever it does.
}

然后,你可以到处处理普通的旧BigDecimal

我会使用 decorator pattern.

基本上,您必须在 CBigDecimal class 中拥有一个 BigDecimal 的实例作为私有成员。要创建 CBigDecimal,您需要一个 BigDecimal 的实例(也可以是 BigDecimal.ZERO)。

然后,在你的CBigDecimal class中你可以提供与BigDecimal相同的接口(你可以添加一个方法CBigDecimal#add(BigDecimal)),因为你有一个实例它在您的 class 中,您还可以创建自己的自定义方法(如您的 CBigDecimal#percentage(double))。

这是示例代码:

CBigDecimal.java:

public class CBigDecimal
{
    private BigDecimal bigDecimal;

    public CBigDecimal(BigDecimal bigDecimal)
    {
        this.bigDecimal = bigDecimal;
    }

    // This method already exists in BigDecimal class, so it will have the same signature
    public CBigDecimal add(BigDecimal toAdd)
    {
        return new CBigDecimal(bigDecimal.add(toAdd));
    }

    // This is the new method which you will implement as you like
    public CBigDecimal percentage(double percentage)
    {
        BigDecimal multiplied = bigDecimal.multiply(new BigDecimal(percentage));
        BigDecimal total = multiplied.divide(new BigDecimal(100));

        return new CBigDecimal(total);
    }

    // This is another method that already exists in BigDecimal class
    public double doubleValue()
    {
        return bigDecimal.doubleValue();
    }
}

然后,客户端代码将通过向其构造函数提供 BigDecimal 实例来创建 CBigDecimal 的实例。

public class CBigDecimalTest
{
     public static void main(String []args)
     {
        CBigDecimal extendedBigDecimal = new CBigDecimal(new BigDecimal(50));

        System.out.println("percentage: " + extendedBigDecimal.percentage(50).doubleValue());
        System.out.println("doubleValue: " + extendedBigDecimal.doubleValue());
     }
}

P.S.: 只有当你真的 需要通过添加一堆新方法来扩展 BigDecimal class 时,这种模式才有价值。如果您只需要添加一个方法,最好按照 .

的建议简单地在某处声明一个静态方法