?
Solved

500pts: Help on instantiating an object

Posted on 2006-05-11
13
Medium Priority
?
226 Views
Last Modified: 2010-04-16
Hi there,

I was reading over one of my c# books about instancing an object, which of course i already do... But i come across something puzzled me and wanted to know why.

Basically its an example in the book that states there are 2 classes. GenericCustomer and Nevermore60Customer (which inherits from base class Generic Customer).

It states to create an instance do the following :

GenericCustomer customer = new Nevermore60Customer();

That confused me, actually maybe i am going crazy but why can't you just do

Nevermore60Customer customer = new Nevermore60Customer();

why must you use GenericCustomer in front?? if you see my mean....

Can anybody clear this up for me?

Thanks in advance

Ian
0
Comment
Question by:ianinspain
  • 4
  • 3
  • 3
  • +1
13 Comments
 
LVL 35

Expert Comment

by:mrichmon
ID: 16663250
You can just do
Nevermore60Customer customer = new Nevermore60Customer();

and in fact in that case customer is more specific.

But let's say you had two classes

Nevermore60Customer and Nevermore100Customer.

Then let's say you had a function that you wanted to do the same thing on both of these types of customer. You could do this:

int DoSomething(GenericCustomer customer)
{ ...
}

and you could then do either:

int myreturn = DoSomething(new Nevermore60Customer ());

or

int myreturn = DoSomething(new Nevermore100Customer ());

Both would work.

So basically in this line:
GenericCustomer customer = new Nevermore60Customer();

You are just using "customer" like it is a GenericCustomer, even though it is a more specific type of Nevermore60Customer.

In general if you know the type you should use the more specific type, and only use the parent type as in that example line of code in the book, if the variable may need to contain different child types.
0
 
LVL 35

Assisted Solution

by:mrichmon
mrichmon earned 600 total points
ID: 16663256
Oh, also note that when you do

GenericCustomer customer = new Nevermore60Customer();

that you can now only call on customer the functions and methods that are part of GenericCustomer.  So if Nevermore60Customer had a member called Nevermore60 - you could not access it without first casting customer into the more specific type.

That is why they say to use a more specific type when possible
0
 
LVL 64

Expert Comment

by:Fernando Soto
ID: 16663355
Hi ianinspain;

The book most likely was talking about polymorphism. This is the ability of an object to look like another object. In this case the author declared the variable customer as follows:

GenericCustomer customer = new Nevermore60Customer();

So he created a variable customer of type GenericCustomer and assigned an object of type Nevermore60Customer which is fine because he is derived from GenericCustomer. You also could have done it the way you stated and the statement would have compiled. Here is the difference. Let say I have a class called GenericCustomer that looks like this:

      public class GenericCustomer
      {
      
            public int gCustomer = 10;
            
            public GenericCustomer()
            {
                  //
                  // TODO: Add constructor logic here
                  //
            }
      }

And a class derived from it as follows:

      public class Nevermore60Customer : GenericCustomer
      {
      
            public int nCustomer = 70;
      
            public Nevermore60Customer()
            {
                  //
                  // TODO: Add constructor logic here
                  //
            }
      }

And you execute the following command:

GenericCustomer customer = new Nevermore60Customer();

You will be able to access the variable gCustomer from that object like this customer.gCustomer but you could not access nCustomer from that object because the variable customer is of type GenericCustomer. But if we were to do this:
Nevermore60Customer customer2 = (Nevermore60Customer ) customer

Now you have access to both gCustomer and nCustomer from the variable customer2.

An example of how this is used could be seen when we declare an ArrayList and add an object to it, which has the definition:

public virtual int Add( object value );

Not that the parameter passed to the array list is of type object, which is the object that all objects are derived from. Sot to add it to the list we do something like this:

ArrayListName.Add(customer2);

Now this is fine because customer3 is derived from type object somewhere up the line. Now when we want to get that customer2 back we can do something like:

Nevermore60Customer  mycustomer = (Nevermore60Customer  ) ArrayListName.Item(1);

Because the Item property returns an object we had to cast the return object.

I hope that this was of some help.

Fernando
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 64

Expert Comment

by:Fernando Soto
ID: 16663382
Hi ianinspain;

Type O, this is the way it should have read above.

Note that the parameter passed to the array list is of type object, which is the object that all objects are derived from. So to add it to the list we do something like this:

Ans this one as well:

Now this is fine because customer2 is derived from type object somewhere up the line. Now when we want to get that customer2 back we can do something like:

Fernando
0
 

Author Comment

by:ianinspain
ID: 16663617
wow thanks both, its beggining to sink in now...

What i can't really understand is: Why would i want Nevermore60Customer is look like GenericCustomer?

Technically Nevermore60customer is inherited from GenericCustom anyway so whats the point?

Also if I use

GenericCustomer customer = new Nevermore60Customer();

then technically I am assigning Nevermore60Customer to GenericCustomer which is fine as it derives from it BUT if i use the method then any static fields that belong only to Nevermore60Customer are not available to me as it is a GenericCustomer - so why even bother ... why not just do

GenericCustomer customer = new GenericCustomer();

So if i am assigning Nevermore60Customer to a genericcustomer i.e. GenericCustomer customer = new Nevermore60Customer();

does this mean that any methods that were declared in Nevermore60Customer as now not available to me because I am using GenericCustomer?

I think i am almost there, i just can't understand what the realworld example would be? If assigning Nevermore60Customer to GenericCustomer (polymorphism) then i lose all the extra functionality of Nevermore60Customer so i could have just used generic customer in the beggining..

Thanks once again for your continued help on this

Ian
0
 

Author Comment

by:ianinspain
ID: 16663631
I must admit i would always do this

Nevermore60Customer customer = new Nevermore60Customer();

because if i needed to override anything then i could using virtual...

but why making it look like its base class is strange...

Almost there i think :-)

Ian
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 16663729
Again, you would do that only if you needed the variable to act as a "pointer" to an unknown child instance type.

So for example using something I actually do.  We have a project that runs rules.  Each rule is a class that MUST inherit from a class called BaseRule.

So we have:

class BaseRule {...}

then

class Rule1: BaseRule { ... }
class Rule2: BaseRule { ... }

etc...

The BaseRule (which is abstract by the way) forces child types to define a function called RunRule which takes in a person object

So we can do this:

BaseRule rule;
Person bob = new Person("Bob");

rule = new Rule1();

rule.RunRule(bob);

rule = new Rule2();

rule.RunRule(bob);

Notice that "rule" is of type BaseRule.

Now in actuality we dynamically load the rules from different assemblies based on an xml file so we don't know what the rule name is in advance, but since we do know that it is of type BaseRule then we know we can declare a variable of that type and assign any child rule to that variable, and call the RunRule based on that parent "rule" instance, which actually points to a more specific child instance.


Does that make sense?
0
 
LVL 6

Assisted Solution

by:PoeticAudio
PoeticAudio earned 600 total points
ID: 16664962
Okay, think about this example.

I know that this isn't a real world example, but it should illustrate a point.

Sometimes it's good to abstract your objects out because if your object derrives from a parent object, then you know for a fact that you can call certain methods. Sometimes you don't know until runtime which object you have at hand, but you do know that you can call a method in that object because all objects of that given type must include a more abstract method from the parent object. Lets look at a little cheesy example.

Notice that in this example I create 2 different object, yet I call the same method and because both objects derrive from a parent object I can call the speak method. This is key... I have 2 objects that both derrive from animal, and both objects have a speak method, but I can run both objects throuth the same MakeAnimalSpeak method and both objects perform their own action.

Here is the abstract class, Animal:
Notice that there is an abstract "Speak" method, so any object that derrives from this must have a speak method.

public abstract class Animal
{
    public abstract void Speak();
}


Here is a class that derrives from Animal. Notice that I override the Speak method and make the Animal object "meow" whenever the speak method is called

public class Cat : Animal
{
    public override void Speak()
    {
        System.Windows.Forms.MessageBox.Show("meow");
    }
}


Okay, now lets make another object that also derrives from Animal, but has a totally different speak method (okay, it's not that different, but we could do whatever we wanted to with the speak method)

public class Dog : Animal
{
    public override void Speak()
    {
        System.Windows.Forms.MessageBox.Show("Bark");
    }
}



Okay, now here's the key. We run an instance of each animal through the SAME method, and because we are passing Animal as a parameter and because speak is a method that both animals have, we can call the speak method, no matter which animal gets passed through the MakeAnimalSpeak method. Again, this happens because both Cat and Dog are Animals, and Speak is an abstract method in the Animal class, so each Animal (Cat & Dog) must have a speak method.

 private void button_Click(object sender, EventArgs e)
{
    Animal myCat = new Cat();
    MakeAnmialSpeak(myCat); //call MakeAnimalSpeak with a cat object

    Animal myDog = new Dog();
    MakeAnmialSpeak(myDog); //call MakeAnimalSpeak with a dog object
}


Notice that in MakeAnimalSpeak all we have to do is call animal.Speak(); and no matter which animal gets passed through, the proper Speak method is called.

private void MakeAnmialSpeak(Animal animal)
{
    animal.Speak();
}


I hope that helped a little bit. It may still be a little confusing because this isn't exactly a real world example, but once you learn how to abstract your objects out a bit, you learn that you gain a great deal in flexibility when it comes to using your objects.
0
 
LVL 6

Expert Comment

by:PoeticAudio
ID: 16665028
Also, lets take my last example one step further. Lets say we want to create an animal and have it speak, but lets say that we create the animal based on a string which represents which animal we want to create. Okay, this one is a little more complex, but you'll get it.

We have a textbox. The user types in which animal they want to hear speak, then they click the button and then we create an animal based on what the user put in the textbox and make it speak. This is a quick example of how we can create an animal at run-time and still call the speak method. Notice that we need to create an instance of Animal in order for this to work properly, we can't make it a concrete Dog object because we don't know that the user wants a dog, we just know that they want an animal.

This example uses a textbox and a button.

Notice that we create an animal based on what the user typed in the textbox. We can then run that animal through the same MakeAnimalSpeak method, and everything works peachy.

private void button1_Click(object sender, EventArgs e)
{
    string animalType = textBox1.Text.Trim();
    Animal animal = CreateAnimal(animalType);
    MakeAnmialSpeak(animal);
}


Okay here is a method where we create an animal based on a string that is passed through. If they pass through "dog" then we create a dog, if they pass through "cat" then we create a cat. If they pass anything else then we will just return null because there are no other animals (yes, this method could be more robust, but I am trying to make it easier to understand)

private Animal CreateAnimal(string animalType)
{
    if (animalType.ToLower() == "dog")
    {  
        return new Dog();  //dog was passed through, return a dog
    }
    else if (animalType.ToLower() == "cat")
    {
         return new Cat(); //cat was passed through, return a cat
    }
    else
    {
         return null;  //well, it wasnt a dog or a cat, so return null
    }
}



Okay here is the "new" MakeAnimalSpeak method. If the animal isnt' null, then we will make it speak. Notice that this method doesn't care which animal it is, as long as it isn't null we can make it speak

private void MakeAnmialSpeak(Animal animal)
{
    if (animal != null)
    {
        animal.Speak();
    }
    else
    {
        MessageBox.Show("Unknown Animal");
    }
}


Okay, here is where all the action happens. We get the string that the user inputs. Then we run that string through a method called CreateAnimal. Now after that we have an animal and we can make it speak regardless of which animal it is. We can't do this if we used a more concrete type, ie, it wouldn't work if we said Dog myDog = CreateAnimal(animalType) because we don't know that it's going to be a dog.

private void button1_Click(object sender, EventArgs e)
{
    string animalType = textBox1.Text.Trim();
    Animal animal = CreateAnimal(animalType);
    MakeAnmialSpeak(animal);
}

This example may seem a bit tricky, but if you really look at it, then I know that you will understand the benefit of of it. I use polymorphism all the time! it can be extremely useful!
0
 
LVL 6

Expert Comment

by:PoeticAudio
ID: 16665041
oops, it's not supposed to be "MakeAnmialSpeak" (Animal, not Anmial!--- doh!), but lucky (because of intellisense) the mispelling is consistant, so you can probably copy-paste the code and it will still work
0
 
LVL 64

Accepted Solution

by:
Fernando Soto earned 800 total points
ID: 16666998
Hi ianinspain;

In my post above I gave you a real world application of why you would what the Class to look like one of the classes it inherits from. The ArrayList is a class that stores things in it. When we place a thing in it we can come back later a get it back again. Now if we told the ArrayList to store this thing and because we operate in a type safe environment it needs to know what type of thing we want to store. So because all things in this case are derived from the class called Object which means that GenericCustomer also derives from it we can store it in an ArrayList even though Nevermore60Customer is what we are really storing. That is why when we get an object out of an ArrayList we need to cast it back to an Nevermore60Customer object. To say it in another way the ArrayList only stores Object, most general class, and so we must look like an object so we morph our GenericCustomer to be an Object. This is a real world reason why you would want to do this.

I hope that this has filled in the gap that you need to make it all come together.

Fernando
0
 

Author Comment

by:ianinspain
ID: 16677667
Thanks everyone for all your comments, after your explanations and digging a little deeper into polymorphism... I got it now....

Its probably something i won't use that much but it is nice to understand it fully..

a big thanks again to everyone involved

Ian
0
 
LVL 6

Expert Comment

by:PoeticAudio
ID: 16678198
you'd be suprised how much you use polymorphism, actually.

Once you fully understand how to construct your objects and have a really good grasp on OOP, it becomes second nature to build classes that take full advantage of OOP constructs, including polymorphism.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Screencast - Getting to Know the Pipeline
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question