5

相信,每个人都会知道变形金刚(擎天柱,威震天等)。

我试图以类和接口的形式来表示它。目前,我不考虑属性。我只是在使用一些功能。

我的设计是

interface Car{
 public void run();
 public void stop();
}

interface Robot{
 public void walk();
 public void fight();
}

class Transformer implements Car, Robot {
 // implementing all the methods
}

所以类Transformer说,它可以执行汽车和机器人操作

在实例化期间

Robot R = new Transformer(); // Now the transformer is in Robot format
Car C = new Transformer();  // Now the transformer is in Car format

我的问题是,这里有两个正在创建的对象Robot RCar C. 因此,这传达了 Robot is getting created和 Car is getting created。但我想要的是The Car is Getting Transformed to A Robot and Vice Versa

如何在设计中实现这一点。

4

7 回答 7

4

据我了解,您希望 Transformer 类具有机器人功能或汽车功能,但不能同时具有两者。

为了建模,我更喜欢Composition 而不是 Inheritance

例如:

class Transformer {

private Car car;
private Robot robot;
private Class currentState = Car.class;

 public void fight() {
   if (currentState.equals(Robot.class)
      robot.fight();
   }

 public void drive() {
  if (currentState.equals(Car.class)
      car.drive();
  }

 public void transform() {
  if (currentState.equals(Car.class) 
      currentState = Robot.class;
  else
      currentState = Car.class;
}

要实例化一个新的 Transformer,您需要定义它的 Car-Form 和 Robot-Form,例如:

new Transformer(new OptimusPrimeRobot(), new GiantTruck());

与构造函数:

Transformer(Robot r, Car c) {
   this.robot = r;
   this.car = c;
}

OptimusPrimeRobot 实现 Robot 和 GiantTruck 实现 Car。

如果你愿意,你甚至可以懒惰地初始化你包含的类。定义字段:

Class carClass;
Class robotClass;

和一个构造函数:

Transformer(Class robotC, Class carC) {
   this.robotClass = robotC;
   this.carClass = carC;
}

然后为机器人和汽车制作吸气剂方法:

private Robot getRobot() {
  if(robot == null) {
     robot = robotClass.newInstance();
  }
  return robot;
}

并调整您的代码,因此它使用 Getters 而不是字段:

   getRobot().fight();

现在您只需指定 Transformer 包含哪些类,并且它们的对象仅在需要时才被实例化。

于 2012-07-19T10:51:23.943 回答
1

你不应该让汽车变成机器人。汽车只不过是汽车,不应该了解机器人。但是您可以将 Transformer 转换为 Car 或 Robot。我不明白你为什么需要它,但你可以做这样的事情:

class Transformer implements Car, Robot {

  public Car transformToCar() {
     return (Car)this;
  }

  public Robot transformToRobot() {
    return (Robot) this;
  }
}

那么你可以这样做:

Transformer optimus = new Transformer();
Car optimusCar = optimus.transformToCar();
//but this is the same as writing:
Car optimusCar = (Car) optimus;

如您所见,transformToXXX() 方法确实没有意义,因为 Transformer 始终既是 Car 又是 Robot。

编辑:您当然可以将 transformToCar() 定义移动到 Robot 并将 transformToRobot() 定义移动到 Car。然后,Transformer 类必须实现这些方法。

于 2012-07-19T10:49:42.927 回答
1

使用转换方法扩展 Car 接口:

interface TransformableCar extends Car {

    TransformableRobot asRobot();
}

用变换方法扩展 Robot 接口:

interface TransformableRobot extends Robot {

    TransformableCar asCar();
}

创建一个具有两个内部类的类,代表两种状态:

public class Megatron {

    private MegatronCar car = new MegatronCar();
    private MegatronRobot robot = new MegatronRobot();

    public TransformableCar asCar() {
        return car;
    }

    public TransformableRobot asRobot() {
        return robot;
    }

    class MegatronCar implements TransformableCar {

        @Override
        public TransformableRobot asRobot() {
            return Megatron.this.asRobot();
        }

        // TODO: Implement Car methods
    }

    class MegatronRobot implements TransformableRobot {

        @Override
        public TransformableCar asCar() {
            return Megatron.this.asCar();
        }

        // TODO: Implement Robot methods
    }
}

像这样使用它:

Megatron megatron = new Megatron();
TransformableCar car = megatron.asCar();
TransformableRobot robot = car.asRobot();
于 2012-07-19T10:51:19.523 回答
1

我将使用策略模式 Transformer是一个具体的类,它将功能委托给 a RobotStrategyor CarStrategy。这两个都将实现TransformerStrategy

public interface TransformerStrategy{
    public void move();//implemented by both
    public void stop();//implemented by both
    public void fight();//implemented by only Robot, NO-OP for car
    //etc
}
于 2012-07-19T10:52:12.723 回答
1

装饰图案。就像在 Collections 类中一样。使用静态方法。

public static Robot transformCar(Car car){
        return (Robot)car;
    }
于 2012-07-19T10:53:34.667 回答
0

我认为您需要更多地描述您的用例。

对我来说,汽车和机器人之间几乎没有共同之处。如果它当前是汽车,我希望它调用运行和停止,如果它是机器人调用步行和战斗。我不想要一个允许我在错误状态下调用错误方法的设计,而且我无法想象我想在这两种状态下调用的行为。这几乎听起来像是一个由 Car 和 Robot 对象组成的 Transformer 对象,并带有一个返回当前状态的 getter。但也许如果你描述更多的用例,不同的东西会更合适。有趣的问题。

于 2012-07-19T10:51:31.597 回答
0

刚刚这里有点形状...

但这里的问题是,transformer 显式行走,而 CAR 显式运行。也就是说,它们是两个不同的对象。我想要他们,就是这样!

public class TransformersClass{

    public TransformersClass() {

        Car transformer = new Transformer(); // Initially they are Cars
        Robot robot = (Robot) transformer; // Now transformed to Robot. No new objects are created

    }

}

class Transformer implements Robot, Car {


    @Override
    public void run() {
        // TODO Auto-generated method stub

    }

    @Override
    public void walk() {
        // TODO Auto-generated method stub

    }

    @Override
    public void attack() {
        // TODO Auto-generated method stub

    }

    @Override
    public void fire() {
        // TODO Auto-generated method stub

    }

}


interface Robot {
    public void walk();
    public void attack();
    public void fire();

}

interface Car {
    public void run();
}
于 2012-07-21T08:29:54.327 回答