プロが教える店舗&オフィスのセキュリティ対策術

こんにちは。

以下のプログラムにおいて、
Animal a = new Cat();として変数aはCat型となるのでしょうか?
変数aにはCatがはいる?(はいるんでしょうね。きっと)

イメージとして
変数aの型(Animal型)より、派生したCAT型のほうが(箱)が大きいと思われるのに
a=Cat型となるのでしょうか?
(上記のイメージで
派生クラスのオブジェクトは基底クラスの変数に代入できることがわかりません。)

分かっていること。

Cat型はAnimal型として振る舞える。
代入後は、変数の型 (= Animal) が呼び出される。
猫 (Cat)は動物(Animal)の一種である。
Catクラスは 動物(Animal)クラスから派生している。

参考にしたページ
https://csharp.keicode.com/basic/as-operator.php

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace catdog
{
class Program
{
static void Main(string[] args)
{
Animal a = new Cat();
a.test();
}
}
class Animal
{
public void test()
{
Console.WriteLine("test");
}
}

class Dog : Animal
{
}

class Cat : Animal
{
}
}

A 回答 (4件)

基底クラス=大分類


派生クラス=小分類
のようなイメージを持てばいいかと思います。

Animal a = new Cat();
の場合、「a」はAnimalとして振る舞う。
aとCatとして扱う場合は(Cat)a などとしてキャストすることでCatとして扱うこともできる。

下記のように活用します。
Animal a = new Cat();
string animalColor = a.getColor(); //動物の色を取得するメソッドがあるとする
if(a is Cat){ //aがCatクラスなら
 Cat cat = a as Cat;
 cat.huntMouse(); //ネズミを捕らえるメソッドがあるとする
}
if(a is Dog){ //aがCatクラスなら
 Dog dog = a as Dog;
 dog.longRun(); //走り回るメソッドがあるとする
}
    • good
    • 0

うーん、まず抽象化を何のために行うか考えたほうが良いでしょう。



Animal型の参照のみを使って行う処理、つまり Cat型であることを知らず
Animal型で使えるメンバ範囲のみを使って行う処理は、Cat型のオブジェクトでも
Dog型のオブジェクトでも動きます。

新たに、Fox型がAnimalを継承して新設されても Animal型の範囲のみで処理を行っている
処理はおそらく全く変更する必要がないし、その処理は Catでも DogでもFoxでも使える
共通処理として使えでしょう。

でも、CatやDog型のオブジェクトの参照がAnimal型と互換性がなければ
そういうことは全くできません。

なので、それができるように言語が実装されているのです。

オブジェクトの共通性からの抽象化と、上位レベルからの処理の共通化は、
オブジェクト指向の基本の一つです。
    • good
    • 0

変数の型とオブジェクトの型は違います。


変数はAnimal型で、オブジェクトがCat型です。
あとこういうオブジェクト変数の型は普通は参照型で、変数に直接オブジェクトの実体を入れるのではなく、オブジェクトはヒープ領域に作られて変数にはその参照(ポインタ)のみが保管されるように実装されます。参照は一般にどの型のオブジェクトでも同じ大きさなので実体が大きくなる下位型のオブジェクトでも問題なく代入できます。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

メモリ内部の話ありがとうございます。
大変さんこうになりました。

でも、わかりませんw

たとえば、アップキャスト
派生クラスは基底クラスの機能をすべてもっているので
基底クラスとしてふるまうことができる。

これは、理にかなっており、Animalクラスの中に書かれているメンバとかメソッドとかは覗けるけど、Catクラス(型)は覗くことはできない。
要するに、Animal型の範囲しか見れないということです。
(↑えらそう ごめんなさい)

Cat型はみれてないじゃん。 ってことです。

上記の理由によりAnimal a = new Cat(); が
Animal型の変数aがCaT型(a=Cat)をしめせるのかがわかりません。

このプログラムにおける継承関係は動物→猫(犬)となってます。
たとえば、猫は動物の一種である。
動物の一種に猫がいる。じゃぁ猫(Cat)が入るじゃないですか。
動物から継承しているので、この式が成り立つ(代入できる)といわれれば
そうかもしれませんが・・・

ちょっとおればかなのかなぁ?

お礼日時:2019/03/22 19:54

> Animal a = new Cat();として変数aはCat型となるのでしょうか?


> 変数aにはCatがはいる?

型はGetType()メソッドで確認できます。
Animal a = new Cat();
Console.WriteLine(a.GetType()); //-> catdog.Cat
a = (Animal)(new Cat());
Console.WriteLine(a.GetType()); //-> catdog.Cat

Animal型変数aは、Animal型から派生したCat型オブジェクトを参照できます。(アップキャスト)


> イメージとして変数aの型(Animal型)より、派生したCAT型のほうが(箱)が大きいと思われる

これについては以前のご質問でも回答していますので参照してください。
https://oshiete.goo.ne.jp/qa/10986235.html の回答No.5
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!