Java 保持子类中抽象方法的可见性
我有以下抽象类:Java 保持子类中抽象方法的可见性,java,abstract-class,visibility,Java,Abstract Class,Visibility,我有以下抽象类: public abstract class AbstractCreateActionHandler { protected IWorkItem mCurrentWI; public AbstractCreateActionHandler(IWorkItem wi) { this.mCurrentWI = wi; } public final void invoke() { try { if (c
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
}*/
}
子类扩展了抽象类:
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()
方法
是否有可能不允许扩展抽象类并实现executeAction()方法的开发人员更改executeAction()的可见性
不,这是不可能的
Java语言规范的章节规定:
重写或隐藏方法的访问修饰符(§6.6)必须提供至少与重写或隐藏方法相同的访问,如下所示:
因此,总是可以让重写方法提供比父类中重写方法更多的访问权限
另请参见。允许将修饰符更改为public,因为它不违反 因此,“正常”调用序列和在 可以绕过抽象类方法invoke()。有办法去吗 检查是否调用了invoke()方法
如果将对
AbstractCreateActionHandler
的引用传递给某人,则调用方将无法看到该方法executeAction
,因为它在AbstractCreateActionHandler
类中不是公共的。因此,如果您将对基类的引用传递给调用方,调用方将无法绕过执行序列。如果您传递对具体类的引用,那么序列可能会被打破。不,没有真正的方法来限制它。您是否担心恶意开发人员或无知的同事?如果是后者,那么您只需要建立编码约定,比如“不要增加方法的可见性”,并在抽象方法上放置一些javadoc来指示正确的用法。如果是前者,那么您可能需要以不同的方式设计代码(可能使用策略模式)。好的……我可能已经知道了。所以也无法检查是否调用了invoke()方法,对吗?战略模式看起来不错。将有一个更仔细的观察。@sk2212-好吧,有很多方法可以做到这一点,比如获取当前堆栈跟踪并回顾它,或者维护一个成员变量,比如“inInvoke”,但我不推荐任何一种:)