2017-08-02 20 views
0

私はOOPの概念を使用してまとめようとしている完全に抽象的な次のシナリオを持っていますが、それを正しく行う方法は苦労しています。スーパークラスからランダムに生成されたサブクラスのメソッドを呼び出す

私には3種類の車があります。この車でできることは2つしかありません.1km走行して停止します。すべての車を同じ方法で駆動し停止することができます。だから、OOPの世界で、私はそうのようなものとして、それを表現したい:車の

class Car{ 
    drive(){...} 
    stop(){...} 
} 

3つのタイプが、この親クラスの車のすべてのサブクラスですCARA、CARBとCARC、です。だからCarAと言って、そのようなものを見てみましょう。

class CarA extends Car{} 

これまでのところ、とても良いです。今ここに私の仕事があります。私はタイプCarの配列の中にさまざまなタイプの車がたくさんあります(クラスCarはすべてのタイプの車の親ですのでこれが可能です)。私はランダムな車(インデックスとして機能する範囲内でランダムに生成された整数を使用して、getRandomCar())を呼び出す関数を持っています。一度ランダムな車を取得すると、私の仕事は車を運転することです(車の親クラスの中で定義されている関数に従って1km起こります)。そして車を止めます。だから私のような何かを:

Car car = (Car) getRandomCar(cars); //cars is the Car array with all the different cars 
car.drive(); //car is driven for 1 km 
car.stop(); //car is stopped. 

私が手にランダムな車は常に車と呼ばれる車の参照変数にそれを格納する前に、その親クラスに型キャストされるので、これは動作します。 car.drive()を呼び出すと、drive()というCarクラスのメソッドが呼び出されます。

ここで、これらの車の1つ、CarAは、わずかに異なる運転方法を持っているとします。 CarAのクラス定義の中で、drive()メソッドをオーバーロードします。

私の質問は、上記のシナリオでは、私が得るランダムな車の1つがCarA型の場合、car.drive()は親メソッドを呼び出し、子メソッドは呼び出さないということです。しかし、CarAを運転する方法は他の自動車とは異なり、それが過負荷の方法を持っている理由です。

このケースでは、car.drive()を呼び出す前にif条件を明示し、ランダムな車のタイプがCarAのものであるかどうかをチェックする以外に、簡単にCarA独自のメソッドを呼び出すことができますすべての車に独自の運転方法があるとすれば退屈なプロセスです)。このようなシナリオは、OOPの宇宙にうまく行き渡っていますか?

+3

あなたは、変数の宣言された型がちょうど 'Car'であっても、呼び出されるのはCarAからのオーバーロードされた' drive'メソッドです。しかし、 'CarA'は必要に応じて' super.drive() 'を使って' Car'からメソッドを呼び出すことができます。 – litelite

+1

Javaの動的メソッドディスパッチまたはランタイムポリモーフィズムについて読む。あなたが間違っていると主張しています* ...私が得たランダムな車のうちの1つがCarA型の場合、car.drive()は子メソッドではなく親メソッドを呼び出します。 –

+0

したがって、参照変数が親クラスの型であっても、Javaで呼び出される子クラスのオーバーロードされたメソッドは、 –

答えて

1

Javaでは、メソッドはコンパイル時にチェックされますが、実行時にバインドされます。あなたは

Car car = (Car) getRandomCar(cars); 

carとしてあなたcar変数を宣言すると、今Carの参照型とCarAのインスタンスです。コンパイラが伝える限り、carCarです。

car.drive()を呼び出すと、コンパイラはそのメソッドをCarクラスの定義と照合してチェックします。 Car実際にはdrive()という名前のメソッドが含まれているため、コンパイルは成功します。実際にプログラムが実行されると、JVMはそのステートメントに達し、実際のオブジェクトのdrive()を呼び出します。 carは実際にはCarAなのでCarAのバージョンはdrive()です。独自の定義が含まれていないCarBCarCの場合、Carのバージョンdrive()が自動的に継承されます。


他のいくつかの注意事項(私が気づいた事とコメントで述べたもの):

  1. あなたはここに記述しているシナリオは過負荷状態にない、をオーバーライドと呼ばれています。オーバーロードは、同じ名前と戻り値の型を持つ複数のメソッドを作成していますが、パラメータは異なります。オーバーライドは、サブクラスで同じメソッドを作成することによって、スーパークラスの機能を置き換えます。

  2. car割り当てでは、Carにキャストする必要はありません。 getRandomCar()は任意のタイプのCarを返すことができるため、返されるタイプはCarである必要があります。 carもタイプCarで宣言されているため、キャストは必要ありません。

関連する問題