Вопрос

In this answer there is this code:

//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");
    }
}

This prints Super as expected, but I have some code where given an instance, I would like to call the static Sub.method(). One solution could be:

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)");
    }
}

However, with non-trivial function bodies (in my case I am checking a parameter falls within limits allowed for the class) there is a lot of repeated code. Is there a good design pattern to resolve this? Reflection would work, perhaps, but it feels like a last resort.

Thinking a bit more, is this any better?

public class Sub extends Super {
    public static void sMethod() {
        Super.sMethod();
        System.out.println("Sub (static)");
    }
    public void method() {
        Sub.sMethod();
    }
}
Это было полезно?

Решение

if you want to call class level method, you don't need an object, just put

Subclass.method();

For reading your comments i think you need basic object inheritance and take approach of polymorphism.

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();

Now you know what method will execute in runtime time, this is call polymorphism and is a main feature from OOP.

And if you still need and static method for some reason in method declaration then you call for example

public class SubClass extends SuperClass{

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

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

}

Другие советы

Static methods are not OO. They're a handy way to store data about a class in simple cases and we all use them a lot, but as things get complicated they become awkward and even impossible.

You might find it easiest to stick with the original solution. (At least it avoids static methods.) But you did ask about a "good design pattern", so:

What you want are two instances of two classes, say MetaSub and MetaSuper, that have methods and data refering to Sub or Super. They need to implement the same interface (call it Meta), so you can get the data without worrying about which you actually have. All instances of Super would have a method getMeta which returns a Meta instance, either MetaSub or MetaSuper as the original is a Sub or not.

Now it's real easy. Call getMeta on your Super object, then call the method method on whatever that returns, and you're done. You've called the right method.

The Meta classes/interfaces replace the static class-level methods (and data) with real OO-style instance methods. You can inherit, extend, and override freely.

You can expand this as needed, with a Meta instance for every Super subclass--and even classes that don't extend Super. And you can have Meta2, Meta3, ... interfaces which might extend others or not. You can even have two objects of the same class with different Meta objects if you want. Also, the Meta instances can be used to label the contentents of collections--"This collections contains Sub objects." It's a lot more powerful than using a Class identifier.

(All it takes is time. Admittedly this is a lot more fun if you're writing something new rather than extending a legacy system.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top