Hello

Can someone help me understand the difference?

Human h = new Human();
or
Man m = new Man();

vs.
Human h2 = new Man();

recently I have seen an object instantiated like this - where it references this other object (after the "new" keyword )

I am trying to figure out what exactly this does or even what it's called so I can look into it more.

thank you

Human h2 = new Man();

In this situation, this is legal when Man is a derived class of Human.

class Program
    {
        static void Main(string[] args)
        {
            Human h2 = new Man();
            h2.Name = "DaniWeb User";
        }
    }

    public class Human
    {
        public string Name { get; set; }
    }

    public class Man : Human
    {
        public int Manliness { get; set; }
    }

You are allowed to do this with inheritance. So you could potentially have a collection of human-derived objects, for example, and use each of them as humans. It is important to note that as long as you have declared the object as a Human, even though you instantiated it as a Man, you can only work with the properties and methods of Human directly. The properties and methods of Man are not accessible unless you cast the object to Man first. In the previous code example, Human.Name is accessible, Man.Manliness is not. To set or retrieve the value of manliness, cast the object to Man and then access that property.

Human h2 = new Man();
            h2.Name = "DaniWeb User";
            ((Man)h2).Manliness = 100;
Comments
Well explained.
Helpful.

Thank you so much for your example. So this helps. Can you also tell me though why this would be done like this? I mean why not just instantiate the class you want to use instead of it doing it this indirect way? Does that make sense to question this - or am I missing something.?

You might not often see a class instantiated in such a way, but go back to what I said about perhaps having a collection of human-derived objects.

class Program
    {
        static void Main(string[] args)
        {
            Man tom = new Man();
            tom.Name = "Tom";
            tom.Manliness = 95;

            Man joe = new Man();
            joe.Name = "Joe";
            joe.Manliness = 92;

            Woman sally = new Woman();
            sally.Name = "Sally";
            sally.HotOrNot = true;

            Woman jill = new Woman();
            jill.Name = "Jill";
            jill.HotOrNot = false;

            List<Human> humans = new List<Human>() { tom, joe, sally, jill };

            foreach (Human human in humans)
                Console.WriteLine(human.Name);

            Console.Read();
        }
    }

    public class Human
    {
        public string Name { get; set; }
    }

    public class Man : Human
    {
        public int Manliness { get; set; }
    }

    public class Woman : Human
    {
        public bool HotOrNot { get; set; }
    }

You may also have a method that accepts a Human parameter. In which case, it would be acceptable to provide a Man or a Woman as an argument, as they derive from Human.

static void DoSomething(Human human)
        {
            Console.WriteLine(human.Name);
        }


        // in some other method
        DoSomething(tom);

It's not uncommon for you to want to work in such a manner. You might not care what the specific types of your objects happen to be, you're only interested (for at least part of the functionality) that the objects be of a given base-type (or interface, as the case may be).

Edited 6 Years Ago by apegram: n/a

Hello

Can someone help me understand the difference?

Human h = new Human();
or
Man m = new Man();

vs.
Human h2 = new Man();

recently I have seen an object instantiated like this - where it references this other object (after the "new" keyword )

I am trying to figure out what exactly this does or even what it's called so I can look into it more.

thank you

Human is base class . if u create base class object then u can directly access that methods .
e.g. Human h = new Human();
or
Man m = new Man();
they are totally different we can not use polymorphism and overloaded concept in this scenario.
But we use
Human h2 = new Man();
this Man class reference will be created and Human class object will be created and we can call h2.ManMethod().

Human h2 = new Man();
this Man class reference will be created and Human class object will be created and we can call h2.ManMethod().

That's true, but intelisense won't detect that "ManMethod" is a valid method. If you said

Human h2 = new Woman();
h2.ManMethod();

It would compile, then blow up with an exception. Don't do this unless you are absolutely sure that the method exists.
This is also related to casting as well

byte[,] nms = (byte[,]) Numbrs.SaveFinalNmbrs[i];

is an example of one of my lines of code. SaveFinalNmbrs is an ArrayList, so it only contains the Object type. You HAVE to cast it for this code to work. The = new Man() works without casting because the code understands they are both Human. You can put it into the ArrayList without casting because whatever you have defined, it is an Object. You can't do Man h2 = new Human(); because a Human isn't a Man. I'm sure that would compile if you cast it as a Man, but I'm pretty sure your code would blow up the second it tries to execute that line.
When you create a windows app, how much coding to you do to paint the windows form? Resize it by dragging a side? None, right? that's because your app is a System.Windows.Forms.Form and you automatically inherit all that functionality.

You might not often see a class instantiated in such a way, but go back to what I said about perhaps having a collection of human-derived objects.

class Program
    {
        static void Main(string[] args)
        {
            Man tom = new Man();
            tom.Name = "Tom";
            tom.Manliness = 95;

            Man joe = new Man();
            joe.Name = "Joe";
            joe.Manliness = 92;

            Woman sally = new Woman();
            sally.Name = "Sally";
            sally.HotOrNot = true;

            Woman jill = new Woman();
            jill.Name = "Jill";
            jill.HotOrNot = false;

            List<Human> humans = new List<Human>() { tom, joe, sally, jill };

            foreach (Human human in humans)
                Console.WriteLine(human.Name);

            Console.Read();
        }
    }

    public class Human
    {
        public string Name { get; set; }
    }

    public class Man : Human
    {
        public int Manliness { get; set; }
    }

    public class Woman : Human
    {
        public bool HotOrNot { get; set; }
    }

You may also have a method that accepts a Human parameter. In which case, it would be acceptable to provide a Man or a Woman as an argument, as they derive from Human.

static void DoSomething(Human human)
        {
            Console.WriteLine(human.Name);
        }


        // in some other method
        DoSomething(tom);

It's not uncommon for you to want to work in such a manner. You might not care what the specific types of your objects happen to be, you're only interested (for at least part of the functionality) that the objects be of a given base-type (or interface, as the case may be).

okay - thanks guys. So it seems like it's not done this way often...
I just thought I saw this a few times like in the above example..also with an interface example although I couldn't find that particular example.

Anyway, I guess I should be more worried about how it can work together if derived or parent class. like in your collection example...

okay - thanks guys. So it seems like it's not done this way often...
I just thought I saw this a few times like in the above example..also with an interface example although I couldn't find that particular example.

OK, I missed it. What isn't done often? Inheritance? Something that is almost impossible to code well, an app that doesn't use inheritance, isn't done too often?
An interface is a special type of inheritance, you can't create an interface, but you can have an object that is an interface. The interface guarantees that certain methods do exist in any object that is an interface.
All of this has to do with casting. An example of implicit casting is:

Human h2 = new Man();

This explicit cast does the same thing:

Human h2 = (Human) new Man();

This is an integral concept of OO design.
When you do event processing in windows for example, one of the parameters passed is an Object. Depending on what you are doing, you can ignore it or do something with it, it's your choice. You don't have a choice of not supplying the Object in the parameter list of a Form event because the Form class insists it is passed.

It's not uncommon for you to want to work in such a manner....

sorry - I read this wrong - I thought you wrote: It's not COMMON (I left out the "UN") but I was talking about instantiating a class this way not inheritance.

I am obviously very new to this stuff and struggling to learn. Hopefully it will click as I persist...
I appreciate your examples and your time. All very helpful..

Edited 6 Years Ago by fxpepper: n/a

sorry - I read this wrong - I thought you wrote: It's not COMMON (I left out the "UN") but I was talking about instantiating a class this way not inheritance.

I am obviously very new to this stuff and struggling to learn. Hopefully it will click as I persist...
I appreciate your examples and your time. All very helpful..

It wasn't my comment, but it is a sentiment I agree with. (not uncommon, a double negative, that's bad English because it leads to misunderstandings like yours, but the sentiment was clear to me because this term is unfortunately common.)
When you code, you model. The human model is a common one used in examples because everyone understands it. It's also a great example because the model changes over time. When I was born, if you were male and adult, you had to be a Man. Today, it's not that obvious. It's not obvious to me that someone born male is still male. It is obvious to me that someone born male can be a Woman. Every criteria that you can use to prove is still male can also be used to prove people born female aren't female, so they must be male. How you implement the model is the trick.

On that note, the Man : Human or Woman : Human really isn't that great of an example because gender could easily be distinguished by a property, there's no reason to split the genders into sibling classes.

A more common example you may run into is something like

Giraffe : Mammal : Animal
Iguana : Reptile : Animal

So Giraffe is a Mammal is an Animal
And Iguana is a Reptile is an Animal

Which leads to possible code like this

static void Main(string[] args)
        {
            Iguana iguana = new Iguana();
            Giraffe giraffe = new Giraffe();

            AnimalFoo(iguana); // legal
            AnimalFoo(giraffe); // legal
            MammalFoo(giraffe); // legal
            MammalFoo(iguana); // NOT legal
            ReptileFoo(iguana); // legal
        }

        static void AnimalFoo(Animal animal)
        {
        }

        static void MammalFoo(Mammal mammal)
        {
        }

        static void ReptileFoo(Reptile reptile)
        {
        }

Quick quiz: Given

public class Human
{
    public string name {get;set;}
    private DateTime Dbirthdate;
    private bool Disfemale;
    public bool IsFemale{get{return Disfemale;}}
    public virtual DateTime BirthDate { get { return Dbirthdate; } set { return; } }
    public Human(string MorF, DateTime Birth ){
        this.Dbirthdate = Birth;
        if (MorF.ToUpper() == "M") Disfemale = false;
        else Disfemale = true;
        name="Unknown";
    }
    public Human(string MorF, DateTime Birth, string givenname)
    {
        this.Dbirthdate = Birth;
        if (MorF.ToUpper() == "M") Disfemale = false;
        else Disfemale = true;
        name = givenname;
    }
}
public class Man : Human {
    private DateTime Mbirthdate;
    public Man()
        : base("M", new DateTime(1800, 1, 1))
    {
        //Default could be set to 21 years old DateTime.Now.AddYears(-21)) or 
        //REALLY old. Too bad for a historical figure. If dead is it still a Man?
        Mbirthdate = DateTime.Now.AddYears(-21);
    }
    public override DateTime BirthDate { get { return Mbirthdate; } set { Mbirthdate = value; } }
}

And in your main code:

Man mn = new Man();
        Human hmn = mn;
        mn.BirthDate = new DateTime(2007, 9, 21);
        hmn.BirthDate = new DateTime(2008, 9, 21);

What years are in hmn.BirthDate and mn.BirthDate?
change

Human hmn = mn;

to

Human hmn = new Man();

Same question.
change

...
public virtual DateTime BirthDate { get { return Dbirthdate; } set { return; } }
...
public override DateTime BirthDate { get { return Mbirthdate; } set { Mbirthdate = value; } }
...

to

...
public DateTime BirthDate { get { return Dbirthdate; } set { return; } }
...
public DateTime BirthDate { get { return Mbirthdate; } set { Mbirthdate = value; } }
...

Same question.
This will compile and execute, but what kind of warning will you get and why?

On that note, the Man : Human or Woman : Human really isn't that great of an example because gender could easily be distinguished by a property, there's no reason to split the genders into sibling classes. ...

Too true, but that was the original example. Have you seen any textbooks that don't give inane examples of inheritance?

Too true, but that was the original example. Have you seen any textbooks that don't give inane examples of inheritance?

Oh yea, my example requires that you instantiate human with an indication whether it is male or female and requires a birthdate. "Human x = new Human();" would blow up. If you provide a new birthdate "Human x = new Human("x",new new DateTime(2009, 9, 21));" you'd have a female that is NOT a Woman and you could NEVER change the original birth date. I didn't apply logic to keep a minimum age of 13 or older but that could be done. The hassle is that if you wanted a Woman class you'd almost have to copy the Man class to have a settable date. This is really poor design, even when I wrote the example. Man, I AM an inane "Textbook" example!

kplcjl, your quick quiz highlights some important issues relating to inheritance and reference types. But i think someone just setting out in c# might struggle to understand the 'why' of the answers if they manage to find them at all.

For the OP's benefit; classes are a reference type. When you instantiate them, an object is created on the heap and a pointer to that object is created in the stack.
If you call:

Man mn = new Man();
        Human hmn = mn;

You will end up with a single instance of the Man class stored on the heap and both mn and hmn will 'reference' that object. So when you call:

mn.BirthDate = new DateTime(2007, 9, 21);
        hmn.BirthDate = new DateTime(2008, 9, 21);

The Man object in the heap will have its BirthDate set first to 21/9/2007 then 21/9/2008 because both of the variables are pointing to the same object.

If you call Human hmn = new Man(); instead of Human hmn = mn; you are creating a second instance of the Man class in the heap. So now hmn points to a different instance that stores its own distinct values.

Lastly, by removing the virtual and override lines you are now hiding the method instead of overriding it. These are both ways to implement polymorphism.

kplcjl, your quick quiz highlights some important issues relating to inheritance and reference types. But i think someone just setting out in c# might struggle to understand the 'why' of the answers if they manage to find them at all.
...

The Man object in the heap will have its BirthDate set first to 21/9/2007 then 21/9/2008 because both of the variables are pointing to the same object.
...
Lastly, by removing the virtual and override lines you are now hiding the method instead of overriding it. These are both ways to implement polymorphism.

By removing the virtual and override lines I also wanted to point out
in

mn.BirthDate = new DateTime(2007, 9, 21);
        hmn.BirthDate = new DateTime(2008, 9, 21);

mn.BirthDate would always return 1/1/1800 no matter what. because the set accessor doesn't do anything in Human and the source. I had to include set for virtual overrides to work, also if you reversed the process order, hmn.BirthDate = 9/21/2008 would remain the value assigned even if both were the same instance.

Whoops, forgot to mention without virtual, C# generates a warning that both classes have the same method defined and you should put new in your code to indicate it was an intentional duplicate.

By removing the virtual and override lines I also wanted to point out
in

mn.BirthDate = new DateTime(2007, 9, 21);
        hmn.BirthDate = new DateTime(2008, 9, 21);

mn.BirthDate would always return 1/1/1800 no matter what. because the set accessor doesn't do anything in Human and the source. I had to include set for virtual overrides to work, also if you reversed the process order, hmn.BirthDate = 9/21/2008 would remain the value assigned even if both were the same instance.

Whoops, my mistake. hmn.BirthDate would always return 1/1/1800 no matter what. Don't reverse the order. mn.BirthDate = 9/21/2007 would remain the value assigned even if both were the same instance.

This article has been dead for over six months. Start a new discussion instead.