2012-04-20 14 views
-1

Fruitクラスは、スーパークラスであり、AppleOrange果実のサブクラスである場合、 とGoldenDeliciousMacintoshAppleの下位クラスです。継承及び多型コンフリクト

は、以下の宣言が与えられていると仮定します

Fruit fruit = new GoldenDelicious(); 
Orange orange = new Orange(); 

説明

と回答この質問をする方法makeAppleCiderAppleクラスで定義されていると仮定します。 fruitこのメソッドを呼び出すことができますか?オレンジ色でこのメソッドを呼び出すことはできますか?

私の答えは: 果物はこのメソッドを呼び出すことができますか?明示的なキャストはありません。Appleクラスで定義されているメソッドを呼び出すには、 フルーツインスタンスの明示的なキャストを行う必要があります。この回答は本当ですか?

+3

これは宿題のような非常に多くを探します。それは...ですか? – Jasper

+0

@Aidanc - 最後の段落の質問の最後に提案された解決策があります。 – Flexo

+0

いいえ、私はJavaの本の紹介からJavaを勉強しており、各章の後に質問を解決します。 私はオブジェクトのキャストと多型に矛盾があったので、本当の答えを知りたい。 宿題はありませんでした。 私はそれを勉強しています – MUE

答えて

0

Fruitには、makeAppleCiderメソッドの「知識」がありません。 makeAppleCiderはサブクラスで定義されており、Fruitのメンバーではありません。クラスは、そのクラスまたはその親の1つが定義するメソッドにのみアクセスできます。特定のタイプのクラスがある場合は、クラス階層をバックアップして、どのメソッドにアクセスできるかを調べる必要があります。変数のタイプは、歩行の開始場所として考えて、クラス階層をバックアップすることができます。

クラスにすべてのアクセスを許可するメソッドがある場合は、階層のルートに配置します。明らかに、このメソッドを使用するロジックは理にかなっているはずです。あるいは、コードを使用する人が混乱するでしょう。

0

もう1つの選択肢は、貧しい人の多重継承のような「インターフェイス」を使用することです(完全な多重継承よりもはるかに理解して実装する方が簡単です)。

あなたは可能性があり、例えば、(構文チェックではない)のようなインターフェースみかんを持っている:そして、Appleはインターフェイスを実装でき

public interface CiderFruit { 
    public void makeCider(); 
} 

public class Apple extends Fruit implements CiderFruit { 
    .... 
    public void makeCider() { 
     doStuff(); 
    } 
    .... 
} 

を使用すると、その後、マルメロのクラスを持っていた場合、それは可能性同じインターフェースを実装し、AppleかQuinceのいずれかを取ってCiderFruit(AppleかQuinceかどうかわからない場合)にキャストし、makeCider()を呼び出します。 (AppleまたはQuinceとタイプされた参照で直接呼び出すこともできます)

1

これは、変数の静的型と動的型に分かれています。

Fruit fruit; 

この行は、静的な型Fruitを持つ変数fruitを宣言します。このタイプは決して変更されません(結局のところ静的です)。これは通常使用するものです。

fruit = new GoldenDelicious(); 

この行は、その変数にGoldenDeliciousの値を割り当てます。この変更を反映するために、変数の動的タイプが変更されます。結局のところ、変数には実際にはGoldenDeliciousが含まれています。ダイナミックタイプは、通常作業しないものですが、(悪い)instanceofを使用するときに使用されるものです(上書きされた関数が正しい場所で呼び出されるようにします)。

は今、あなたはこれをしたい:

fruit.makeAppleCider(); 

これは動作しません。果物のうち、我々は基本的に静的な型だけを知っていて、静的な型のFruitはそのメソッドを何も知らない。 (しかし、舞台裏で、GoldenDeliciousMacintoshが異なる方法で関数を実装している場合は、動的な型が正しいバージョンが呼び出されることを確認します)。

あなたの答えに記載されているとおり、明示的なキャストを使用してあなたが作業しているものの静的な型であり、そういうものとして、それをそのように動作させることができます。しかし、キャストは避けて "適切なOOP"ではないので、そうしないほうが良いです。

結論として、あなたの答えは正しいです。

(はい、私の説明が少し技術的です。私はあなたがそのために私を許していただければ幸いです...)

+0

ありがとう、私はすでにあなたを許しています:)) – MUE

+0

良い答え。異なる視点。 – Dhananjay