我是Java的新手。所以问题可能听起来很简单,但我陷入困境,无法弄清楚为什么这段代码会返回null和0.0?
file:Transport.java
public class Transport { private String name; private double price; public Transport(String name, double price) { this.name = name; this.price = price; } public String carName() { return name; } public double carPrice(){ return price; } }
文件:Car.java
public class Car extends Transport{ protected String name; protected double price; public Car(String name, double price) { super(name, price); } @Override public String carName(){ return name; } @Override public double carPrice(){ return price * 1.5; } }
file:Main.java
public class Main { public static void main(String[] args) { Car c = new Car("CarBrand", 1000); System.out.println("Name: " + c.carName()); System.out.println("Price: " + c.carPrice()); } }
输出
Name: null Price: 0.0
答案 0 :(得分:8)
您已在name
中声明了单独的 price
和Car
个变量,并且从未为它们分配过值 - 它们与name
中声明(并初始化)price
和Transport
个变量。因此,您基本上会看到String
和double
的默认值。在Car
中删除这些额外变量,并使用super.carPrice()
从Transport
获取原始价格:
public class Car extends Transport {
public Car(String name, double price) {
super(name, price);
}
@Override
public double carPrice(){
return super.carPrice() * 1.5;
}
}
请注意,除非确实希望它改变行为,否则根本不需要覆盖carName()
。
我还建议将carName()
和carPrice()
更改为getName()
和getPrice()
更加惯用。
答案 1 :(得分:1)
您正在通过super()将这两个值传递给父类Transport。所以
Car c = new Car("CarBrand", 1000);
最终将设置
传输类属性名称&价。
您不需要在Car类中声明这两个属性。 Car将通过继承隐式地拥有这两个属性。在这里,您将为Car创建单独的属性。
答案 2 :(得分:0)
问题是name
有两个不同的变量,一个在Car中,一个在Transport中。 c.carName()
返回尚未初始化的Car.name
。
如果您的汽车类别是下面的汽车类别,那么它将起作用
public class Car extends Transport {
public Car(String name, double price) {
super(name, price);
}
@Override
public double carPrice(){
return price * 1.5;
}
}
变量price
答案 3 :(得分:0)
派生类Car
隐藏了类Transport
的实例变量。虽然您从Transport
类继承了正确初始化的数据成员,但是Car
类初始化为默认值的实例变量将从Car
类方法返回
答案 4 :(得分:0)
在创建Car类型的'c'对象时,仅为Transport类的'name'和'price'变量分配值(因为在构造函数中,您调用super(name,price)会从中调用构造函数)您的家长班)。
在这里:c.carName()从Car类中调用该方法(因为标记为@Override),并且此方法从Car类返回'name'变量的值。在您的情况下,此变量为null,因为您尚未为其分配任何值。 您为“运输”类型的“名称”变量分配了“ CarBrand”值。 对于“ price”变量也是如此。
答案 5 :(得分:0)
使用super将通过调用构造函数super(name,price)返回您已经存储在父类中的值,使用super后接点符号将访问父类方法。因此super.carPrice()将返回存储在父类中的值。
此外,@ Override批注仅应用于更改父类中的现有方法,并在子类中使用新功能,而无需更改名称。因此,在@overide for carname()的情况下,您需要调用super.carname(),因为您是从父类中返回值。
简而言之,为什么当您应该访问父类值时访问子类值而得到null和0.0的原因。
public class Car extends Transport{
protected String name;
protected double price;
public Car(String name, double price) {
super(name, price);
}
@Override
public String carName(){
return name;
}
@Override
public double carPrice(){
return price * 1.5;
}
}
Your class should be
public class Car extends Transport{
public Car(String name, double price) {
super(name, price);
}
public String getName(){
return super.carName();
}
@Override
public double carPrice(){
return super.carPrice()* 1.5;
}
}
您的主要班级现在应该是
public class Main {
public static void main(String[] args) {
Car c = new Car("CarBrand", 1000);
System.out.println("Name: " + c.getName());
System.out.println("Price: " + c.carPrice());
}
}