超类属性覆盖子类属性
superclass attribute overrides subclass attribute
我有一个包含许多子class的class,但是当将一个子class实例传递给某个应该接收super[=15实例的方法时=],子class的属性被覆盖
例如下面的代码打印0,我应该怎么做才能打印subclass参数值?
class A{
int cost;
}
class B extends A{
int cost = 10;
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.cost);
}
}
虽然字段可以在继承中共享,但如果有正确的访问修饰符(即任何不是 private
的东西 - 默认访问将不会跨不同的包工作),它们在编译时解析,相反在运行时解析的方法(后者称为虚拟方法调用)。
int
s 默认为 0
,并且您传递的是 A
引用类型,因此打印 A.cost
的 0
值.
这里有多种选择:
- 不要在
B
中声明 cost
并在 B
的构造函数或实例初始化程序等中将 A
中的 cost
值分配给10
method4A
中的丑陋、明确的转换,例如System.out.println(((B)a).cost);
- 在
method4A
中传递 B
引用类型而不是 A
- 保留两个
cost
变量并在 A
returning cost
中声明一个简单的 getter,并在 [=] 中声明 @Override
17=] 具有相同的实现(如果实例实际上是 B
,即使在 A
引用上调用它也会 return B
的成本)
您可以像这样使用带有 getter 的方法覆盖:
class A {
int cost;
public int getCost() {
return cost;
}
}
class B extends A {
int cost = 10;
public int getCost() {
return cost;
}
}
class Test {
public static void main(String[] args) {
B b = new B();
method4A(b);
}
static void method4A(A a) {
System.out.println(a.getCost());
}
}
你的问题与覆盖没有任何关系。
在两个 classes(class 和 subclass)中声明两次相同的字段可能是 error-prone。
您真的需要定义两个不同的字段吗?
为什么不在子 class 中重用父 class 的字段或提供对 的访问权限?
当然,在某些特定情况下,定义两个不同的字段是可以接受和可取的,但对于这些情况,通常您使用 private
修饰符来隔离它们。
定义此类行为的一种自然方式是在父级 class 中为 cost
和 getter 以及 setter 提供一个 private
字段。
这样subclass就有办法value/set这个字段了
例如,它可以从其构造函数中为字段赋值:
class A{
private int cost;
public void setCost(int cost){
this.cost = cost;
}
public int getCost(){
return cost;
}
}
class B extends A{
public B(){
this.setCost(10);
}
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.getCost());
}
}
我有一个包含许多子class的class,但是当将一个子class实例传递给某个应该接收super[=15实例的方法时=],子class的属性被覆盖
例如下面的代码打印0,我应该怎么做才能打印subclass参数值?
class A{
int cost;
}
class B extends A{
int cost = 10;
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.cost);
}
}
虽然字段可以在继承中共享,但如果有正确的访问修饰符(即任何不是 private
的东西 - 默认访问将不会跨不同的包工作),它们在编译时解析,相反在运行时解析的方法(后者称为虚拟方法调用)。
int
s 默认为 0
,并且您传递的是 A
引用类型,因此打印 A.cost
的 0
值.
这里有多种选择:
- 不要在
B
中声明cost
并在B
的构造函数或实例初始化程序等中将A
中的cost
值分配给10
method4A
中的丑陋、明确的转换,例如System.out.println(((B)a).cost);
- 在
method4A
中传递 - 保留两个
cost
变量并在A
returningcost
中声明一个简单的 getter,并在 [=] 中声明@Override
17=] 具有相同的实现(如果实例实际上是B
,即使在A
引用上调用它也会 returnB
的成本)
B
引用类型而不是 A
您可以像这样使用带有 getter 的方法覆盖:
class A {
int cost;
public int getCost() {
return cost;
}
}
class B extends A {
int cost = 10;
public int getCost() {
return cost;
}
}
class Test {
public static void main(String[] args) {
B b = new B();
method4A(b);
}
static void method4A(A a) {
System.out.println(a.getCost());
}
}
你的问题与覆盖没有任何关系。
在两个 classes(class 和 subclass)中声明两次相同的字段可能是 error-prone。
您真的需要定义两个不同的字段吗?
为什么不在子 class 中重用父 class 的字段或提供对 的访问权限?
当然,在某些特定情况下,定义两个不同的字段是可以接受和可取的,但对于这些情况,通常您使用 private
修饰符来隔离它们。
定义此类行为的一种自然方式是在父级 class 中为 cost
和 getter 以及 setter 提供一个 private
字段。
这样subclass就有办法value/set这个字段了
例如,它可以从其构造函数中为字段赋值:
class A{
private int cost;
public void setCost(int cost){
this.cost = cost;
}
public int getCost(){
return cost;
}
}
class B extends A{
public B(){
this.setCost(10);
}
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.getCost());
}
}