自从我弄乱了Java抽象和/或接口以来已经有很长一段时间了,但我现在回过头来讨论一个项目而且让我感到紧张。下面是我的代码片段。
public class A {
private static String name = "None";
private static String description = "No description";
public A() {}
public A(User user) {
user.setData(this);
}
public static String getName() {
return name;
}
public static String getDescription() {
return description;
}
}
public class B extends A {
private static String name = "B";
private static String description = "This is B";
public B() {}
public B(User user) {
super(user);
}
}
public class User {
private A a;
public void setData(A a) {
this.a = a;
}
public A getData() {
return a;
}
}
当我使用B.getName()
时,我希望它返回"B"
,但它会返回"None"
。
现在我显然做错了什么,四处寻找并没有帮助。我非常肯定这是可能的,除非我对另一种语言感到困惑。
有人可以指出我正确的方向吗?感谢。
答案 0 :(得分:4)
你在类B上调用了getName方法.B没有一个名为getName的静态方法,因此它在超类A中查找它。
也许您希望B的版本名称覆盖A?变量不会被覆盖。 A正在访问在A上定义的静态变量名,该方法最初在B上调用不会影响它。
继承和静态方法不能很好地协同工作。像多态这样的OO概念依赖于运行时调度,单词static
应该意味着与之相反。使用多态性,程序在高级抽象中工作,通过超类型引用对象并让子类计算出细节。使用静态方法,您必须引用您希望调用该方法的特定子类,因此您没有这种抽象级别。
答案 1 :(得分:2)
再次欢迎回到Java。 您在A类和B类中使用静态变量。这些变量与类而不是对象相关联。
如果您更改方法以从用户获取名称,它将按预期工作。
答案 2 :(得分:0)
您需要覆盖方法getName():
public class B extends A {
private static String name = "B";
private static String description = "This is B";
public B() {}
@Override
public static String getName() {
return name;
}
public B(User user) {
super(user);
}
}
答案 3 :(得分:0)
您面临的问题在于方法getName
和getDescription
的定义:它们在类A
中定义为静态成员。这意味着即使在调用B.getName()
时,实际调用为A.getName()
,并且name
的静态成员变量值也设置为None
。
在考虑继承时,你要小心你所声称的静态。这与接口或抽象类无关。
public class A {
protected String name = "None";
protected String description = "No description";
public A() {}
public A(User user) {
user.setData(this);
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
}
public class B extends A {
public B() {
name = "B";
description = "This is B"
}
public B(User user) {
super(user);
}
}
public class User {
private A a;
public void setData(A a) {
this.a = a;
}
public A getData() {
return a;
}
}
使用protected
关键字,您可以访问扩展类中的字段。
另见:
答案 4 :(得分:0)
班上有几点需要注意:
静态变量绑定到类,静态方法不能被重写
答案 5 :(得分:0)
这是预期的行为,因为类A的getName()方法可以访问它自己的类的成员变量,它是类A的“名称”。由于名称是不 > static 即使您将其设置为非静态并且您访问它,如下面的代码段所示,它将返回“None”。请记住,只有方法被覆盖而不是成员变量。因此,B类的“名称”不会覆盖“A”类的“名称”。
auto confirmOperation = [](auto pr) ->
std::enable_if_t<std::is_same<decltype(pr.second), bool>::value> {
assert(pr.second);
};
另外,如果要将“B”作为输出,请覆盖B类中A类的getName()方法,并使方法和变量非静态。