我车库里真的有车吗? [英] Do I really have a car in my garage?
问题描述
我是Java编程的新手,试图掌握OOP。
I'm a newbie to Java programming, trying to get the hang of OOP.
所以我构建了这个抽象类:
So I built this abstract class:
public abstract class Vehicle{....}
和2个子类:
public class Car extends Vehicle{....}
public class Boat extends Vehicle{....}
汽车
和 Boat
还包含一些不常见的唯一字段和方法(不具有相同的名称,因此我无法为它们定义抽象方法)车辆)。
Car
and Boat
also hold some unique fields and methods that aren't common (don't have the same name, so I can't define an abstract method for them in Vehicle).
现在在mainClass我设置了我的新车库:
Now in mainClass I have setup my new Garage:
Vehicle[] myGarage= new Vehicle[10];
myGarage[0]=new Car(2,true);
myGarage[1]=new Boat(4,600);
我对多态性感到非常满意,直到我尝试访问Car独有的字段之一,例如:
I was very happy with polymorphism until I tried to access one of the fields that are unique to Car, such as:
boolean carIsAutomatic = myGarage[0].auto;
编译器不接受。我使用强制转换解决了这个问题:
The compiler doesn't accept that. I worked around this issue using casting:
boolean carIsAutomatic = ((Car)myGarage[0]).auto;
这有效......但它对方法没有帮助,只是字段。意思是我做不到
That works... but it doesn't help with methods, just fields. Meaning I can't do
(Car)myGarage[0].doSomeCarStuff();
所以我的问题是 - 我的车库里到底有什么?我试图获得直觉以及了解幕后发生了什么。
So my question is - what do I really have in my garage? I'm trying to get the intuition as well as understand what's going on "behind the scenes".
为了这个缘故未来的读者,以下答案的简短摘要:
for the sake of future readers, a short summary of the answers below:
- 是的,有一个
汽车
inmyGarage []
- 作为一种静态类型语言,Java编译器不会提供对非方法/字段的访问权限 - 车辆,如果通过基于Vehicle超级类的数据结构访问它们(例如
Vehicle myGarage []
) - 至于如何解决,有以下两种主要方法:
- Yes, there's a
Car
inmyGarage[]
- Being a static typed language, the Java compiler will not lend access to methods/fields that are non-"Vehicle", if accessing those through a data structure based on the Vehicle super class( such as
Vehicle myGarage[]
) - As for how to solve, there are 2 main approaches below:
- 使用类型转换,这将减轻编译器的顾虑并将设计中的任何错误留给运行时间
- 我需要铸造的事实说设计存在缺陷。如果我需要访问非车辆功能,那么我不应该将汽车和船只存储在基于车辆的数据结构中。要么使所有这些功能属于Vehicle,要么使用更具体(派生)类型的结构
推荐答案
如果你需要区分 Car 你的车库里有code>和
船
,那么你应该将它们存放在不同的结构中。
If you need to make the difference between Car
and Boat
in your garage, then you should store them in distinct structures.
例如:
public class Garage {
private List<Car> cars;
private List<Boat> boats;
}
然后,您可以定义特定于船只或特定于汽车的方法。
Then you can define methods that are specific on boats or specific on cars.
假设车辆
如下:
public abstract class Vehicle {
protected int price;
public getPrice() { return price; }
public abstract int getPriceAfterYears(int years);
}
每个车辆
有一个价格,所以它可以放在 Vehicle
抽象类中。
Every Vehicle
has a price so it can be put inside the Vehicle
abstract class.
然而,确定n后价格的公式几年取决于车辆,所以它留给实施班来定义它。例如:
Yet, the formula determining the price after n years depends on the vehicle, so it left to the implementing class to define it. For instance:
public Car extends Vehicle {
// car specific
private boolean automatic;
@Override
public getPriceAfterYears(int years) {
// losing 1000$ every year
return Math.max(0, this.price - (years * 1000));
}
}
船
class可能有 getPriceAfterYears
的其他定义以及特定的属性和方法。
The Boat
class may have an other definition for getPriceAfterYears
and specific attributes and methods.
所以现在回到 Garage
类,你可以定义:
So now back in the Garage
class, you can define:
// car specific
public int numberOfAutomaticCars() {
int s = 0;
for(Car car : cars) {
if(car.isAutomatic()) {
s++;
}
}
return s;
}
public List<Vehicle> getVehicles() {
List<Vehicle> v = new ArrayList<>(); // init with sum
v.addAll(cars);
v.addAll(boats);
return v;
}
// all vehicles method
public getAveragePriceAfterYears(int years) {
List<Vehicle> vehicules = getVehicles();
int s = 0;
for(Vehicle v : vehicules) {
// call the implementation of the actual type!
s += v.getPriceAfterYears(years);
}
return s / vehicules.size();
}
多态的兴趣是能够调用 getPriceAfterYears
在车辆
没有关心实施。
The interest of polymorphism is to be able to call getPriceAfterYears
on a Vehicle
without caring about the implementation.
通常,向下转向是设计有缺陷的标志:如果您需要区分其实际类型,请不要将您的车辆全部存放在一起。
Usually, downcasting is a sign of a flawed design: do not store your vehicles all together if you need to differenciate their actual type.
注意:当然是设计这里可以轻松改进。这只是一个展示要点的例子。
Note: of course the design here can be easily improved. It is just an example to demonstrate the points.
这篇关于我车库里真的有车吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!