当前位置: 首页 > 面试题库 >

抽象类的集合(或类似的东西……)

况博容
2023-03-14
问题内容

场景

我正在用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)。克尔维特(克尔维特)的车子speed0.9and,Cl子(Clunker)的车子为speed0.1。)。如果Car不指定它应该是哪种汽车,就永远无法实例化。所以现在,要制造一辆汽车,我们有:

Car car = new Car(1998, Corvette);

我们刚刚创建的克尔维特将是一个Car具有对象speed0.9

问题

我的实际情况,涉及许多种以上的汽车,每节车厢有几个特定的属性以外speed(也许还有用于场colornumDoorsfuelTankSize)。有了如此多的汽车(每种汽车都有自己的特定属性),代码变得比我想要的更加复杂。

可能的解决方案

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

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

    • 填充speed每辆车的场地
    • CarCars类创建对象
    • 等等

您将如何提供帮助

我正在寻找一种允许单个Cars类包含每个Car对象的解决方案。我
希望不同的集合(如CorvettesClunkers)。我也在寻找一种解决方案,该解决方案允许Car基于单个汽车种类的属性来创建对象…如前所述,创建新Car种类Corvette将导致speed0.9。没有其他方法可以指定汽车的speed

在这种情况下是否有最佳实践?我已经把例子弄清楚了吗?

谢谢。

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


问题答案:

我正在寻找一种允许单个Cars类包含每个Car对象的解决方案。我不想要其他系列(例如Corvettes,Clunkers)。我也在寻找一种解决方案,该解决方案允许根据单个汽车类型的属性创建Car对象…如前所述,创建新的Corvette类型的Car的速度为0.9。没有其他方法可以指定汽车的速度。

哦,男孩,哦,男孩,有很多方法可以解决这个问题,我们可以整天去!我会动脑筋,希望您处理的不会太多。

解决方案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);

而这正是您想要的。

但是,您会在策略和Car之间取得联系。

解决方案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处理,将您的“实例化逻辑”与代码分离。但是,您仍然需要知道要构建的汽车并相应地调用该方法,这仍然很小。

解决方案3:战略工厂!

因此,如果我们想摆脱最后的耦合,就可以将两者结合在一起!

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,您会注意到,这就是它们处理诸如布局(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(例如,从数据存储中提取汽车属性)。



 类似资料:
  • 问题内容: 我正在尝试制作一个按钮,以便用户单击它时,按住鼠标按钮时它会更改其样式。如果在移动浏览器中触摸它,我也希望它以类似的方式更改其样式。对我来说,看似显而易见的事情是使用CSS:active伪类,但这没有用。我尝试了:focus,但是也没有用。我尝试:hover,它似乎起作用了,但是当我将手指从按钮上移开后,它仍然保持了样式。所有这些观察都是在iPhone 4和Droid 2上进行的。 有

  • 我正在处理一个项目的pull请求,有人告诉我,将两个类似类的代码组合成一个抽象类可能是个好主意,其他两个类将从中扩展。我的问题是我没有正确的方法来做这件事。以下是两个课程: 第二点是: 不同之处在于Constructor()、open()和nextRecord()方法以及resultSet变量。一班和二班也有。我假设open和nextRecord方法只是不在抽象基类中实现它们,而让它们在类一和类二

  • 问题内容: 我正在学习PHP5(上次检查PHP是在PHP4天内),我很高兴看到PHP5 OO比PHP4更像Java,但是仍然有一个问题使我感到非常困惑,因为我的Java背景:阵列。 我正在阅读“ Proffesional PHP6”(Wrox),它显示了自己的Collection实现。我在基于SPL的http://aheimlich.dreamhosters.com/generic- collec

  • 嗨,我有一个抽象类,其中有一些公共方法和一些抽象方法。我让公众知道,他们实现了派生类的通用方法。 让我困惑的是,为什么我想定义一个公共抽象方法,而不是受保护的抽象方法。在抽象类中定义公共抽象方法对我来说毫无意义。。。。因为if是一个抽象,在派生类中会被重写,但if被定义为public也是一样的,但在某种程度上,将其定义为protected更有意义,因为我们知道,我们将在派生类中重写它。 在抽象类中

  • 我想知道探索者是否有一个唯一的id或什么的,因为我正在做一个实验,我意识到谷歌检测它是同一台电脑,即使我有很多机会。我已经试过了 null 我真的很感谢你们的帮助,谢谢你们

  • 问题内容: 在C#中,您可以将一个类标记为,以便只能从同一包中对其进行访问。Java有什么类似的东西吗? 问题答案: 您可以通过从类的声明中省略安全修饰符(公共,私有)来创建程序包专用类。