[英]Calling inherited method in Java
我有以下java代码,
class Animal {
private String name="Animal";
public String getName() {
return name;
}
}
class Cat extends Animal {
private String name = "Cat";
}
public class Test {
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(cat.getName());
}
}
运行该代码后,我得到了输出Animal
,但我认为它应该是Cat
。 在像这样覆盖Cat
getName
方法之后,我得到了Cat
。
@Override
public String getName() {
return name;
}
这是因为在子类实例中调用继承的(不是覆盖的)方法就像cat.getName()
等于调用super.getName()
(所以我在第一种情况下得到Animal
而不是Cat
)? 还是因为实例变量隐藏的奇怪行为(我不太确定)?
name
字段在子类中重新声明,但是在父类中实现了getName
方法,将要读取的唯一字段是父类的Animal.name
。
在子类中声明已在超类中声明的字段总是一个坏主意,因为字段不会被“覆盖”,它们只是被隐藏。
您打算做的是以下任一操作:
重写方法:
class Animal {
private String name="Animal";
public String getName() {
return this.name;
}
}
class Cat extends Animal {
public String getName() {
return "Cat";
}
}
您也可以在子类中声明一个不同的字段,但这仍然是一个坏主意。 做到这一点的“正确”方法是覆盖该方法。
或者,将字段暴露给子类,并更改子类的值:
class Animal {
protected String name = "Animal";
public String getName() {
return name;
}
}
class Cat extends Animal {
public Cat() {
this.name = "Cat";
}
}
这样,就不会混淆哪个字段存储实际值,并且“覆盖”发生的位置很清楚。
在 Cat 类中添加一个同名的私有作用域变量不会掩盖 Animal 类中的变量。 要更改行为,您需要覆盖访问器方法以从 Cat 类上下文中读取变量。
您可以重载方法,而不是数据成员。 Animal.name
和Cat.name
是两个不同的数据成员。 Animal.getName()
没有什么特别之处——它返回Animal.name
,并且完全不知道Cat.name
。
一种可能的方法是只有一个数据成员Animal.name
,并让每个类对其进行不同的初始化。 例如:
class Animal {
private String name;
public Animal() {
this("Animal);
}
protected Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Cat extends Animal {
public Cat() {
this("Cat');
}
}
或者如果你想依赖你的类名,你可以使用getSimpleName
:
class Animal {
private String name;
public Animal() {
name = getClass().getSimpleName();
}
public String getName() {
return name;
}
}
class Cat extends Animal {
}
这是因为cat.getName()
调用Animal
类中的getName()
方法,该方法只知道自己的name
字段,而不知道子类之一。
一个可能的解决方案可能是:
class Animal {
private String name = "Animal";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Cat extends Animal {
private String name = "Cat";
public Cat() {
setName(name);
}
}
public class Test {
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(cat.getName());
}
}
我不鼓励你重写方法,因为你应该在未来的每个Animal
子类上都这样做。
您需要覆盖方法 getName()。 它是实例级函数,您可以在子类中调用它,但如果不覆盖该函数,则无法修改它。 所以它使用父类属性调用父类函数。
如果您想在输出中使用“cat”,只需覆盖该方法。
接受的答案涵盖了一些很好的答案,但我想添加一些内容。
例如。
class Animal {
protected String name;
public Animal() {
this.name = "Animal";
}
public String getName() {
return this.name;
}
}
class Cat extends Animal {
public Cat() {
this.name = "Cat";
}
}
例如。
class Animal {
private String name = "Animal";
public String getName() {
return this.name;
}
protected void setName(String name) {
this.name = name;
}
}
class Cat extends Animal {
public Cat() {
setName("Cat");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.