Why is it legal to store a derived type in a base class reference?

Suppose we declare these two classes:

public class Animal
{
    //.....
}

public class Dog : Animal
{
    //.....
}

Well, my question is: why is the swap string valid?

Animal animal = new Dog();

EDIT:

The e-book "Professional C # 2008" has a paragraph that says:

It is always safe to store a derived type in a base class reference.

+3
source share
7 answers

You create a new one Dog, but then you process (use) it as Animal.

, - , Animal, Dog - . Dog Dog, Animal, , .

: , , :

public abstract class Animal
{
    public abstract void Move();

    public virtual void MakeSignatureSound() 
    {
        Console.WriteLine("Ugggg");
    }
}

public class Dog : Animal 
{
    public override void Move() 
    {
        RunLikeAPuppy();
    }

    public override void MakeSignatureSound()
    {
        Console.WriteLine("Woof");
    }
}

public class CaveMan : Animal
{
    public override void Move() 
    {
        RunLikeANeanderthal();
    }
}

public class Cat : Animal
{
    public override void Move() 
    {
        RunLikeAKitteh();
    }

    public override void MakeSignatureSound()
    {
        Console.WriteLine("Meioww");
    }
}

:

  • Animal , Move(), , Move(), didn , - ,
  • CaveMan MakeSignatureSound(),

, :

Animal caveman = new CaveMan();
Animal dog = new Dog();
caveman.MakeSignatureSound();
dog.MakeSignatureSound();

:

Ugggg
Woof

, , :

Animal animal = new Animal();

, , ( ) Animal, , Animal, .

+5

, , , ( Dog Animal), dog Animal.

. , Animal :

// Error: Cannot implicitly convert type 'Animal' to 'Dog'.
// An explicit conversion exists (are you missing a cast?)
Dog dog = new Animal();

Animal, , . , , , .

Animal animal = new Cat();

// Unable to cast object of type 'Cat' to type 'Dog'.
Dog dog = (Dog)animal;
+9

, ...

...

List<Animal> animals = new List<Animal>();

.

animals.Add(new Dog());
animals.Add(new Cat());

, .

class Animal
{
   public abstract string Run();
}

class Dog : Animal
{
   public override string Run()
   {
      return "Running into a wall.";
   }

}

class Cat : Animal
{
   public override string Run()
   {
     return "Running up a tree";
   }

}

.

foreach(var animal in animals)
   Console.WriteLine(animal.Run());

, , .

, .

!

+2

Dog Animal - Dog , Animal ( Animal , "" - / Animal , Dog).

+1

,

public class Dog : Animal

, IS A Animal

, , ,

 Animal animal = new Dog()

, , .

- , , , , .

, - .

+1

# ( ) : . ( : Animal) , ( : Dog) . :

Animal animal;
if (userInput) 
    animal = new Wolf();
else 
    animal = new Dog();

, .
. :

Dog d = new Animal(); // X
Animal a = new Car(); // X (assuming car does not inherit from animal)

? ( ), . , .
, Animal Wolf Dog, Animal, , Aminal Animal. .
, , " ". , Aminal eat. Dog a Wolf , -. :

Animal a = new Animal();
Animal d = new Dog();

a.eat(); // Animal eat
d.eat(); // Dog eat

, d Animal, . . :

Animal zoo[100]; // each animal in the zoo array is a static type Animal
zoo[0] = new Dog(); // first element of the array is of dynamic type Dog
zoo[1] = new Cat();
zoo[2] = new Rabbit();
...
// Now the array holds different types of animals. We want to feed them all, but each one in it own way.
foreach(Animal a in zoo)
    a.eat();

:

  • , . , .
  • , . . :
+1

, Animal animal = new Dog();

public class Animal
{
    //.....
}


public class Dog : Animal
{
    //.....
}

Feed.

void Feed(Dog d)
{

  //....
}

Cat

public class Cat : Animal
{
    //.....
}

then in my main program I will have to write another function for Feed specifically for the cat class

void Feed(Dog d)
{

  //....
}

void Feed(Cat d)
{

  //....
}

To avoid coding of repeated functions (in the case of derived classes), it is legal and safe to store the derived type in a base class reference.

Now, instead of two functions, I can write one Feed function and take the base class parameter.

Animal animal = new Dog();

Animal animal2 = new Cat();

Feed(animal);
Feed(animal2);

void Feed(Animal A)
{

  //....
}
0
source

Source: https://habr.com/ru/post/1768825/


All Articles