Maximilian Conroe Maximilian Conroe - 1 month ago 10
Java Question

How to avoid redundant code for static methods

Let's assume I have the following classes:

public class Cat {
private final String noise = "meow";

pulic static void makeNoise(){
System.out.println(noise);
}
}

public class Dog {
private final String noise = "woof";

pulic static void makeNoise(){
System.out.println(noise);
}
}


As you can see, these two classes share pretty much the same code. To remove redundant code, I'd create a parent class like this:

public abstract class Animal {
protected final String noise;

public Animal(String noise) {
this.noise = noise;
}

public void makeNoise() {
System.out.println(noise);
}
}

public class Dog extends Animal{
public Dog(){
super("woof");
}
}


Now unfortunately I'm running into a two problems:


  1. Since make noise of animal can't be static anymore, as the constants
    will have to be assigned through the constructor of animal, you will
    need to create a cat or dog to get the noise of that animal. Even
    though it is a constant.

  2. The method makeNoise() need's to work in the class Animal - which
    doens't have a noise per default.



A possible solution would be something along the line like this:
public abstract void makeNoise();
which is neither allowed, nor would it erase the need to copy the code into each and everyone of the children of Animal.

How would you erase the need to have redundant code in the children of animal while keeping the method makeNoise static?

Answer

Static methods in Java can't be overridden in subclasses.

If you define a static method in a subclass with the same signature as the static method in the parent class, the method is not overriding the parent method is hiding it. The methods in the parent and the child class has no relation to each other.

In your example, if method static void makeNoise() exists in Animal and any subclass define the method as well, the subclass is just hiding the makeNoise method in Animal.

In your example, the best you can do with static methods is:

public static void makeNoise(String noise) {
    System.out.println(noise);
}

And invoke the method this way:

Animal.makeNoise(Cat.NOISE); // A constant NOISE is defined in each subclass

If the method makeNoise is non-static, inheritance could be used to use a different noise in each subclass:

public abstract class Animal {
    protected String noise;

    protected Animal(String noise) {
        this.noise = noise;
    }

    public void makeNoise() {
        System.out.println(noise);
    }

}

public class Cat extends Animal{
    public static final String NOISE = "meow";

    public Cat() {
        super(NOISE);
    }
}