Chace Fields
Chace Fields

Reputation: 907

What is happening with inheritance in my example? And, what is the proper terminology in c#?

I am learning OOP and have a question about what is exactly happening with the code below.

I have the classic Dog Animal example going. Dog inherits 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";
    }
}

Both questions are based on this assignment: Animal a = new Dog();

  1. What is actually happening when I declare an Animal and set it to a Dog reference. Is there a specific term for this?
  2. When I call a.Hungry(), the output is "Dog Speak." If the output is "Dog Speak", why can I not call a.Fetch()? What is the term for what's happening here?

Any help and further reading on the particular topic would be greatly appreciated.

Upvotes: 5

Views: 156

Answers (7)

Venson
Venson

Reputation: 1870

If you Create an Animal with a Dog, you only create A Animal and Have only the Propertys of Animal. This has an Simply Reason. Just a Example:

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";
    }
}

So if you now Crate a Insance like this:

Animal a = new Dog();

You know that your Animal can Speak and that he is Hungry, Nothing more thats all that you need to know, you can Call a.Speak() and your Animal returns "Dog Speak" buf if you now change a like this: a = new Cat() you can call a.Speak() too but it Return something else ... the same call but different returns. Of course if you are sure that the Animal is really a Dog you can cast it back to the Explicit implementation.

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

d is now a real Dog and can everything that only a Dog can but you cant assign anymore d as a Cat. Becorse its a Dog and not an Animal

Why as and not Cast?

Upvotes: 0

Hossein Narimani Rad
Hossein Narimani Rad

Reputation: 32521

  1. when you declare an Animal and set it to a dog implicit cast is done
  2. try this code to see the effect of using virtual and not using it.

:

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();
}

Upvotes: 0

Kevin DiTraglia
Kevin DiTraglia

Reputation: 26078

  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.

Upvotes: 2

Matt Burland
Matt Burland

Reputation: 45155

Animal a = new Dog();

Is upcasting. You are creating a Dog object and assigning it to a variable of the parent class. This is allowed, but...

a.Fetch();

Won't work. Why, because Animal doesn't have a method called Fetch, and as far as the compiler knows, a can be any Animal. If you want to call Fetch you will need to cast a back to a Dog

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

Note however, that this will cause an error if a isn't a Dog, so usually you check first:

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

When you call

a.Hungry();

This is allowed, because Animal has a Hungry method. The Hungry method called Speak, but since a is a Dog and not the base Animal, it'll call the Dog.Speak method (this, as Servy pointed out elsewhere, is true polymorphism - the idea the actual code executed when calling a particular method will be different depending on the actual type of the object).

Upvotes: 4

Servy
Servy

Reputation: 203812

  1. This is an "upcast". In C# there is an implicit conversion from any type to any of it's base types, so you don't need to do anything to treat a Dog as if it were an Animal. (Thanks to Matt Burland for reminding me that this is the appropriate term.)
  2. Because the type of the variable is Animal, and as such you can only access members that the compiler knows an Animal can access, i.e. Speak and Hungry. It doesn't know that the Animal is a Dog, so it can't call Fetch. The variable would need to be of type Dog for you to be able to call Fetch on it.

Upvotes: 5

the word for that is polymorphism

  1. because your animal just happened to be instantiated as a Dog, and it will execute all of Dog's methods. Both Animal and Dog have a Speak method, and Dog inherits Hungry from Animal.Dog's speak method overrides Animal's, so that's what gets executed.

  2. the reason why you can't write a.Fetch is because the compiler doesn't know that at design time.

for example

Animal a;

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

a.Fetch();

at this point when you call a.Fetch you don't know whether or not a is a dog

Upvotes: 1

Lee
Lee

Reputation: 144206

  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.

Upvotes: 2

Related Questions