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

deleydSoftware EngineerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

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
deleydSoftware EngineerAuthor 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
deleydSoftware EngineerAuthor 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
käµfm³d 👽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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
deleydSoftware EngineerAuthor Commented:
Yes I had dog1 & dog2 reversed
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.