我有一个包含许多子类的类,但是当将子类实例传递给某个应该接收超类实例的方法时,子类的属性会被覆盖。
例如,以下代码打印0.我应该怎么做才能打印子类参数值?
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);
}
}
答案 0 :(得分:2)
虽然字段可以在继承中共享,但是给定正确的访问修饰符(即任何不是private
的东西 - 默认访问不会在不同的包中工作),它们在编译时解析,与方法相反在运行时解析(后者称为虚方法调用)。
int
默认为0
,并且您传递了A
引荐类型,因此A.cost
的值为{{1}打印。
您可以在此处获得一系列选项:
0
,并在cost
的构造函数或实例初始化程序等中B
分配cost
值。到A
B
中一个丑陋的,明确的演员表,例如10
method4A
System.out.println(((B)a).cost);
引荐类型而非B
A
个变量,并在method4A
cost
中声明一个简单的getter,并在A
中使用相同的实现声明cost
(&#39} ;即使在@Override
引用上调用,如果实例实际为B
),也会返回B
的费用答案 1 :(得分:1)
你可以使用方法覆盖这样的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());
}
}
答案 2 :(得分:1)
您的问题与覆盖没有任何关系。
在两个类(类和子类)中声明两次相同的字段可能容易出错 你真的需要定义两个不同的领域吗? 为什么不在子类中重用父类的字段或提供访问权限?
当然,在某些特定情况下,定义两个不同的字段是可以接受的,但是对于这些情况,通常使用private
修饰符来隔离它们。
定义此类行为的一种自然方式是为private
提供cost
字段,在父类中提供getter和setter。
通过这种方式,子类可以对该字段进行赋值/设置
例如,它可以从其构造函数中对该字段进行值:
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());
}
}