2017-06-11 11 views
0

こんにちは、subclass変数が以下のコードに従ってスーパークラスオブジェクトを参照できない理由を理解できません。Subclass型の宣言が、SuperクラスのObjectを参照できないのはなぜですか?

class Superclass{ 
} 

class Subclass extends Superclass{ 
} 

public class DemoClass { 

    public static void main(String[] args) { 

     Superclass obj = new Subclass(); //Valid 
     Subclass obj2 = new Superclass(); //Invalid 

    } 

} 
+0

開発者は、子クラスの開発者は子クラスに入れますどのような追加の行動を知りません。そのようなメソッドが呼び出された場合、Parentクラスのオブジェクトはその操作を実行する方法を知らないでしょう。参照の宣言タグに基づいて、任意の操作を呼び出すことができます。私の答えを読んでもっと詳しい説明をしてください。 https://stackoverflow.com/a/44481873/504133 –

答えて

2

Subclassのインスタンスも常にSuperclassのインスタンスであるので、あなたは、あなたが割り当てることができませんので、ないSuperclassのすべてのインスタンスがSubclassのインスタンスであり、一方、

Superclass obj = new Subclass(); 

を割り当てることができますSuperclassインスタンスをSubclass変数に変換します。

Superclassのいくつかの事例もSubclassのインスタンスであるので、あなたは、割り当てを行うためにSubclassSuperclassインスタンスをキャストすることができます

Superclass obj = new Subclass(); 
    Subclass obj2 = (Subclass) obj; 

しかし、しかし、あなたの例(Subclass obj2 = new Superclass();)であなたがしようとしていますでないインスタンスをSubclassからSubclassに割り当てることができます。したがって、キャストしても機能しません。

+0

そして、あなたが説明したものを満足する以下のユーザーdavidxxxによって与えられたAnimal、Cat、Dogクラスの説明ですか? – anukb

2

サブクラスオブジェクトをスーパークラスオブジェクトとして「総称的に」扱うことはできますが、サブクラスオブジェクトではないため、汎用スーパークラスオブジェクトを持つことができず、より特定のサブクラスオブジェクトとして扱うことはできません。 あなたのサブクラスにメソッドがあるとしましょう。あなたのスーパークラスには存在しないメソッドfoo()を呼び出してください:スーパークラスオブジェクトをサブクラスタイプに格納することが許可されていれば、そのオブジェクトに対してfoo()メソッドを使用しますか?

public class Superclass { 

} 

public class Subclass extends Superclass { 
    void foo() { 
     //... 
    } 
} 

public class MainClass { 
    public static void main(String...s) { 
     Subclass obj = new SuperClass(); 
     obj.foo(); //THIS 
    } 
} 
2

OOPはこのように機能しないためです。
サブクラスの型の変数は、そのスーパークラスのオブジェクトを参照することができない。

Subclass obj2 = new Superclass(); 

スーパークラスの任意のインスタンスは、特定のサブクラスのインスタンス必要がないように。

しかし、逆は可能です:任意のサブクラスのインスタンスとして

Superclass obj = new Subclass(); 

は、最終的には、スーパークラスのインスタンスです。あなたが最初の割り当てを行うことができない理由を、(サブクラスタイプで宣言された変数に親インスタンスを割り当てる)、理解してこのコードを想定する

が働いた:

Animal animal = new Dog(); 
Cat cat = animal; // should not be legal 

君はCat変数にDogを割り当てanimal変数はDogインスタンスを指します。意味がない。

0

サブクラスは、基本クラスの拡張です。 基本クラスにはわからないとサブクラス

Parent p = new Child() // Child knows and behaves like parent and can override some behavior too 

Child c = new Parent() // author of Parent class has no idea as how Child will be implemented 
    // and what extra behaviors will be added in child. 
// If any behavior of parent is invoked on c, the object of Parent class will not know how to perform it. 

理解することはそのシンプルなように振る舞うことができない、現実の世界に近い例を取ることができます。

  1. アップル、マンゴー、キウイは果物です。 Appleクラス、マンゴクラス、キウイクラスをJavaクラスとして表現すると、すべてFruitクラスから継承されます。 ClassA obj = new ....のようなものを宣言するコードの場合

  2. は無視当分できます...と見ClassA、参照objのためにその宣言された型。 ClassAにあるすべての公開メイドは、objで呼び出すことができます。

  3. Fruit.javaがの場合、sweetを返します。すべてのサブクラスは、スーパークラスからgetTasteメソッドを継承します。 getTasteは、マンゴー、キウォ、アップルのすべてで呼び出すことができます。

  4. Mango.javaの開発者がconvertToMangoShake()という追加のメソッドを追加することを決めたとします。

  5. マンゴーシェイクに変換する準備ができているマンゴーだけに注意してください。

    マンゴー以外の果物はマンゴーシェイクに変換する準備ができていません。アップル、キウイはマンゴーシェイクに変換する準備ができていません。あなたがMango mango = new Fruit()を言うと方法convertToMangoShake()mango.convertToMangoShake()のように呼び出されたフルーツがないよう、今、エラーがスローされます場合マンゴーシェイクに変換する準備をするkiwoを依頼する任意のそのような行動は、エラー今

  6. になりますこの方法を知っている。

0

私はこれがあなたを理解するのに役立つと信じています。私はコードの代わりに簡単な英語でこの質問に答えようとします。

実際の違いは、SubClassは、SuperClassのより特化したバージョンであることを意味します。技術的には何かを行うか、、またはにいくつかの追加のプロパティを保存する必要があります。

SuperClassをSuperClassとして記述しようとすると、SuperClassが同じ目的を果たすことができないため、これはもはや真実ではありません。関数はSuperClassやプロパティと同様に存在しません。

したがって、SubClassをSuperClassとして記述することができれば、実際にはそれはもはやSubClassではありません。これは、言語の制約に違反する、その場でオブジェクト型のコントラクトを上書きするようなものです。

逆に、SubClassはSuperClassのすべての機能とプロパティを保持しているため、SuperClassと同様に機能することができます(ただし、機能を明示的にオーバーライドする場合を除く)。これは継承に由来するプロパティです。

あなたの例では、SubClassとSuperClassには実質的な違いはありません。そのような場合、SubClassを持つ実際的な方法はありません。将来的に機能を拡張し、その2つを区別したい場合は、設計上の決定に関連する可能性があります。しかし、たとえそれらが同じであっても、extendキーワードを使うことによって、 "ちょっと、このクラスにもっと何かがあります"というようなことを理解する必要があります。これには前述の制約があります。

0

クラスから継承するときは、常にスーパークラスの共通の動作を特化します。

例では、Subclassは特別なSuperclassです。スーパークラスからすべての動作を継承し、動作をオーバーライドして違う動作や新しい動作を追加することができます。

サブクラスは、一般的に追加の動作を定義するため、許可されていません。スーパークラスオブジェクトをサブクラス参照に割り当てることができた場合、実際には存在しないクラスメンバーにアクセスしようとすると、実行時に問題が発生します。

サブクラスオブジェクトを参照するには2つの方法があります。

  1. 最初のアプローチ(スーパークラスの参照を使用して参照):両方が他の上いくつかの利点/欠点を有するスーパークラスの参照変数に使用することができるスーパークラスから派生した任意のサブクラスのオブジェクトを参照します。メソッドがSuperClassに存在し、SubClassによってオーバーライドされている場合は、メソッドがオーバーライドされて実行されます。
  2. 2番目のアプローチ(サブクラス参照を使用した参照):サブクラス参照を使用してそのオブジェクトを参照できます。

例:親のためのコードを書く

public static void main(String[] args) { 
      // using superclass reference 
      // first approach 
      Superclass sub1 = new Subclass(); 

      // using subclass reference() 
      // second approach 
      Subclass sub2 = new Subclass(); 
} 
関連する問題