我有以下抽象类:
public abstract class AbstractCreateActionHandler {
protected IWorkItem mCurrentWI;
public AbstractCreateActionHandler(IWorkItem wi) {
this.mCurrentWI = wi;
}
public final void invoke() {
try {
if (checkForLockingFile()) {
this.executeAction();
Configuration.deleteInstance();
}
} catch (IOException e) {
Configuration.deleteInstance();
e.printStackTrace();
}
}
protected abstract void executeAction();
private boolean checkForLockingFile() throws IOException {
String path = Configuration.getInstance().getProperty("path");
File lock = new File(path + "lock_"+mCurrentWI.getId()+"__.tmp");
if(!lock.exists()) {
lock.createNewFile();
return true;
}
return false;
}
}
子类扩展了抽象类:
public class MyAction extends AbstractCreateActionHandler {
public MyAction(IWorkItem wi) {
super(wi);
}
@Override
protected void executeAction() {
// Implementation
}
// ALSO POSSIBLE...
/* @Override
public void executeAction() {
// Implementation
}*/
}
问题:
是否有可能扩展抽象类并实现executeAction()
方法的开发人员不允许更改executeAction()
的可见性?
目前,开发人员可以简单地将方法的可见性更改为“public”,创建子类的对象并调用executeExtion()
。可以更改可见性修饰符,并且仍然将抽象方法接受为“已实现”。
因此可以绕过“正常”调用序列和在抽象类方法invoke()
中执行的检查。有没有办法检查是否调用了invoke()
方法?
答案 0 :(得分:4)
是否有可能扩展抽象类并实现executeAction()方法的开发人员不允许更改executeAction()的可见性?
不,这是不可能的。
Java语言规范的第8.4.8.3. Requirements in Overriding and Hiding条指定:
覆盖或隐藏方法的访问修饰符(第6.6节)必须至少提供与重写或隐藏方法一样多的访问权限,如下所示:...
因此,总是可以让覆盖方法提供更多访问权限,而不是父类中重写的方法。
答案 1 :(得分:4)
不,没有办法限制它。你担心恶意开发者还是无能为力的同事?如果后者那么你只需要建立编码约定,如“不增加方法的可见性”,并在抽象方法上放置一些javadoc来表示正确的用法。如果是前者,那么您可能需要以不同的方式设计代码(可能使用策略模式)。
答案 2 :(得分:0)
允许将修饰符更改为公开,因为它不违反Liskov Substitution Principle。
所以“正常”调用序列和检查执行 可以绕过抽象类方法invoke()。有办法吗? 检查是否调用了invoke()方法?
如果您将某个引用传递给AbstractCreateActionHandler
,则调用者将无法看到方法executeAction
,因为AbstractCreateActionHandler
类中的不公开 。因此,如果将对Base类的引用传递给调用者,则调用者将无法绕过执行序列。如果传递对Concrete类的引用,则序列可能会被破坏。