Animal dog = new Dog();

What's the difference between dog1, dog2 and dog3 below? Is there a difference?
using System;

namespace Animal
{
  class Program
  {
    static void Main(string[] args)
    {
      Animal dog1 = new Dog();
      Dog dog2 = new Dog();
      var dog3 = new Dog();
      string x = Console.ReadLine();
    }
  }
  class Animal
  {
    public Animal()
    {
      Console.WriteLine("Animal Constructor");
    }
  }
  class Dog : Animal
  {
    public Dog()
    {
      Console.WriteLine("Dog Constructor");
    }
  }
}

Open in new window

deleydAsked:
Who is Participating?
 
käµfm³d 👽Connect With a Mentor Commented:
am I correct that the difference here is with dog1 I can call any Dog method and also any Animal method...
...but with dog2 I can only call Animal methods
You have that backwards.

did I instantiate a Dog class or an Animal class?
You instantiated a Dog (i.e. an object of whatever type follows new). The reference pointer (Animal dog1) points to an Animal, which a Dog is because of inheritance. Because you have an Animal reference pointer, without casting you can only see the Animal members.
0
 
käµfm³d 👽Commented:
Animal dog1 = new Dog();
This is polymorphism. You created a Dog object, but you are accessing it as a reference to an Animal object. None of the "Dog" data is lost, but in order to access it, you would need to cast back to a Dog.

e.g.

((Dog)dog1).Bark();

Open in new window


Dog dog2 = new Dog();
This is a Dog being referenced as a Dog. No casting is required to get to the Dog's normal properties/methods. The base class' (Animal) methods/properties are also accessible due to inheritance, and you don't need to cast to be able to use them.

var dog3 = new Dog();
The var keyword means the type of dog3 will be inferred by the compiler. The object is still a Dog, and you still have access to the methods/properties of both the Dog and the Animal (via inheritance mentioned above) classes. This is essentially just a shortcut to what you did with "dog2". The var keyword becomes very important when working with anonymous types and Linq.
0
 
EvoWingCommented:
In the short example given the are all unique instances of the Class Dog. In the exection of the program there is no difference.

However, if additional code is written then the differences are:-
if other classes were derived from Animal then they could be assogned to dog1 and dog3, but not dog2. Similarly, an instance of any class could be assigned to dog3 but not dog1 or dog2.
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
käµfm³d 👽Commented:
@EvoWing
if other classes were derived from Animal then they could be assogned to dog1 and dog3
That is not entirely accurate. If you have already assigned a type to the var, then trying to assign a different type will fail during compilation. For example:

using System;

namespace _27479447
{
    class Program
    {
        static void Main(string[] args)
        {
            var dog3 = new Dog();

            dog3 = new Cat();
            Console.ReadKey();
        }
    }

    class Animal
    {
        public Animal()
        {
            Console.WriteLine("Animal Constructor");
        }
    }
    class Dog : Animal
    {
        public Dog()
        {
            Console.WriteLine("Dog Constructor");
        }
    }
    class Cat : Animal
    {
        public Cat()
        {
            Console.WriteLine("Cat Constructor");
        }
    }
}

Open in new window


You can't assign a Cat because the compiler has already noted that "dog3" is going to be a Dog, and there is no implicit conversion between the two. If we said this, however:

using System;

namespace _27479447
{
    class Program
    {
        static void Main(string[] args)
        {
            var dog3 = new Dog();

            dog3 = new Cat();
            Console.ReadKey();
        }
    }

    class Animal
    {
        public Animal()
        {
            Console.WriteLine("Animal Constructor");
        }
    }
    class Dog : Animal
    {
        public Dog()
        {
            Console.WriteLine("Dog Constructor");
        }

        public static implicit operator Dog(Cat c)
        {
            return new Dog();
        }
    }
    class Cat : Animal
    {
        public Cat()
        {
            Console.WriteLine("Cat Constructor");
        }
    }
}

Open in new window


then it would work, but I'm sure we agree that an implicit conversion from Cat to Dog is nonsensical.
0
 
ToddBeaulieuCommented:
Actually, polymorphism has nothing to do with casting. It's the concept that classes that implement the same interface (or methods, etc.) can be handled similarly, but the actual behavior could be different.

So it's not the fact that you're casting a dog into an animal, but the fact that all animals would support making a noise, or eating, but internally each could implement that behavior differently.
0
 
käµfm³d 👽Commented:
@ToddBeaulieu

I can see how my previous statement implies that. I meant to indicate that assigning a Dog to an Animal reference is the polymorphism aspect of that line. Separate from that, you would indeed need to cast the Animal pointer to a Dog in order to be able to call the ChewSlippers method, for example.
0
 
ToddBeaulieuCommented:
You're absolutely right.

I don't know why you'd actually want a dog to chew slippers, though. I try to discourage that!
0
 
deleydAuthor Commented:
So is dog1 a Dog object cast as an Animal object?

We can use it to reference Animal methods, but to access Dog methods we need to cast it back to a Dog object, which it actually is, then we can call the "Bark" method? Is that correct?



What happens if I try to cast it as something it's not? Say cast the dog1 object as a Tool object and attempt to call the "Screwdriver" method? (I'll give that a try just to find out.)
0
 
käµfm³d 👽Commented:
So is dog1 a Dog object cast as an Animal object?
In a technical sense, no. A Dog is an Animal. Think about it as you would in real life. A dog is an animal. An animal is a living organism, and because a Dog is an Animal, it too is a living organism. You don't convert a dog into an animal--it already is one. But if you said to your friend, "I have an animal," your friend couldn't determine, based on that simple information, that the animal that you have can actually bark. You would have to tell your friend that your animal is a dog.

Something similar happens in your code. You have an animal, that just happens to be a dog:

Animal dog1 = new Dog();

Open in new window


but you are treating "dog1" as if it were the animal you told your friend about. In order for your friend to know it can bark, you have to tell him it's a dog:

((Dog)dog1).Bark();

Open in new window


What happens if I try to cast it as something it's not?
You will get an InvalidCastException. You can always check the type of the object before you cast it by using the is keyword:

if (dog1 is Tool)
{
    Tool t = (Tool)dog1;
}

Open in new window


Another option, often more desirable, is to use the as keyword:

Tool t = dog1 as Tool;

if (t != null)
{

}

Open in new window


The as keyword will try to cast the object in question (dog1) to the specified type (Tool). If the conversion cannot be safely accomplished, then the resulting reference (t) will be null. If the reference is not null, then you can proceed to use the reference as the type specified.
0
 
deleydAuthor Commented:
Hmm, well if a dog is an Animal, and a dog is also a Dog,
      Animal dog1 = new Dog();
      Dog dog2 = new Dog();

Open in new window

am I correct that the difference here is with dog1 I can call any Dog method and also any Animal method:
dog1.bark();   //only dogs bark
dog1.die();    //all animals die
dog1.<any Dog method>
dog1.<any Animal method>

Open in new window

(assuming the Animal method isn't overridden by a Dog method)

but with dog2 I can only call Animal methods, I can't call any Dog methods (even though it is a Dog) because... what class did I instantiate with
      Animal dog1 = new Dog();

Open in new window

did I instantiate a Dog class or an Animal class?
0
 
deleydAuthor Commented:
Yes I had dog1 & dog2 reversed
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.