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

私の質問は、ここで作成されている2つのオブジェクトRobot RCar C. したがって、これは Robot が作成され、 Car が作成されていることを伝えます。しかし、私が欲しいのはThe Car is Getting Transformed to A Robot and Vice Versa

これを設計に実装する方法。

4

7 に答える 7

4

私が理解しているように、Transformer クラスにはロボット機能または車機能のいずれかが必要ですが、同時に両方は必要ありません。

それをモデル化するには、Inheritance よりも Composition を優先します。

例えば:

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;
}

Robot を実装する OptimusPrimeRobot と Car を実装する GiantTruck を使用します。

必要に応じて、含まれているクラスを遅延初期化することもできます。フィールドを定義します。

Class carClass;
Class robotClass;

コンストラクター:

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

次に、ロボットと車の getter メソッドを作成します。

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

コードを調整して、フィールドの代わりにゲッターを使用するようにします。

   getRobot().fight();

次に、Transformer を構成するクラスを指定するだけで、それらのオブジェクトは必要な場合にのみインスタンス化されます。

于 2012-07-19T10:51:23.943 に答える
1

車をロボットに変形させるべきではありません。車は車に過ぎず、ロボットについて何も知らないはずです。ただし、Transformer を車やロボットに変形させることはできます。なぜそれが必要なのかわかりませんが、次のようなものを作ることができます:

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();
}

2 つの状態を表す 2 つの内部クラスを持つクラスを作成します。

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

戦略パターン は具体的なクラスであり、機能をorTransformerに委譲します。これらは両方ともRobotStrategyCarStrategyTransformerStrategy

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

これでやっと形が整った…

しかし、ここでの問題は、トランスフォーマーが明示的に WALK し、CAR が明示的に実行されることです。つまり、これらは 2 つの異なるオブジェクトです。私はそれらが欲しい、それだけです!

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 に答える
0

ユースケースをもう少し説明する必要があると思います。

私にとって、車とロボットの間に共通点はほとんどありません。現在の車なら走って止まる、ロボットなら歩いて戦う。間違った状態にあるときに間違ったメソッドを呼び出すことができる設計は望んでおらず、両方の状態で呼び出したい動作を想像できません。Car オブジェクトと Robot オブジェクトの両方で構成される Transformer オブジェクトと、現在の状態を返す getter のように聞こえます。しかし、ユースケースをもっと説明すれば、別のものが適しているかもしれません。興味深い質問です。

于 2012-07-19T10:51:31.597 に答える