0

这个答案中有这个代码:

//in a main method somewhere
Super instance = new Sub();
instance.method();

//...
public class Super {
    public static void method() {
        System.out.println("Super");
    }
}

public class Sub extends Super {
    public static void method() {
        System.out.println("Sub");
    }
}

这按预期打印Super,但我有一些代码在给定实例的地方,我想调用 static Sub.method()。一种解决方案可能是:

public class Sub extends Super {
    public static void sMethod() {
        Super.sMethod();
        System.out.println("Sub (static)");
    }
    public void method() {
        super.method();
        System.out.println("Sub (instance)");
    }
}

然而,对于非平凡的函数体(在我的例子中,我正在检查一个参数是否在类允许的范围内)有很多重复的代码。有没有好的设计模式来解决这个问题?也许反射会起作用,但感觉像是最后的手段。

再想一想,这样更好吗?

public class Sub extends Super {
    public static void sMethod() {
        Super.sMethod();
        System.out.println("Sub (static)");
    }
    public void method() {
        Sub.sMethod();
    }
}
4

2 回答 2

0

如果要调用类级别的方法,则不需要对象,只需放

Subclass.method();

为了阅读您的评论,我认为您需要基本的对象继承并采用多态性的方法。

public class Super {
    public  void method() {
        System.out.println("Super");
    }
}

public class Sub extends Super {
    public  void method() {
        System.out.println("Sub");
    }
}
//in a main method somewhere
Super instance = new Sub();
instance.method();

现在您知道什么方法会在运行时执行,这就是调用多态性,它是 OOP 的一个主要特性。

如果在方法声明中由于某种原因您仍然需要静态方法,那么您可以调用例如

public class SubClass extends SuperClass{

public static void method2(){
  //do Something
}

@Override
public void method(){
  Subclass.method2();
}

}
于 2013-07-05T00:42:05.113 回答
0

静态方法不是面向对象的。 它们是在简单情况下存储类数据的便捷方式,我们都经常使用它们,但随着事情变得复杂,它们变得笨拙甚至不可能。

您可能会发现坚持使用原始解决方案最容易。(至少它避免了静态方法。)但是您确实询问了“良好的设计模式”,所以:

您想要的是两个类的两个实例,比如 MetaSub 和 MetaSuper,它们具有引用 Sub 或 Super 的方法和数据。他们需要实现相同的接口(称为 Meta),因此您可以获取数据而不必担心您实际拥有哪些数据。Super 的所有实例都有一个getMeta返回 Meta 实例的方法,MetaSub 或 MetaSuper,因为原始实例是否为 Sub。

现在真的很容易。 调用getMeta你的 Super 对象,然后调用method任何返回的方法,你就完成了。你调用了正确的方法。

元类/接口将静态类级方法(和数据)替换为真正的 OO 样式实例方法。您可以自由继承、扩展和覆盖。

您可以根据需要扩展它,为每个 Super 子类使用 Meta 实例——甚至是扩展 Super 的类。您可以拥有 Meta2、Meta3、... 接口,这些接口可能会扩展其他接口,也可能不会。如果需要,您甚至可以拥有两个具有不同 Meta 对象的同一类的对象。此外,Meta 实例可用于标记集合的内容——“此集合包含子对象”。它比使用类标识符强大得多。

(所需要的只是时间。诚然,如果您正在编写新的东西而不是扩展遗留系统,这会更有趣。)

于 2013-07-09T19:50:25.857 回答