可能是一个非常基本的java问题。
我有一个抽象类,简化它:
public abstract class A{
private String value = "A" ; // I want it undeclared, but set it for testing purpouse
public String getValue(){
return value ;
}
}
然后我有一个课程扩展它:
public abstract class B{
private String value = "B" ;
}
所以我遇到的问题是,当通过类A创建B的实例并调用getValue()时,它总是返回“A”:
A b = new B();
b.getValue(); // returns "A"
如何使用自己的属性获取B调用超级方法而无需重复代码?它目前太长了,它被扩展到许多不同的类,只有它的属性值不同,所有类都使用与超类相同的方法。
谢谢!
编辑:
对不起,我没那么具体。我有很多属性,以及一些处理这些属性的方法。扩展类更改了这些属性,但我希望将超类方法与扩展类实例化对象一起使用,而不必将它们声明两次。如果有帮助,我正在使用servlet上下文属性。
Config.java
public abstract class Config {
private String someValue1 ;
...
private String someValuen ;
public void export(ServletContext cxt){
cxt.setAttribute("someValue1", someValue1);
...
cxt.setAttribute("someValuen", someValuen);
}
}
SomeConfig.java
public class SomeConfig {
private String someValue1 = "something" ;
...
private String someValuen = "something else" ;
}
SomeServlet.java
ServletContext cxt = getServletContext() ;
Config config = new SomeConfig();
config.export(cxt);
为清楚起见,属性都有不同的名称。我在jsp中使用它们:$ {someValuen}
答案 0 :(得分:5)
它不起作用的原因是只能覆盖方法 - 隐藏变量成员(如果从B类打印value
,它将是"B"
)。
对于该特定示例,我将使用专用构造函数(我已对其进行了保护以防止客户端类访问它):
public abstract class A {
private final String value;
public A() { //for internal / testing use only
value = "A";
}
protected A(String value) {
this.value = value;
}
public String getValue(){
return value ;
}
}
然后B可以简单地调用相关的构造函数:
public class B extends A {
public B() {
super("B");
}
}
修改强>
ConfigHolder
的示例:
public class ConfigHolder {
String value1;
String value2;
String value3;
public ConfigHolder value1(String value1) {
this.value1 = value1;
return this;
}
//same for other variables
}
然后在A班:
public abstract class A {
private final ConfigHolder config;
public A() {
this.config = new ConfigHolder()
.value1("value1")
.value2("value2");
}
protected A(ConfigHolder config) {
this.config = config;
}
public void export(ServletContext cxt){
cxt.setAttribute("someValue1", builder.value1);
...
cxt.setAttribute("someValuen", builder.valuen);
}
}
在B:
public class B extends A {
public B() {
super(new ConfigBuilder()
.value1("value1InB")
.value2("value2InB"));
}
}
答案 1 :(得分:0)
要执行此操作:A b = new B();
B必须是A
此外,抽象类无法实例化,即无法创建抽象类对象。如果你尝试,编译器会产生错误。
public abstract class A{
private String value = "A" ;
public String getValue(){
return value ;
}
}
public class B extends A{
private String value ;
public B(){
value = "B";
}
}
现在你可以B notAbstractClass = new B();
在做notAbstractClass.getValue();
时,必须返回“B”
答案 2 :(得分:0)
我只是想出了一个简单的方法来使用构造函数并将超类属性更改为protected(感谢@assylias答案): Config.java
public abstract class Config {
protected String someValue1 ;
...
protected String someValuen ;
public void export(ServletContext cxt){
cxt.setAttribute("someValue1", someValue1);
...
cxt.setAttribute("someValuen", someValuen);
}
}
SomeConfig.java
public class SomeConfig {
public SomeConfig(){
someValue1 = "something";
...
someValuen = "something else";
}
}