我去“刷新”我的Java,只是意识到显然我不了解基本概念!这是我不知道的简单方法:
public abstract class Robot {
private String model = "NONAME";
public Robot() {
System.out.println("Making a generic " + model + " robot, type: " + this.getClass());
}
public String getModel() {
return model;
}
}
OK,然后是子类:
public class Terminator extends Robot {
private String model;
public Terminator(String model) {
super();
System.out.println("Making a " + model + " terminator, type: " + this.getClass());
this.model = model;
}
}
然后运行一个简单的示例,期望打印“ T1000”:
Robot r1 = new Terminator("T1000");
System.out.println(r1.getModel());
没有骰子!打印“ NONAME”。在此之前,我从构造函数获得以下输出:
制作一个通用的NONAME机器人,键入:class com.akarpov.tutorial.Terminator
制作T1000终结器,键入:类com.akarpov.tutorial.Terminator
好了,我看到Java意识到我的类的运行时实例是Terminator,这就是“ new”的意思。而且,显然,终结者实例的确保留了模型的副本==“ T1000”。但是在调试器(IntelliJ)中检查r1对象时,我看到两个名为'model'的变量,它们位于不同的地址(显然),具有不同的字符串。而且,显然,如输出所示,抽象类中的getModel选取了Robot类中定义的默认值,而不是传递给Terminator的构造函数(并保留在对象内部)的默认值。
我对抽象类和继承不了解什么,如何使用默认值和默认行为(即getModel)来选择子类中的特定数据(即“ T1000”)?
谢谢!我很抱歉,如果这已经被很多次困扰了-我看了一下,但是什么都没跳。
最佳答案
您遇到的问题是您确实在创建两个变量。现在,有了代码,调用r1.getModel()
时,您将获得原始的基类model
。
如果您希望能够从子类中设置模型,则有几种选择。您可以通过声明一个新的String model
来确定开始的方向,但是您必须继续从超类重写getModel()
方法,以便您的子类将查找自己的model
而不是超类。
public class Terminator extends Robot {
private String model;
public Terminator(String model) {
super();
System.out.println("Making a " + model + " terminator, type: " + this.getClass());
this.model = model;
}
@Override
public String getModel(){
return model;
}
}
另一种选择是在
model
的超类中创建一个受保护的setter方法的公共类。public abstract class Robot{
private String model = "NONAME";
public Robot() {
System.out.println("Making a generic " + model + " robot, type: " + this.getClass());
}
public String getModel() {
return model;
}
protected void setModel(String str){
this.model = str;
}
}
然后,只需将Terminator对象先调用
model
,再调用setModel(model)
,即可获得所需的输出。