class Base {
Base() {
System.out.println("Base Constructor");
}
}
class Derived1 extends Base {
private static String pattern = "a+b+";
Derived1() {
super();
System.out.println("Derived 1 Constructor");
}
public static boolean doesMatch(String v) {
return v.matches(pattern);
}
}
class Derived2 extends Base {
private static String pattern = "c+";
Derived2() {
super();
System.out.println("Derived 2 Constructor");
}
public static boolean doesMatch(String v) {
return v.matches(pattern);
}
}
class Builder {
public static Base baseFromString(String v) throws Exception {
if (Derived1.doesMatch(v)) return new Derived1();
if (Derived2.doesMatch(v)) return new Derived2();
throw new Exception("Could not match " + v + " to any derived type.");
}
}
class Test {
public static void main(String[] args) throws Exception {
Base b = Builder.baseFromString("aaab");
}
}
The code above has a primary problem I want to solve:
doesMatch
method is repeated code for the two derived classes. I'd like to move it to the base class, but then it won't be able to access the pattern member. How do I structure my code better so that each derived class can have its own static pattern, while they all share the same base doesMatch
method?I've tried messing around with abstract classes and interfaces, but I couldn't get anything to work. I am fine with those types of solutions as long as there is a hierarchy where the derived classes either extend or implement the base class.
Secondary question (from original post)
baseFromString
method with another if
every time I extend the base class. Is this something that can be solved with polymorphism?You can't do that, at least not with static members. The problem is that static members cannot be overridden.
public class Driver {
public static void main(String args[]) {
Derived aDerived = new Derived();
aDerived.print(); // prints "Value is 5", not "Value is 10"
}
}
public class Base {
protected static final int VALUE = 5;
public Base() {}
protected void print() {
System.out.println("Value is " + VALUE);
}
}
public class Derived extends Base {
protected static final int VALUE = 10; // does not override base Value
public Derived() {}
}
Each subclass can have its own value, and they would all inherit print()
. But it doesn't do what you want because print()
will always reference Base.VALUE
even in the inherited Derived.print()
.
So, static doesn't work. I assume that you feel the pattern
member needs to be static because there only needs to be one copy of the pattern value for the entire class. That one copy part should have tipped you off to a handy little design pattern: the singleton pattern!
public class Driver {
public static void main(String args[]) {
Derived aDerived = new Derived();
aDerived.print(); // prints "Value is 10"
}
}
public class Base {
protected Value val = Value.getInstance();
public Base() {}
protected void print() {
System.out.println("Value is " + val.value());
}
}
public class Derived extends Base {
public Derived() { val = DerivedValue.getInstance(); }
}
public class Value {
private int value = 5;
public int value() { return value; }
private static Value instance = new Value();
protected Value() {}
public static Value getInstance() { return instance; }
}
public class DerivedValue extends Value {
private int value = 10;
public int value() { return value; }
private static DerivedValue instance = new DerivedValue();
private DerivedValue() {}
public static DerivedValue getInstance() { return instance; }
}
There's a lot more code in this version, but now there is only one copy of the two different values used.
Note: Below is how you can make the value
members final
. You'll have to set up your packages appropriately so the protected Base(Value v)
constructor is only visible to the Derived
class.
public class Base {
protected final Value val;
public Base() { val = Value.getInstance(); }
protected Base(Value v) { val = v; }
protected void print() {
System.out.println("Value is " + val.value());
}
}
public class Derived extends Base {
public Derived() { super(DerivedValue.getInstance()); }
}