3

C# プログラムで以下のコードを試しました。これは、OOP の概念を学習するためのものです。

 class a
    {      
        public void testa()
        {
        }
    }
    class b:a
    {     
        public void testb()
        {
        }
    }

  a a1 = new b();

  b b1 = new a();

上記のコードに関して、次の質問があります。

  1. 2行目でエラーが発生するのはなぜですか?
  2. とはどういう意味ですかa a1=new b();
  3. a1.testb()のコンストラクターbがに割り当てられているにもかかわらず、アクセスできないのはなぜa1ですか?
  4. a a1=new a()とはどう違い a a1=new b()ますか?
4

6 に答える 6

4

理解を深めるために、クラスとメソッドの名前を実際の同等のものに変更します。aas Animaltestaas Eatbas Humantestbasと名付けましたTalk。したがって、次のようになります。

class Animal {      
    public void Eat() { }
}

class Human : Animal {     
    public void Talk() { }
}

Animal a1 = new Human();

Human b1 = new Animal();

OK、質問に戻ります。

1) すべての動物は人間ではないため、2 行目にエラーが発生します。それは...ですか?

2)a1=new b()私たちの新しい命名規則によれば、 はa1 = new Humanを意味しAnimal a1 = new Humanます。そうですね、人間は動物の一種だからです。

3)a1.testb()新しい命名規則に従って、 に変わりa1.Talk()ます。a1は動物 ( Animal a1) であり、動物に話すことは期待できません。

もっと:

classaは、属性と動作のグループであると考えてください。たとえば、動作Animalを定義するという名前のグループがありEatます。Humanまた、グループを拡張するという名前の別のグループと、 というAnimal名前の独自の動作がありTalkます。私たちが知っているように、Humanにもそのスーパーグループの動作があります-たとえばEat、この例では-.

group のインスタンスがある場合、Animalそれが食べることを期待できます。しかし、話をするように頼むことはできません。不可能です。一方、 group から選択したすべての項目Humanは、実際にはAnimalです。だから私たちは彼に食べるように頼むことができます.

インスタンスがある場合、彼に として振る舞い、としてHumanも振る舞うように頼むことができます。つまり、私たちは彼に頼むことができ、彼にも頼むことができます。すべては、人間のグループと動物のグループに分類できます。HumanAnimalTalkEatHuman

1)Human b1 = new Animal();正確に言うと、グループ - 右部分 - から項目をピックアップし、グループ - 左部分Animal- に入れることHumanはできません。人間以外の動物がたくさんいるからです。

2) 私たちが言うとき:グループ - 右の部分 -Animal a1 = new Humanからアイテムを拾い上げ、グループ - 左の部分 - に入れることは簡単に可能です。HumanAnimal

3) 私たちが と言うときa1.Talk()、私たちは が話すことを期待していAnimalます。Animalつまり、不可能な行動をとることを期待しているというHumanことです。

于 2013-11-05T08:12:09.077 に答える
4

1)この行を意味する場合:

b b = new a();

それは、すべてbがそうであるが、すべてがそうではaないからaですb

2-3)のコンストラクターが に割り当てられているにもかかわらず、アクセスできないのはa a1=new b(); なぜですか?a1.testb()ba1

bこれは、クラスのオブジェクトを作成するが、それへの参照を取得することを意味しますa(キャストせずに、この参照を介して扱うことができaますb

于 2013-11-05T07:56:21.293 に答える
3

おそらく、継承ポリモーフィズムの概念はまだそれほど明確ではありません。 この記事はあなたを助けるかもしれません。

classがbから継承されてaいる場合、それは の「特殊化」と考えることができますabしたがって、インスタンスとして使用/表示できることは簡単に理解できaますが、その逆は当てはまりません!


2行目でエラーが発生するのはなぜですか?

b b1 = new a();は有効な割り当てではないためです。説明したように、継承されたクラスのインスタンスを基底クラスの変数に代入できますが、その逆はできません!

a a1=new b(); の意味

より具体的なクラス インスタンスを基本クラス インスタンスとして確実に使用できるため、この割り当ては正しいです。

bのコンストラクタがa1に割り当てられているにもかかわらず、なぜa1.testb()にアクセスできないのですか?

クラスから継承すると、このクラスのすべてのメソッドpublicprotectedメソッドが継承され、新しいクラスでアクセスまたはオーバーライドできます。ただしtestb()、継承されたメソッドではありません。クラス内で定義された新しいメソッドであるbため、この割り当てを行う場合にのみ使用できます。b b1=new b();

于 2013-11-05T09:17:53.433 に答える
1

クラスは、特定の操作の存在を保証するコントラクトと考えてください。クラスaは 1 つの操作を定義し、クラスはbすべての操作を継承しa、独自の別の操作を定義します。

最初の行:

a a1 = new b();

a1typeという名前の変数を宣言しますa。つまり、この変数に与える値は、 typeaが必要とするすべての操作を持つ必要があります。variable に割り当てられるnew b()class の新しいインスタンスを作成します。classは type からすべての操作を継承するため、 typeの値を typeの変数に割り当てることができます。ba1baba

2 行目:

b b = new a();

同様に、 type で定義されたすべての操作を持つ変数を定義しますb。しかし、必要な操作タイプaを定義していないタイプの値を入力したため、コンパイラはこれを受け入れません。testbb

3 番目の質問については、コンパイラは変数の型 ( a) のみを認識しており、実際に変数に割り当てた値は認識していません。基本的に、コンパイラに「この値が操作を定義することを保証しますtesta。操作を実行させてくださいtestb!」と伝えました。コンパイラは変数の実際の値を知らないので、それに関する限り、それは不可能です。

a a1=new a()との違いについてa a1=new b(): どちらの場合も、型の変数aが作成されます。最初の式では、この変数に割り当てられた値は type の新しく作成されたインスタンスですaが、2 番目の式では、値は type の新しく作成されたインスタンスですb。型 'b' は基本的に type の拡張バージョンであるaため、コンパイラは、 type のインスタンスに求めることができるすべてのことが type のaインスタンスによっても満たされることを認識しているbため、値を type であるかのように扱いますa

于 2013-11-05T08:09:38.913 に答える
0

1) すべてbは ですaが、その逆は真ではありません。

2) ポリモーフィズムの例ポリモーフィズム - たった 2 つの文で定義する

3)定義がないa1.testb()インスタンスとして扱っているため、アクセスできませんatestb()

于 2013-11-05T07:59:15.803 に答える