给定一个实例调用静态方法

时间:2013-07-05 00:33:03

标签: java design-patterns inheritance anti-patterns

this answer中有以下代码:

//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,但我有一些给定实例的代码,我想调用静态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();
    }
}

2 个答案:

答案 0 :(得分: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();
}

}

答案 1 :(得分:0)

静态方法不是OO。它们是一种在简单的情况下存储类的数据的便捷方式,我们都使用它们很多,但随着事情变得复杂,它们变得笨拙甚至不可能

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

你想要的是两个类的两个实例,比如MetaSub和MetaSuper,它们有方法和数据引用Sub或Super。他们需要实现相同的界面(称之为Meta),这样您就可以获得数据而无需担心实际拥有的数据。 Super的所有实例都有一个方法getMeta,它返回一个Meta实例,MetaSub或MetaSuper,因为原始是Sub或不是。

现在真的很容易。在超级对象上调用getMeta,然后在返回的任何内容上调用method方法,然后就完成了。你称之为正确的方法。

Meta类/接口用真实的OO样式实例方法替换静态类级别方法(和数据)。您可以自由地继承,扩展和覆盖。

您可以根据需要扩展它,为每个超级子类使用Meta实例 - 甚至扩展Super的类。你可以拥有Meta2,Meta3,...接口,这些接口可能会扩展其他人或不扩展。如果需要,您甚至可以使用具有不同Meta对象的同一类的两个对象。此外,Meta实例可用于标记集合的contentents - “此集合包含Sub对象”。它比使用类标识符更强大。

(所需要的只是时间。无论如何,如果您正在撰写新内容而不是扩展遗留系统,这会更有趣。)