【问题标题】:Method override returns null方法覆盖返回 null
【发布时间】:2014-11-21 22:52:26
【问题描述】:

我是 Java 新手。所以问题可能听起来很简单,但我被卡住了,无法弄清楚为什么这段代码返回 null 和 0.0 ?

文件:Transport.java

公共类运输{

        私有字符串名称;
        私人双倍价格;

    公共交通(字符串名称,双倍价格){
        this.name = 名称;
        this.price = 价格;
    }

    公共字符串车名(){
        返回名称;
    }

    公共双车价格(){
        退货价格;
    }
}

文件:Car.java

公共类汽车扩展运输{

    受保护的字符串名称;
    受保护的双倍价格;

    公共汽车(字符串名称,双倍价格){
        超级(名称,价格);
    }

    @覆盖
    公共字符串车名(){
        返回名称;
    }

    @覆盖
    公共双车价格(){
        返回价格 * 1.5;
    }
}

文件:Main.java

公共类主要{
    公共静态无效主要(字符串[]参数){

        汽车 c = new Car("CarBrand", 1000);

        System.out.println("名称:" + c.carName());
        System.out.println("价格:" + c.carPrice());
    }
}

输出

名称:空
价格:0.0

【问题讨论】:

  • 如果你的类名为“Car”,通常不需要将“car”放在属性名称中。您可能还想尽早习惯重要的 bean 模式,并通过“get”和“set”为属性访问器添加前缀。考虑这样的名称: Car myCar = new Car(...), myCar.getname()

标签: java overriding


【解决方案1】:

您已经在Car 中声明了单独 nameprice 变量,并且从未为它们赋值 - 它们与 name 和 @987654325 不同@在Transport 中声明(和初始化)的变量。所以你基本上看到了Stringdouble 的默认值。去掉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() 以更加地道。

【讨论】:

  • 好的,知道了。但是从Car类调用方法carPrice()的正确方法是什么?
  • @Gerardas:我不确定你的意思。我在答案中向您展示了如何从Car 调用Transport 实现以调用原始方法,该方法仅返回price 变量...使用我的答案中的代码替换您的类,那就是所有你需要做的。
  • 写评论的时候上面没有代码...谢谢你的帮助! :)
  • @Gerardas 调用继承方法的正确方法是:c.carPrice() - 如果它在您的上下文中可见(取决于它是否是公共的、包私有的、受保护的),它只会就像你在 Car 中声明一样。
【解决方案2】:

问题是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也是如此

【讨论】:

  • 这个更正给出了错误:Exception in thread "main" java.lang.Error: Unresolved compilation problem: The field Transport.price is not visible
【解决方案3】:

派生类Car隐藏了类Transport的实例变量。所以虽然你从Transport类继承了正确初始化的数据成员,但是初始化为默认值的Car类实例变量是从Car 类方法返回

【讨论】:

    【解决方案4】:

    您正在通过 super() 将这两个值传递给父类 Transport。所以

    Car c = new Car("CarBrand", 1000);
    

    最终会设置

    运输类属性名称和价格。

    你不需要在 Car 类中声明这两个属性。 Car 将通过继承隐式地具有这两个属性。在这里,您正在为 Car 创建单独的属性。

    【讨论】:

      【解决方案5】:

      当您创建 Car 类型的 'c' 对象时,您只为 Transport 类的 'name' 和 'price' 变量赋值(因为在您的构造函数中,您调用 super(name, price) 将调用构造函数你的父类)。

      这里: c.carName() 您从 Car 类调用方法(因为被标记为 @Override),这个方法从 Car 类返回“name”变量的值。在您的情况下,此变量为 null ,因为您尚未为其分配任何值。 您为 Transport 类型的“名称”变量分配了值“CarBrand”。 'price' 变量也是如此。

      【讨论】:

        【解决方案6】:

        使用 super 将通过调用构造函数 super(name, price) 返回您已经存储在父类中的值,使用 super 后跟点符号将访问父类方法。所以 super.carPrice() 会返回父类中存储的值。

        另外,@Override 注释应该只用于更改父类中的现有方法,并在子类中使用新功能而不更改名称。因此,对于 carname() 的 @Overide,您需要调用 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());
        
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-16
          • 2012-11-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多