正当我开始熟悉接口(interface)时,我遇到了抽象类的绊脚石。在我的理解中,它们可以用来为子类提供一些功能,但会强制子类指定未定义的函数(如果还有的话)。
但是,我遇到的所有示例都只处理可能是静态的功能 - 没有引用实例变量。
我试图在抽象类中隐藏一些常见的函数,例如getName()
,但能够在子类中定义所述名称。
public interface Application {
public String getName();
}
/**
* Specify some default behaviour to keep leaf classes free of common code
*/
public abstract class DefaultApplication implements Application {
public static final String NAME = "DefApp";
@Override
public String getName() {
return NAME;
}
}
public class MyApp extends DefaultApplication {
public static final String NAME = "My App";
}
// Main class
Application myApp = new MyApp();
System.out.println(myApp.getName()); // Prints "DefApp"
我认为protected String name
可能有效,但这也会返回抽象类中的实例变量。在每个子类中重新定义 getName() 是唯一的解决方案吗?我不会太介意,但这并不是我试图将方法转移到抽象类中的唯一情况。
谢谢!
编辑:
如果相关(建议我可以考虑的其他方法),Application 是一个插件 api,MyApp 是提供的示例应用程序。 DefaultApplication 是基础项目的一部分。
最佳答案
您无法覆盖任何静态内容。静态方法不属于特定对象,而是属于类本身;当您编写 return NAME
时,编译器会将其读取为 return DefaultApplication.NAME
。
在这种情况下,您可以按照您已经提出的方式重写每个子类中的 getName()
,也可以使该字段成为非静态,并执行如下操作:
abstract class DefaultApplication implements Application {
private final String name;
protected DefaultApplication(String name) {
this.name = name;
}
protected DefaultApplication() {
this("DefApp");
}
public String getName() {
return name;
}
}
class MyApp extends DefaultApplication {
public MyApp() {
super("My App");
}
}
这将为 DefaultApplication
的每个实例添加一个额外的字段,但只要您没有数百万个实例,这就不重要。
关于java - 抽象类中的具体方法可以返回子类中定义的变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13886453/