5

私は OOP を学んでおり、以下のコードで正確に何が起こっているのかについて質問があります。

私は古典的なDog Animal例を持っています。Dogを継承しAnimalます。

public class Animal
{
    public string Name { get; set; }

    public virtual string Speak()
    {
        return "Animal Speak";
    }

    public string Hungry()
    {
        return this.Speak();
    }
}


public class Dog : Animal
{
    public override string Speak()
    {
        return "Dog Speak";
    }

    public string Fetch()
    {
        return "Fetch";
    }
}

両方の質問は、次の割り当てに基づいています。Animal a = new Dog();

  1. Animalを宣言して参照に設定すると、実際に何が起こっているのかDog。これには特定の用語がありますか?
  2. を呼び出すa.Hungry()と、出力は「Dog Speak」です。出力が「Dog Speak」の場合、なぜ呼び出せないのa.Fetch()ですか? ここで起こっていることを表す用語は何ですか?

特定のトピックに関するヘルプとさらなる読書は大歓迎です。

4

7 に答える 7

5
  1. これが「アップキャスト」です。DogC# では、任意の型からその基本型への暗黙的な変換があるため、 aを であるかのように扱うために何もする必要はありませんAnimal。(これが適切な用語であることを思い出させてくれた Matt Burland に感謝します。)
  2. 変数の型は でありAnimal、コンパイラがアクセスできると認識しているメンバー、つまり と にしかアクセスできないAnimalためSpeakですHungryAnimalが であることを認識していないDogため、 を呼び出すことはできませんFetch。変数はDog、呼び出すことができる型である必要がありますFetch
于 2013-01-18T19:40:58.383 に答える
4
Animal a = new Dog();

アップキャストです。オブジェクトを作成し、Dogそれを親クラスの変数に割り当てています。これは許されますが…

a.Fetch();

うまくいきません。なぜ、 にAnimalは というメソッドがなくFetch、コンパイラが知る限り、a任意のAnimal. 呼び出したい場合Fetchは、キャストaバックする必要がありますDog

Dog d = (Dog)a;
d.Fetch();

ただし、 でaはない場合はエラーが発生するDogため、通常は最初に確認します。

if (a is Dog) 
{
    Dog d = (Dog)a;
    d.Fetch();
}

電話すると

a.Hungry();

Animalメソッドがあるため、これは許可されHungryます。Hungryメソッドは呼び出されますがSpeak、それaDogbaseAnimalではなく、メソッドを呼び出しますDog.Speak(Servy が他の場所で指摘したように、これは真のポリモーフィズムです。特定のメソッドを呼び出すときに実行される実際のコードは、実際のメソッドによって異なります)。オブジェクトのタイプ)。

于 2013-01-18T19:45:35.360 に答える
2
  1. Your are storing an object of type Dog inside an variable that will accept any Animal. This is called Polymorphism (actually not quite see Servy's comment)
  2. You can only call fetch by first casting the object to a dog

Like so:

Dog dog = (Dog)a;
dog.Fetch();

Otherwise as far as the compiler knows it could be any animal, and not all animals have the method Fetch. Also note the cast would throw an InvalidCastError if it was not actually a Dog object.

于 2013-01-18T19:40:00.243 に答える
2
  1. a is an Animal reference and it points to a Dog object. This is a form of polymorphism (subtype polymorphism).

  2. You can't call a.Fetch since a has type Animal and the Fetch method is not defined in your Animal class.

于 2013-01-18T19:40:27.057 に答える
1

そのための言葉はポリモーフィズムです

  1. あなたの動物はたまたま としてインスタンス化され、のDogすべてDogのメソッドを実行するからです。と の両方Animalにメソッドがあり、 からDog継承します。のメソッドが をオーバーライドするため、それが実行されます。SpeakDogHungryAnimalDogspeakAnimal's

  2. 記述できない理由a.Fetchは、コンパイラが設計時にそれを認識していないためです。

例えば

Animal a;

if(console.ReadLine() == "Dog")
{
    a = new Dog();
}
else
{
    a = new Animal();
}

a.Fetch();

この時点であなたが電話をかけるとき、あなたa.Fetchは a が犬かどうかわからない

于 2013-01-18T19:42:09.557 に答える
0

犬で動物を作成する場合、動物のみを作成し、動物のプロパティのみを持ちます。これには単純な理由があります。ほんの一例:

public class Animal
{
    public string Name { get; set; }

    public virtual string Speak()
    {
        return "Animal Speak";
    }

    public string Hungry()
    {
        return this.Speak();
    }
}


public class Dog : Animal
{
    public override string Speak()
    {
        return "Dog Speak";
    }

    public string Fetch()
    {
        return "Fetch";
    }
}

public class Cat: Animal
{
    public override string Speak()
    {
        return "Cat Speak";
    }

    public string Fetch()
    {
        return "Fetch";
    }
}

したがって、次のように Insance をクレートするとします。

Animal a = new Dog();

あなたはあなたの動物が話すことができ、彼が空腹であることを知っています.あなたが知る必要があるのはこれだけです.あなたは電話することができa.Speak()、動物は"Dog Speak"次のように変更するとbufを返します:a = new Cat()あなたも電話することができますa.Speak()が、何か他のものを返します.. . 同じ呼び出しだが異なるリターン。もちろん、Animal が本当に Dog であることが確実な場合は、それを Explicit 実装にキャストすることができます。

var d= new Dog();
if(a is Dog)
d = a as Dog;

d は本物の犬になり、犬だけができるすべてのことができますが、猫として d を割り当てることはできなくなりました。動物ではなく犬だから

なぜ as ではなく Cast なのですか?

于 2013-01-18T19:43:18.123 に答える
0
  1. を宣言して暗黙のキャストAnimalに設定すると、行われますdog
  2. このコードを試して、使用した場合と使用virtualしなかった場合の効果を確認してください。

:

public class Animal
{
    public string Name { get; set; }
    public string Speak()
    {
        return "Animal Speak";
    }
    public string Hungry()
    {
        return this.Speak();
    }
}

public class Dog : Animal
{
    public new string Speak()
    {
        return "Dog Speak";
    }
    public string Fetch()
    {
        return "Fetch";
    }
}

static void Main(string[] args)
{
    Animal a = new Dog();
    Console.WriteLine(a.Hungry());   //Animal Speak
    Console.ReadLine();
}
于 2013-01-18T19:49:40.697 に答える