I have a Java class called Program
whose rough skeleton is like this:
public class Program {
public Program(AST ast){
...
new RewriteRule1().rewriteAll();
new RewriteRule2().rewriteAll();
}
interface RewriteRule {
// find a line where this rewrite rule can be applied
public abstract Optional<Integer> findRewrite();
// apply this rewrite rule to the program at given line
// destructively modifies the program!
public abstract void doRewrite(int line);
// repeatedly find and rewrite all instances
public default void rewriteAll(){
while (true){
Optional<Integer> line = findRewrite();
if (!line.isPresent())
break;
doRewrite(line.get());
}
}
}
class RewriteRule1 implements RewriteRule{
@Override
public Optional<Integer> findRewrite() {}
@Override
public void doRewrite(int l1) {}
}
class RewriteRule2 implements RewriteRule{
@Override
public Optional<Integer> findRewrite() {}
@Override
public void doRewrite(int l1) {}
}
}
Here, I want to have a notion called RewriteRule
that has two distinct abstract methods called findRewrite
and doRewrite
. I want these to be abstract but I want to have a method called rewriteAll
which is common to all subtypes of RewriteRule
.
In the actual program, I create an instance of every rewrite rule and I call rewriteAll()
individually. This feels wrong. I want to be able to just refer to the subtype RewriteRule1
instead of having to create an instance. Creating an instance feels suboptimal since there is no data associated with it.
But the issue is that
- If
RewriteRule
is an interface, I can't force it to have static abstract methods. Java is asking me to give an implementation for all static methods. - If
RewriteRule
is an abstract class, I can't force it to have static unimplemented methods either.
What is the best way to organize this code?