Classes inheritance and something that confuses me
-
Since
e
is defined as anEmployee
then it only has access to the properties and methods of the base class. However, you should go back to the book to see what the author is trying to illustrate with this sample, as any comments made here will most likely be out of context.The best things in life are not things.
The book is about casting and the author says that the above is legal instead the following is not:
class Employee { }
class ContractEmployee : Employee { }
class CastExample2
{public static void Main () { ContractEmployee ce = new Employee(); // Won't compile. }
}
And this is ok for me, but still I do not understand why is such a declaration useful and what it actually means. If I declare
Employee e = new ContractEmployee()
and e has the properties of the Employee class, why then not writeEmployee e = new Employee()
as we "normally" do? What is the difference between those two? -
Hallo, I am reading a book on C# and I came to the following example.
class Employee { }
class ContractEmployee : Employee { }
class CastExample1
{
public static void Main ()
{
Employee e = new ContractEmployee();
}
}So my question is maybe simple: which properties and methods does the object e has? Those from the base class Employee or of the derived class ContractEmployee? Maybe it is the syntax that confuses me... how should I read this? Let's create an Object which belongs to the Employee class but gets all its properties from the ContractEmployee class? Or maybe it's the opposite that is true? I really don't get it and I would appreciate an explanation. Thanks in advance.
You have
Employee
instance and you assign an instance of theContractEmployee
to it. So you can do something like this (I'll take example from Wayne Gaylard):class Employee
{
public void Talk()
{
MessageBox.Show("I am an Employee.");
}
}class ContractEmployee: Employee
{
public void ContractTalk()
{
MessageBox.Show("I am a Contract Employee.");
}
}Then you can do:
static void CreateEmployee()
{
Employee e = new ContractEmployee();
e.Talk();
((ContractEmployee)e).ContractTalk();
}But you can't do:
static void CreateEmployee()
{
Employee e = new Employee();
e.Talk();
((ContractEmployee)e).ContractTalk(); // Here you will get an exception at runtime. Compliler won't find any errors.
}On this example it seems useless, but it is sometimes useful. For example you can have a class structure of different user type, all inheriting from
User
, you can store them on in a collection ofUser
sDon't forget to rate answer, that helped you. It will allow other people find their answers faster.
-
The book is about casting and the author says that the above is legal instead the following is not:
class Employee { }
class ContractEmployee : Employee { }
class CastExample2
{public static void Main () { ContractEmployee ce = new Employee(); // Won't compile. }
}
And this is ok for me, but still I do not understand why is such a declaration useful and what it actually means. If I declare
Employee e = new ContractEmployee()
and e has the properties of the Employee class, why then not writeEmployee e = new Employee()
as we "normally" do? What is the difference between those two?As I said before, you need to go back to the book and see where the author is going with this. There are often cases where you would do this when passing an object through some code that knows about
Employee
s but does not know aboutContractEmployee
s. Some common code could adjust the properties ofe
without needing to know what type of employee the object refers to. At some later point you could upcaste
to aContractEmployee
and process as necessary.The best things in life are not things.
-
The book is about casting and the author says that the above is legal instead the following is not:
class Employee { }
class ContractEmployee : Employee { }
class CastExample2
{public static void Main () { ContractEmployee ce = new Employee(); // Won't compile. }
}
And this is ok for me, but still I do not understand why is such a declaration useful and what it actually means. If I declare
Employee e = new ContractEmployee()
and e has the properties of the Employee class, why then not writeEmployee e = new Employee()
as we "normally" do? What is the difference between those two?nstk wrote:
And this is ok for me, but still I do not understand why is such a declaration useful and what it actually means. If I declare
Employee e = new ContractEmployee()
and e has the properties of the Employee class, why then not write
Employee e = new Employee()
as we "normally" do? What is the difference between those two?The first code line means you create a new instance of class ContractEmployee. This object in memory *is* a ContractEmployee. You then have a variable
e
which is an Employee. Since a ContractEmployee is specifically also an Employee (ContractEmployee derives from Employee) this is a valid assigment. The difference between the two lines is that in the first, e behaves like a ContractEmployee and in the second e behaves like an Employee. However, through e you can only access members of ContractEmployee which are also part of Employee. The most important thing to distinguish in these examples is the difference between the actual object created (and in memory), which is specified by new, and the interface you are using to access it. The actual object you create is different in both examples, but the interface you use to access them is the same. To properly explain this sample, we'd need to explain almost everything about classes and inheritance, and it seems you're not there yet. So probably, it's best to keep those questions in the back of your head until you get to that subject and ask them again; probably, you'll find you know the answers -
nstk wrote:
And this is ok for me, but still I do not understand why is such a declaration useful and what it actually means. If I declare
Employee e = new ContractEmployee()
and e has the properties of the Employee class, why then not write
Employee e = new Employee()
as we "normally" do? What is the difference between those two?The first code line means you create a new instance of class ContractEmployee. This object in memory *is* a ContractEmployee. You then have a variable
e
which is an Employee. Since a ContractEmployee is specifically also an Employee (ContractEmployee derives from Employee) this is a valid assigment. The difference between the two lines is that in the first, e behaves like a ContractEmployee and in the second e behaves like an Employee. However, through e you can only access members of ContractEmployee which are also part of Employee. The most important thing to distinguish in these examples is the difference between the actual object created (and in memory), which is specified by new, and the interface you are using to access it. The actual object you create is different in both examples, but the interface you use to access them is the same. To properly explain this sample, we'd need to explain almost everything about classes and inheritance, and it seems you're not there yet. So probably, it's best to keep those questions in the back of your head until you get to that subject and ask them again; probably, you'll find you know the answers -
Hallo, I am reading a book on C# and I came to the following example.
class Employee { }
class ContractEmployee : Employee { }
class CastExample1
{
public static void Main ()
{
Employee e = new ContractEmployee();
}
}So my question is maybe simple: which properties and methods does the object e has? Those from the base class Employee or of the derived class ContractEmployee? Maybe it is the syntax that confuses me... how should I read this? Let's create an Object which belongs to the Employee class but gets all its properties from the ContractEmployee class? Or maybe it's the opposite that is true? I really don't get it and I would appreciate an explanation. Thanks in advance.
Let's make a better example for this:
class Employee
{
public string Name { get; set; }
}class ContractEmployee : Employee
{
public object Contract { get; set; }
}class Program
{
static void Main()
{
Employee e = new ContractEmployee();
e.Name = "Ricky"; // No problem with this
e.Contract = new object(); // Problem: this does not compile
}
}nstk wrote:
which properties and methods does the object e has?
e
object, at runtime, has the properties and methods defined withinContractEmployee
class, because it is the object you have created with new, so it hasName
(inherited fromEmployee
class), andContract
(defined withinContractEmployee
). However, without any casting, frome
object you will only be able to access those members defined withinEmployee
class (Name
property in this case), because it is the type you have used to declare the object. Why? Becausee
object is declared asEmployee
, andEmployee
does not define a member namedContract
. Yes,e
is aContractEmployee
instance and, yes, it has aContract
property, but the compiler does not know it. All the compiler knows is thate
object is declared asEmployee
, so it allows you to access only the members defined inEmployee
class. So, if you want to access theContract
property ofe
object, in this case, you would need a previous casting operation:((ContractEmployee)e).Contract = new object();
// or
ContractEmployee ce = (ContractEmployee)e;
ce.Contract = new object();nstk wrote:
how should I read this?
Any
ContractEmployee
object is aEmployee
, always, so you can declare anEmployee
and instantiate aContractEmployee
, but not in the other direction, I mean, not all of theEmployee
objects have to beContractEmployee
. -
The book is about casting and the author says that the above is legal instead the following is not:
class Employee { }
class ContractEmployee : Employee { }
class CastExample2
{public static void Main () { ContractEmployee ce = new Employee(); // Won't compile. }
}
And this is ok for me, but still I do not understand why is such a declaration useful and what it actually means. If I declare
Employee e = new ContractEmployee()
and e has the properties of the Employee class, why then not writeEmployee e = new Employee()
as we "normally" do? What is the difference between those two?In short, such a declaration is useful because of polymorphism. Code which does not know about ContractEmployee can still call methods on it if they are overrides of virtual (or abstract or interface-defined) methods of a base class. For example consider the class hierarchy (another common OO tutorial one):
abstract class Animal {
public abstract string Noise { get; }
public virtual string Feed() { return "Mm, tasty."; }
}class Dog : Animal {
public override string Noise { get { return "Woof."} }
public void GiveBone() { Console.WriteLine("Chomp."); }
}class Cow : Animal {
public override string Noise { get { return "Moo."; } }
public override string Feed() { return "I'll only eat it if it's green."; }
}Now, because the methods are virtual, polymorphism will ensure that the appropriate one is called when they are dispatched on an instance of Animal, and 'down-casting' to feed instances to a more generic (in the normal English sense of the word) method is appropriate:
void FeedAndListen(Animal animal){
Console.WriteLine(animal.Feed());
Console.WriteLine(animal.Noise);
// You can't do this, because the animal type is not known
// animal.GiveBone();
}static void Main(){
List animals = new List<Animal>();
animals.Add(new Dog());
animals.Add(new Cow());
foreach(Animal animal in animals) FeedAndListen(animal);
}Note how FeedAndListen produces the output from the derived methods, even though the instances are 'downcasted' into a List<Animal> and passed to it as Animal, not their actual declaration class. Also note how you can put the different subclasses into the one list. Finally, see how Dog inherits the Feed behaviour because it is not overridden. And you can't call methods which are not defined on the base class. I agree with the other comment which says that as you complete your OO training you will naturally see how these concepts work.
-
Hallo, I am reading a book on C# and I came to the following example.
class Employee { }
class ContractEmployee : Employee { }
class CastExample1
{
public static void Main ()
{
Employee e = new ContractEmployee();
}
}So my question is maybe simple: which properties and methods does the object e has? Those from the base class Employee or of the derived class ContractEmployee? Maybe it is the syntax that confuses me... how should I read this? Let's create an Object which belongs to the Employee class but gets all its properties from the ContractEmployee class? Or maybe it's the opposite that is true? I really don't get it and I would appreciate an explanation. Thanks in advance.
The object refered to by
e
is aContractEmployee
and therefore contains all the trimmings of aContractEmployee
. However... becausee
has been declared as anEmployee
, it exposes only those properties and methods defined by the base class. In other words, the following test will succeed:Employee e = new ContractEmployee();
Debug.Assert (e is Employee);
Debug.Assert (e is ContractEmployee());For
e
to expose itsContractEmployee
properties and methods, you'd need to first cast it to aContractEmployee
.Employee e = new ContractEmployee();
ContractEmployee ce = e as ContractEmployee; // unsafe casting; better to use the cast operator
// (ContractEmployee) which will throw on failure
Debug.Assert (ce != null);/ravi
My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com
-
nstk wrote:
And this is ok for me, but still I do not understand why is such a declaration useful and what it actually means. If I declare
Employee e = new ContractEmployee()
and e has the properties of the Employee class, why then not write
Employee e = new Employee()
as we "normally" do? What is the difference between those two?The first code line means you create a new instance of class ContractEmployee. This object in memory *is* a ContractEmployee. You then have a variable
e
which is an Employee. Since a ContractEmployee is specifically also an Employee (ContractEmployee derives from Employee) this is a valid assigment. The difference between the two lines is that in the first, e behaves like a ContractEmployee and in the second e behaves like an Employee. However, through e you can only access members of ContractEmployee which are also part of Employee. The most important thing to distinguish in these examples is the difference between the actual object created (and in memory), which is specified by new, and the interface you are using to access it. The actual object you create is different in both examples, but the interface you use to access them is the same. To properly explain this sample, we'd need to explain almost everything about classes and inheritance, and it seems you're not there yet. So probably, it's best to keep those questions in the back of your head until you get to that subject and ask them again; probably, you'll find you know the answersI thought of it, that maybe it is one of the questions that is going to be answered by itself with time. Nevertheless, thank you for your descriptive answer, it helps a lot. There is however one point regarding the following:
MicroVirus wrote:
The difference between the two lines is that in the first, e behaves like a ContractEmployee and in the second e behaves like an Employee.
In that case shouldn't have been the same if we wrote: ContractEmployee e = new ContractEmployee()
-
In short, such a declaration is useful because of polymorphism. Code which does not know about ContractEmployee can still call methods on it if they are overrides of virtual (or abstract or interface-defined) methods of a base class. For example consider the class hierarchy (another common OO tutorial one):
abstract class Animal {
public abstract string Noise { get; }
public virtual string Feed() { return "Mm, tasty."; }
}class Dog : Animal {
public override string Noise { get { return "Woof."} }
public void GiveBone() { Console.WriteLine("Chomp."); }
}class Cow : Animal {
public override string Noise { get { return "Moo."; } }
public override string Feed() { return "I'll only eat it if it's green."; }
}Now, because the methods are virtual, polymorphism will ensure that the appropriate one is called when they are dispatched on an instance of Animal, and 'down-casting' to feed instances to a more generic (in the normal English sense of the word) method is appropriate:
void FeedAndListen(Animal animal){
Console.WriteLine(animal.Feed());
Console.WriteLine(animal.Noise);
// You can't do this, because the animal type is not known
// animal.GiveBone();
}static void Main(){
List animals = new List<Animal>();
animals.Add(new Dog());
animals.Add(new Cow());
foreach(Animal animal in animals) FeedAndListen(animal);
}Note how FeedAndListen produces the output from the derived methods, even though the instances are 'downcasted' into a List<Animal> and passed to it as Animal, not their actual declaration class. Also note how you can put the different subclasses into the one list. Finally, see how Dog inherits the Feed behaviour because it is not overridden. And you can't call methods which are not defined on the base class. I agree with the other comment which says that as you complete your OO training you will naturally see how these concepts work.
-
Hallo, I am reading a book on C# and I came to the following example.
class Employee { }
class ContractEmployee : Employee { }
class CastExample1
{
public static void Main ()
{
Employee e = new ContractEmployee();
}
}So my question is maybe simple: which properties and methods does the object e has? Those from the base class Employee or of the derived class ContractEmployee? Maybe it is the syntax that confuses me... how should I read this? Let's create an Object which belongs to the Employee class but gets all its properties from the ContractEmployee class? Or maybe it's the opposite that is true? I really don't get it and I would appreciate an explanation. Thanks in advance.
nstk wrote:
Or maybe it's the opposite that is true?
Yes. It is indeed the opposite that is true. The sub class has access to all the protected members of the parent class but not the other way round. Whenever we say we have a object deriving from something, we are always assuming that this object has properties of the parent and adds on some of its own.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.