-4

关于这段代码的一些事情让我感到困惑。第一个打印行是 1600。我知道这与静态类是 Car 而不是 Sportscar 有关。但是我们将对象创建为跑车,那么为什么体积字段不是 3500?谢谢。

 public class Car {
 public int volume;

 public Car() { this(1600); }
 public Car(int volume) { this.volume = volume; }
 public String toString() { return "Car:" + volume; }
 }



 public class SportsCar extends Car {
 public int volume;

 SportsCar() { this(3000); }
 SportsCar(int volume) { this.volume = volume; }
 public String toString() {return "SportsCar:"+volume;}
 }



 public class CarApplication {
 public static void main(String [] args) {
 Car car = new SportsCar(3500);

 System.out.println(car.volume);
 System.out.println(car.toString());
 System.out.println(car);
 }
 } 
4

4 回答 4

2

首先,请注意,当您调用SportsCarJava 的构造函数时,会自动调用其父类的默认构造函数,Car. 这会将volume对象父Car类的字段设置为 1600。

在 Java 中,字段没有多态性。因此,尽管类中的toString()方法SportsCar总是覆盖其父Car类 ( ) 的方法,但访问同名实例变量的规则略有不同。

如果您volumeSportsCar类中访问,则将使用volumeof SportsCar。从类本身外部(因此当您调用 from 时CarApplication)访问哪个实例变量取决于相关对象的编译时类型。因为您将类型声明car为 a Car,所以使用volumeCar类的值 - 因此打印 1600。如果您改为声明car为 a SportsCar,则会打印 3500 。

另一种选择是:

System.out.println(((SportsCar)car).toString());

这将输出 3500,因为类型car已转换为SportsCar.

于 2016-06-29T18:49:36.820 回答
1

当您以这种方式声明某些内容时:

ParentClass variable = new ChildClass(Args);

中的方法和字段ParentClass是您唯一可用的。它受到限制,因为您将类型声明为ParentClass. 因为Car' 的体积是 1600 并且对象仅限于ParentClass' 的方法和字段,所以它打印 1600。

一个例子如下:

考虑我有一个 Apple 课程和一个 Fruit 课程:

public class Fruit {
    private String type;

    public Fruit(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}

苹果类:

public class Apple extends Fruit {
     private String variant;

     public Apple(String variant) {
          System.out.println("I like " + variant + apples too!");
          super("Apple");
     }

     public String getVariant() {
          return variant;
     }
}

现在我像这样实例化:

Fruit ap = new Apple("Fiji");

我无权访问getVariant()Apple 类中的任何方法,因为该类型属于父类,而不是 Apple。我能做到,getType()但仅此而已。

在你的情况下:

public class SportsCar extends Car {
    public int volume;

    SportsCar() {
        this(3000); 
    }

    SportsCar(int volume) { 
        this.volume = volume; 
    }

    public String toString() {
        return "SportsCar:"+volume;
    }
}

虽然SportsCar它有自己的构造函数并接受它自己的卷,但父类Car是实际类型,导致Car构造函数被调用,因此设置volume为 1600。要指定SportsCar对象,请执行以下操作:

SportsCar sc = new SportsCar(3500);
System.out.print(sc.toString());

这将打印出:

SportsCar:3500

你也可以像这样对它进行类型转换:

Car c = new SportsCar(1600);
System.out.print(((SportsCar) c).toString());
于 2016-06-29T18:24:42.630 回答
1

所以这里的重点是,当你使用 car.volume 时,car 变量是 Car 类型,对象引用是 SportsCar 类型。

由于这两个类具有相同的名为 volume 的元素,并且您试图通过父对象变量引用它,因此它返回 1600。

如果您要进行类型转换然后检查音量,它将按照以下代码返回 3500:

System.out.println(((SportsCar)car).volume);
于 2016-06-29T18:34:16.240 回答
0

Aman Chhabra 的回答是正确的。您创建了一个来自 Car“家族”的 SportCar 对象。你打印的是 Car 的体积,而不是 SportCar 的体积。

另一种方法是创建一个 SportsCar 对象而不是 Car。

Ps:您应该始终将您的类属性设置为私有 :)

于 2016-06-29T18:42:59.960 回答