gpt4 book ai didi

java - 抽象类的集合(或类似的东西......)

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:06:24 25 4
gpt4 key购买 nike

场景

我正在用 Java 编写一个涉及汽车的程序。

注意:我已(尽我所能)简化了此场景,使其更通用且更易于理解。我实际上并不是在研究汽车。

我创建了一个 Cars 类,它是 Car 对象的集合。

Car 对象有一个 speed (double) 和一个 year (int)。构造函数将年份作为参数,例如:

public class Car {
private int year;
private double speed;

public Car(int year) {
this.year = year;
}
}

这是棘手的部分……汽车必须有一个种类(比如 Corvette 或 Clunker)。 Corvette 的 speed0.9,而 Clunker 的 speed0.1Car 永远不能在不指定它应该是哪种汽车的情况下被实例化。所以现在,要制造一辆汽车,我们有:

Car car = new Car(1998, Corvette);

我们刚刚创建的 Corvette 将是 Car 对象,speed0.9

问题

我的实际情况涉及更多种类的汽车,每辆汽车除了speed之外还有几个特定的​​属性(也许还有colornumDoors<的字段fuelTankSize)。有这么多种类的汽车(每一种都有自己的特定属性),代码变得比我想要的更复杂。

可能的解决方案

  1. 我可以使用子类,也就是说,有一个由 CorvetteClunker 扩展的抽象 Car 类,但是然后我遇到了使用 Cars 对象的问题(因为我无法收集无法实例化的东西)。 请参阅下面的编辑。

  2. 使用枚举(例如 CarKind)似乎需要几个凌乱的 switch 语句:

    • 填充每辆车的speed字段
    • Cars 类创建 Car 对象
    • 等等

您可以如何提供帮助

我正在寻找一种解决方案,允许单个 Cars 类包含每个 Car 对象。我想要不同的 Collection (例如CorvettesClunkers)。我也在寻找一种解决方案,允许根据单个汽车种类的属性创建 Car 对象...如前所述,创建一个新的 Car kind Corvette 将导致 speed0.9。应该没有其他方法可以指定汽车的速度

在这种情况下是否有最佳实践?我举的例子够清楚了吗?

谢谢。

编辑:我不想要抽象 Car 对象集合的原因是 Cars 集合的目的是创建和操作 Car 对象,无论其种类如何。 Car 是抽象的似乎使这个复杂化。如果您认为这是最佳解决方案,请做出相应的回答。

最佳答案

I'm looking for a solution that allows a single Cars class to contain every Car object. I don't want different collections (like Corvettes, Clunkers). I'm also looking for a solution that allows the creation of Car objects based on the attributes of an individual car kind... as previously mentioned, creating a new Car of kind Corvette would result in a speed of 0.9. There should be no other way to specify a car's speed.

天哪,天哪,解决这个问题的方法太多了,我们可以继续一整天!我会做一个大脑转储,希望它不会对你来说太难处理。


解决方案 1:使用策略。

策略基本上是一种将繁重的可替代逻辑与另一个类分开的方法。在这种情况下,每辆车都需要以不同的方式创建。一个策略是完美的。

抱歉,如果我不小心混入了一些 C#...我已经很久没有使用 Java 了。

public interface CarCreationStrategy{
void BuildCar(Car theCar);
}

public class CorvetteStrategy implements CarCreationStrategy{
public void BuildCar(Car theCar){
theCar.Type = "Corvette";
theCar.Speed = 0.9;
theCar.Comments = "Speedster!";
}
}

public class ToyotaStrategy implements CarCreationStrategy{
public void BuildCar(Car theCar){
theCar.Type = "Toyota";
theCar.Speed = "0.5";
theCar.Comments = "Never dies, even if you drop it from the top of a building";
}
}

现在,您可以将策略传递给您的汽车制造商。

public class Car{
// Variables ...

public Car(CarCreationStrategy strategy, int year){
strategy.BuildCar(this); // Implements your properties here.
this.year = year;
}
}

所以,你现在得到的真是太棒了!

List<Car> cars = new List<Car>();
cars.Add(new Car(new CorvetteStrategy(),1999));
cars.Add(new Car(new ToyotaStrategy(),2011);

这将完全按照您的意愿行事。

但是,您会在策略和汽车之间建立耦合。


解决方案 2:使用 Factory。

Factory 也是一个不错的解决方案,而且可能更容易。您要做的是拥有一个 CarFactory,其中包含用于创建每种类型汽车的多个工厂方法。

public class CarFactory{
public static Car BuildCorvette(int year){
Car car = new Car(year);
car.Type = "Corvette;
car.Speed = 0.9";
return car;
}

public static Car BuildToyota(int year){
Car car = new Car(year);
car.Type = "Toyota;
car.Speed = 0.5";
return car;
}
}

用法:

List<Car> cars = new List<Car>();
cars.Add(CarFactory.BuildCorvette(1999));
cars.Add(CarFactory.BuildToyota(2011));

所以这样做的好处是您现在不必担心实例化 Car。它全部由 CarFactory 处理,将您的“实例化逻辑”与您的代码分离。但是,您仍然需要知道要构建哪辆车并相应地调用该方法,这仍然是一个小耦合。


方案三:策略工厂!

因此,如果我们想摆脱最后一点耦合,就让我们将两者结合起来吧!

public class CarFactory{
public static Car BuildCar(CarCreationStrategy strategy, int year){
Car car = new Car(year);
strategy.BuildCar(car);
return car;
}
}

List<Car> cars = new List<Car>();
cars.Add(CarFactory.BuildCar(new CorvetteStrategy(),1999));
cars.Add(CarFactory.BuildCar(new ToyotaStrategy(),2011);

现在您有了一个制造汽车的策略,一个为您制造汽车的工厂,以及一辆没有您原来的额外耦合器的汽车。很棒,不是吗?

如果您使用过 Swing,您会注意到这就是它们处理 Layouts 等一些事情的方式(GridBagLayout、GridLayout 都是策略)。还有一个 BorderFactory。


改进

抽象策略

public interface CarCreationStrategy{
void BuildCar(Car theCar);
}

public class AbstractStrategy:CarCreationStrategy{
public string Type;
public double Speed;
public string Comments;

public void BuildCar(Car theCar){
theCar.Type = this.Type;
theCar.Speed = this.Speed;
theCar.Comments = this.Comments;
}
}

public class CorvetteStrategy extends AbstractStrategy{
public CorvetteStrategy(){
this.Type = "Corvette";
this.Speed = 0.9;
this.Comments = "Speedster!";
}
}

public class ToyotaStrategy extends AbstractStrategy{
public ToyotaStrategy{
this.Type = "Toyota";
this.Speed = "0.5";
this.Comments = "Never dies, even if you drop it from the top of a building";
}
}

使用它可以让您灵活地动态创建 AbstractStrategies(例如,从数据存储中提取汽车属性)。

关于java - 抽象类的集合(或类似的东西......),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7493438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com