Please tell me what is of parent object instantiating with child class like:
public class A
{
public A()
{
Console.WriteLine("A");
}
public virtual void method()
{
Console.WriteLine("AM");
}
}
public class B : A
{
public B()
{
Console.WriteLine("B");
}
public new void method()
{
Console.WriteLine("BM");
}
public void method1()
{
Console.WriteLine("BM1");
}
}
class Program
{
static void Main(string[] args)
{
A obj = new B();// what is use of it?
obj.method();
Console.Read();
}
private void methodP1()
{
}
}
please tell me what is use of
Parent obj = new Child();
as i we can only call to only public methods of parent class which is possible using
Parent obj = new Parent();
is it possible: Child obj = new Parent() ?
please tell me what is use of Parent
obj = new Child(); as i we can only
call to only public methods of parent
class which is possible using Parent
obj = new Parent();
This is the basis for polymorphism: Imagine you have several child classes that inherit from you parent class. You want to use all these child classes through the interface / methods defined on your parent class, without worrying about the implementation details in each child class (each might do something different, but with the same overall semantics).
This is possible because the child class has a IS A relationship with its parent class since child inherits from parent.
In your example, B is-a A, but A is-not-a B.
The above is of use when the code using the reference to B can only understand (or needs to understand) types of A. B is a specialisation of A. Imagine something like (pseudo-code)
Shape s;
if (x == 1) {
s = new Square();
}
else {
s = new Triangle();
}
// following code knows only about Shapes
s.draw();
s.calculateArea();
The following code doesn't need to know if s is a square or a triangle, just that it's a shape. What use is that ? If you call s.draw(), the shape itself determines how it's going to look. The code calling it doesn't know or care.
This is a key point of object-oriented programming. Asking objects to do things for you rather than determine yourself what's needed.
Note that your final question doesn't intuitively make sense when using this example.
Shape s = new Square(); // fine
vs
Square s = new Shape(); // can you instantiate a "shape" and why then do you decide it's a square?
BrokenGlass's answer is correct. However, your sample will have different behaviour depending upon whether you declare obj as type A or B.
In the case of A obj = new B(); the program will output A B AM because the compiler is linking to the virtual method A.method, which class B then inherits.
In the case of B obj = new B(); the program outputs A B BM because the compiler is directed to use the new method B.method().
If B.method() was instead declared as public override void method(), then the output would always be A B BM regardless of whether obj was declared as type A or type B.
Thus your example does not show polymorphism in the classic sense, as the method called on instances of type B depends on the type of the variable to which the instance is assigned. This can make debugging fun and interesting.
The reason that you would use polymorphism is so that you can pass a more specific object to an entity that only requires a more general object. The entity that receives the object only cares about the public interface that is exposed, not the details of how the methods in that interface are carried out. Here's a simple class hierarchy:
public class Animal
{
public virtual string GetFood()
{
return "Food";
}
}
public class Monkey : Animal
{
public override string GetFood()
{
return "Bananas";
}
}
public class Cow : Animal
{
public override string GetFood()
{
return "Grass";
}
}
And here's how you could use the polymorphism:
class Program
{
static void Main(string[] args)
{
Animal[] animalArray = { new Monkey(), new Cow() };
foreach (Animal a in animalArray) {
WhatDoIEat(a); // Prints "Bananas", then "Grass"
}
}
static void WhatDoIEat(Animal a)
{
Console.WriteLine(a.GetFood());
}
}
If you have to use only the methods on the parent class, you can go ahead and instantiate it. The object of a child class is to add functionality to the parent class while keeping the parent intact. Instantiating the parent through the child without further use of the child functionality does not make sense.
There's no use in simple examples like yours, where the scope of usage for the variable is limited. But it's important to understand that in .NET variables has types that are static, known at compile time and even if obj keeps a reference to Child class, it is still typed as Parent.
And when you have method that requires Parent, you can pass obj (with type Child) to it (and it still behaves like Child) - this is an example of Child being referred by Parent type.
Child obj = new Parent() is not possible, Parent is not a Child, compiler wouldn't let you assign object to variable of incompatible type.
Say you have a parent class called Animal and child classes called Dog, Cat, and Lizard. Each class has a method call makeSound(). Then when you say Animal a1 = new Dog(); and Animal a2 = new Cat(), a1.makeSound() will bark and a2.makeSound() will meow.
The technical term for this behavior is called polymorphism. It is useful for code reuse. You only need to write code once for an application that has Animals makeSound() when they are happy, instead of separate code for each animal type.
Another use of polymorphism is hiding your code's implementation from other users. For example you can show other users that you are using a List and then you have the choice to implement the List as a LinkedList or as an ArrayList. You can also choose a LinkedList and then at a later time switch to an ArrayList without effecting your users.
You also can't say Dog d = new Animal() because a Dog is an Animal but an Animal is not necessarily a Dog.
When You Know Common features about a Class which inherits from and when you dont know the exact child you can put the data on Parent class, whenever you knew about the child class you can assign those values on it.
Related
Can anybody tell the working of overriding and hiding in terms of memory and references.
class A
{
public virtual void Test1() { //Impl 1}
public virtual void Test2() { //Impl 2}
}
class B : A
{
public override void Test1() { //Impl 3}
public new void Test2() { Impl 4}
}
static Main()
{
A aa=new B() //This will give memory to B
aa.Test1(); //What happens in terms of memory when this executes
aa.Test2(); //-----------------------SAME------------------------
}
Here memory is with class B but in the second statement aa.Test2 class A's method will be called. Why is it? If B has memory then B's method should be called (in my point of view).
Any link / exercise that describes this fundamental very deeply and completely will be a big help.
Take a look at this answer to a different question by Eric Lippert.
To paraphrase (to the limits of my comprehension), these methods go into "slots". A has two slots: one for Test1 and one for Test2.
Since A.Test1 is marked as virtual and B.Test1 is marked as override, B's implementation of Test1 does not create its own slot but overwrites A's implementation. Whether you treat an instance of B as a B or cast it to an A, the same implementation is in that slot, so you always get the result of B.Test1.
By contrast, since B.Test2 is marked new, it creates its own new slot. (As it would if it wasn't marked new but was given a different name.) A's implementation of Test2 is still "there" in its own slot; it's been hidden rather than overwritten. If you treat an instance of B as a B, you get B.Test2; if you cast it to an A, you can't see the new slot, and A.Test2 gets called.
To add to #Rawling's answer, practical examples could be shown using an example such as this:
class Base
{
// base property
public virtual string Name
{
get { return "Base"; }
}
}
class Overriden : Base
{
// overriden property
public override string Name
{
get { return "Overriden"; }
}
}
class New : Base
{
// new property, hides the base property
public new string Name
{
get { return "New"; }
}
}
1. Overriding
In case of the overriden property, base class' virtual method's slot is replaced by a different implementation. Compiler sees the method as virtual, and must resolve its implementation during run-time using the object's virtual table.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new Overriden();
// Base.Name is virtual, so the vtable determines its implementation
Console.WriteLine(b.Name); // prints "Overriden"
Overriden o = new Overriden();
// Overriden.Name is virtual, so the vtable determines its implementation
Console.WriteLine(o.Name); // prints "Overriden"
}
2. Hiding
When a method or a property is hidden using the new keyword, the compiler creates a new non-virtual method for the derived class only; base class' method remains untouched.
If the type of the variable is Base (i.e. only contains the virtual method), its implementation will be resolved through the vtable. If the type of the variable is New, then the non-virtual method or property will be invoked.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new New();
// type of `b` variable is `Base`, and `Base.Name` is virtual,
// so compiler resolves its implementation through the virtual table
Console.WriteLine(b.Name); // prints "Base"
New n = new New();
// type of `n` variable is `New`, and `New.Name` is not virtual,
// so compiler sees `n.Name` as a completely different property
Console.WriteLine(n.Name); // prints "New"
}
3. Summary
If a part of your code accepts the base type, it will always use the virtual table during run-time. For most OOP scenarios, this means that marking a method as new is very similar to giving it a completely different name.
4. Object sizes after instantiation
Note that instantiating any of these types doesn't create a copy of the virtual table. Each .NET object has a couple of bytes of header and a pointer to the virtual table of table of its type (class).
Regarding the new property (the one which is not virtual), it is basically compiled as a static method with thiscall semantics, meaning that it also doesn't add anything to the size of the instance in memory.
Already answered at here
Overriding is the definition of multiple possible implementations of the same method signature, such that the implementation is determined by the runtime type of the zeroth argument (generally identified by the name this in C#).
Hiding is the definition of a method in a derived type with a signature identical to that in one of its base types without overriding.
The practical difference between overriding and hiding is as follows:
Hiding is for all other members (static methods , instance members, static members). It is based on the early binding . More clearly , the method or member to be called or used is decided during compile time.
•If a method is overridden, the implementation to call is based on the run-time type of the argument this.
•If a method is simply hidden, the implementation to call is based on the compile-time type of the argument this.
Here are some samples : Example # 1. and Example # 2
Test1() method in class A and test1() method in class B will executes according to MethdOverriding.
Test2() method in class A and test2() method in class B will executes according to Method Hiding.
In method Overriding the child class members will execute, and in Method Hiding the Parent class members will execute.
Put simply when overriding a method or property the override method must have the same signature as the base method. When hiding this is not required, the new object can take any form as shown below
// base
public int GrossAmount { get; set; }
// hiding base
public new string GrossAmount
{
get;
set;
}
Deducting from the code provided you should have B:A.
You can hide a method in case when you want create your own implementation of the (say) method of the base class, which can not be overriden, cause, say, it's not virtual.
In my expirience, I used hiding mostly for debug purposes.
For example when I don't know who sets the property of some 3rd prt component, whom code is not available to me. So what I do is:
create a child class from the component
hide the property of interest with new keyword
put the breakpoint in set
and wait when it will be hit.
Sometimes, very useful and helps me get information in fast way, especially in first stage when you're learning new components, frameworks, libraries.. whatever.
By hiding a method or a property you are simply stating that you want to stop such method being polymorphic when you have an object of that type. Additionally hidden methods are called in a non polymorphic way so to call these method type has to be know at compile time, as it was a simply non virtual method.
public class BaseClass
{
public void PrintMethod()
{
Console.WriteLine("Calling base class method");
}
}
public class ChildClass
{
public new void PrintMethod()
{
Console.WriteLine("Calling the child or derived class method");
}
}
class Program
{
static void Main()
{
BaseClass bc = new ChildClass();
bc.PrintMethod();
}
}
Method Hiding is that when Base Class reference variable pointing to a child class object. It will invoke the hidden method in base Class.
Where as, When We declare virtual method in the base class. We override that method in the derived or child class. Then Base Class reference variable will call the derived class method. This is called Method Overriding.
class Base {
int a;
public void Addition() {
Console.WriteLine("Addition Base");
}
public virtual void Multiply()
{
Console.WriteLine("Multiply Base");
}
public void Divide() {
Console.WriteLine("Divide Base");
}
}
class Child : Base
{
new public void Addition()
{
Console.WriteLine("Addition Child");
}
public override void Multiply()
{
Console.WriteLine("Multiply Child");
}
new public void Divide()
{
Console.WriteLine("Divide Child");
}
}
class Program
{
static void Main(string[] args)
{
Child c = new Child();
c.Addition();
c.Multiply();
c.Divide();
Base b = new Child();
b.Addition();
b.Multiply();
b.Divide();
b = new Base();
b.Addition();
b.Multiply();
b.Divide();
}
}
Output : -
Addition Child
Multiply Child
Divide Child
Addition Base
Multiply Child
Divide Base
Addition Base
Multiply Base
Divide Base
At the time of overriding the compiler checks the object of the class but in
in hiding compiler only checks the reference of the class
Consider this code:
class Program
{
static void Main(string[] args)
{
Person person = new Teacher();
person.ShowInfo();
Console.ReadLine();
}
}
public class Person
{
public void ShowInfo()
{
Console.WriteLine("I am Person");
}
}
public class Teacher : Person
{
public new void ShowInfo()
{
Console.WriteLine("I am Teacher");
}
}
When I run this code, the following is outputted:
I am Person
However, you can see that it is an instance of Teacher, not of Person. Why does the code do that?
There's a difference between new and virtual/override.
You can imagine, that a class, when instantiated, is nothing more than a table of pointers, pointing to the actual implementation of its methods. The following image should visualize this pretty well:
Now there are different ways, a method can be defined. Each behaves different when it is used with inheritance. The standard way always works like the image above illustrates. If you want to change this behavior, you can attach different keywords to your method.
1. Abstract classes
The first one is abstract. abstract methods simply point to nowhere:
If your class contains abstract members, it also needs to be marked as abstract, otherwise the compiler will not compile your application. You cannot create instances of abstract classes, but you can inherit from them and create instances of your inherited classes and access them using the base class definition. In your example this would look like:
public abstract class Person
{
public abstract void ShowInfo();
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
public class Student : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a student!");
}
}
If called, the behavior of ShowInfo varies, based on the implementation:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a student!'
Both, Students and Teachers are Persons, but they behave different when they are asked to prompt information about themselves. However, the way to ask them to prompt their information, is the same: Using the Person class interface.
So what happens behind the scenes, when you inherit from Person? When implementing ShowInfo, the pointer is not pointing to nowhere any longer, it now points to the actual implementation! When creating a Student instance, it points to Students ShowInfo:
2. Virtual methods
The second way is to use virtual methods. The behavior is the same, except you are providing an optional default implementation in your base class. Classes with virtual members can be instanciated, however inherited classes can provide different implementations. Here's what your code should actually look like to work:
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am a person!");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
The key difference is, that the base member Person.ShowInfo isn't pointing to nowhere any longer. This is also the reason, why you can create instances of Person (and thus it does not need to be marked as abstract any longer):
You should notice, that this doesn't look different from the first image for now. This is because the virtual method is pointing to an implementation "the standard way". Using virtual, you can tell Persons, that they can (not must) provide a different implementation for ShowInfo. If you provide a different implementation (using override), like I did for the Teacher above, the image would look the same as for abstract. Imagine, we did not provide a custom implementation for Students:
public class Student : Person
{
}
The code would be called like this:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a person!'
And the image for Student would look like this:
3. The magic `new` keyword aka "Shadowing"
new is more a hack around this. You can provide methods in generalized classes, that have the same names as methods in the base class/interface. Both point to their own, custom implementation:
The implementation looks like the one, you provided. The behavior differs, based on the way you access the method:
Teacher teacher = new Teacher();
Person person = (Person)teacher;
teacher.ShowInfo(); // Prints 'I am a teacher!'
person.ShowInfo(); // Prints 'I am a person!'
This behavior can be wanted, but in your case it is misleading.
I hope this makes things clearer to understand for you!
Subtype polymorphism in C# uses explicit virtuality, similar to C++ but unlike Java. This means that you explicitly have to mark methods as overridable (i.e. virtual). In C# you also have to explicitly mark overriding methods as overriding (i.e. override) to prevent typos.
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am Person");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am Teacher");
}
}
In the code in your question, you use new, which does shadowing instead of overriding. Shadowing merely affects the compile-time semantics rather than the runtime semantics, hence the unintended output.
You have to make the method virtual and you have to override the function in the child class, in order to call the method of class object you put in parent class reference.
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am Person");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am Teacher");
}
}
Virtual Methods
When a virtual method is invoked, the run-time type of the object is
checked for an overriding member. The overriding member in the most
derived class is called, which might be the original member, if no
derived class has overridden the member. By default, methods are
non-virtual. You cannot override a non-virtual method. You cannot use
the virtual modifier with the static, abstract, private or override
modifiers, MSDN.
Using New for Shadowing
You are using new key word instead of override, this is what new does
If the method in the derived class is not preceded by new or override keywords, the compiler will issue a warning and the method will behave as if the new keyword were present.
If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class, This MSDN article explains it very well.
Early binding VS Late binding
We have early binding at compile time for normal method (not virtual) which is the currrent case the compiler will bind call to method of base class that is method of reference type (base class) instead of the object is held in the referece of base class i.e. derived class object. This is because ShowInfo is not a virtual method. The late binding is performed at runtime for (virtual / overridden method) using virtual method table (vtable).
For a normal function, the compiler can work out the numeric location
of it in memory. Then it when the function is called it can generate
an instruction to call the function at this address.
For an object that has any virtual methods, the compiler will generate
a v-table. This is essentially an array that contains the addresses of
the virtual methods. Every object that has a virtual method will
contain a hidden member generated by the compiler that is the address
of the v-table. When a virtual function is called, the compiler will
work out what the position is of the appropriate method in the
v-table. It will then generate code to look in the objects v-table and
call the virtual method at this position, Reference.
I want to build off of Achratt's answer. For completeness, the difference is that the OP is expecting the new keyword in the derived class's method to override the base class method. What it actually does is hide the base class method.
In C#, as another answer mentioned, traditional method overriding must be explicit; the base class method must be marked as virtual and the derived class must specifically override the base class method. If this is done, then it doesn't matter whether the object is treated as being an instance of the base class or derived class; the derived method is found and called. This is done in a similar fashion as in C++; a method marked "virtual" or "override", when compiled, is resolved "late" (at runtime) by determining the referenced object's actual type, and traversing the object hierarchy downward along the tree from the variable type to the actual object type, to find the most derived implementation of the method defined by the variable type.
This differs from Java, which allows "implicit overrides"; for instance methods (non-static), simply defining a method of the same signature (name and number/type of parameters) will cause the subclass to override the superclass.
Because it's often useful to extend or override the functionality of a non-virtual method you do not control, C# also includes the new contextual keyword. The new keyword "hides" the parent method instead of overriding it. Any inheritable method can be hidden whether it's virtual or not; this allows you, the developer, to leverage the members you want to inherit from a parent, without having to work around the ones you don't, while still allowing you to present the same "interface" to consumers of your code.
Hiding works similarly to overriding from the perspective of a person using your object at or below the level of inheritance at which the hiding method is defined. From the question's example, a coder creating a Teacher and storing that reference in a variable of the Teacher type will see the behavior of the ShowInfo() implementation from Teacher, which hides the one from Person. However, someone working with your object in a collection of Person records (as you are) will see the behavior of the Person implementation of ShowInfo(); because Teacher's method doesn't override its parent (which would also require Person.ShowInfo() to be virtual), code working at the Person level of abstraction won't find the Teacher implementation and won't use it.
In addition, not only will the new keyword do this explicitly, C# allows implicit method hiding; simply defining a method with the same signature as a parent class method, without override or new, will hide it (though it will produce a compiler warning or a complaint from certain refactoring assistants like ReSharper or CodeRush). This is the compromise C#'s designers came up with between C++'s explicit overrides vs Java's implicit ones, and while it's elegant, it doesn't always produce the behavior you would expect if you come from a background in either of the older languages.
Here's the new stuff: This gets complex when you combine the two keywords in a long inheritance chain. Consider the following:
class Foo { public virtual void DoFoo() { Console.WriteLine("Foo"); } }
class Bar:Foo { public override sealed void DoFoo() { Console.WriteLine("Bar"); } }
class Baz:Bar { public virtual void DoFoo() { Console.WriteLine("Baz"); } }
class Bai:Baz { public override void DoFoo() { Console.WriteLine("Bai"); } }
class Bat:Bai { public new void DoFoo() { Console.WriteLine("Bat"); } }
class Bak:Bat { }
Foo foo = new Foo();
Bar bar = new Bar();
Baz baz = new Baz();
Bai bai = new Bai();
Bat bat = new Bat();
foo.DoFoo();
bar.DoFoo();
baz.DoFoo();
bai.DoFoo();
bat.DoFoo();
Console.WriteLine("---");
Foo foo2 = bar;
Bar bar2 = baz;
Baz baz2 = bai;
Bai bai2 = bat;
Bat bat2 = new Bak();
foo2.DoFoo();
bar2.DoFoo();
baz2.DoFoo();
bai2.DoFoo();
Console.WriteLine("---");
Foo foo3 = bak;
Bar bar3 = bak;
Baz baz3 = bak;
Bai bai3 = bak;
Bat bat3 = bak;
foo3.DoFoo();
bar3.DoFoo();
baz3.DoFoo();
bai3.DoFoo();
bat3.DoFoo();
Output:
Foo
Bar
Baz
Bai
Bat
---
Bar
Bar
Bai
Bai
Bat
---
Bar
Bar
Bai
Bai
Bat
The first set of five is all to be expected; because each level has an implementation, and is referenced as an object of the same type as was instantiated, the runtime resolves each call to the inheritance level referenced by the variable type.
The second set of five is the result of assigning each instance to a variable of the immediate parent type. Now, some differences in behavior shake out; foo2, which is actually a Bar cast as a Foo, will still find the more derived method of the actual object type Bar. bar2 is a Baz, but unlike with foo2, because Baz doesn't explicitly override Bar's implementation (it can't; Bar sealed it), it's not seen by the runtime when looking "top-down", so Bar's implementation is called instead. Notice that Baz doesn't have to use the new keyword; you'll get a compiler warning if you omit the keyword, but the implied behavior in C# is to hide the parent method. baz2 is a Bai, which overrides Baz's new implementation, so its behavior is similar to foo2's; the actual object type's implementation in Bai is called. bai2 is a Bat, which again hides its parent Bai's method implementation, and it behaves the same as bar2 even though Bai's implementation isn't sealed, so theoretically Bat could have overridden instead of hidden the method. Finally, bat2 is a Bak, which has no overriding implementation of either kind, and simply uses that of its parent.
The third set of five illustrates the full top-down resolution behavior. Everything is actually referencing an instance of the most derived class in the chain, Bak, but resolution at every level of variable type is performed by starting at that level of the inheritance chain and drilling down to the most derived explicit override of the method, which are those in Bar, Bai, and Bat. Method hiding thus "breaks" the overriding inheritance chain; you have to be working with the object at or below the level of inheritance that hides the method in order for the hiding method to be used. Otherwise, the hidden method is "uncovered" and used instead.
Please read about polymorphism in C#: Polymorphism (C# Programming Guide)
This is an example from there:
When the new keyword is used, the new class members are called instead
of the base class members that have been replaced. Those base class
members are called hidden members. Hidden class members can still be
called if an instance of the derived class is cast to an instance of
the base class. For example:
DerivedClass B = new DerivedClass();
B.DoWork(); // Calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // Calls the old method.
You need to make it virtual and then override that function in Teacher. As you're inheriting and using the base pointer to refer to a derived class, you need to override it using virtual. new is for hiding the base class method on a derived class reference and not a base class reference.
I would like to add a couple of more examples to expand on the info around this. Hope this helps too:
Here is a code sample that clears the air around what happens when a derived type is assigned to a base type. Which methods are available and the difference between overridden and hidden methods in this context.
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
A a = new A();
a.foo(); // A.foo()
a.foo2(); // A.foo2()
a = new B();
a.foo(); // B.foo()
a.foo2(); // A.foo2()
//a.novel() is not available here
a = new C();
a.foo(); // C.foo()
a.foo2(); // A.foo2()
B b1 = (B)a;
b1.foo(); // C.foo()
b1.foo2(); // B.foo2()
b1.novel(); // B.novel()
Console.ReadLine();
}
}
class A
{
public virtual void foo()
{
Console.WriteLine("A.foo()");
}
public void foo2()
{
Console.WriteLine("A.foo2()");
}
}
class B : A
{
public override void foo()
{
// This is an override
Console.WriteLine("B.foo()");
}
public new void foo2() // Using the 'new' keyword doesn't make a difference
{
Console.WriteLine("B.foo2()");
}
public void novel()
{
Console.WriteLine("B.novel()");
}
}
class C : B
{
public override void foo()
{
Console.WriteLine("C.foo()");
}
public new void foo2()
{
Console.WriteLine("C.foo2()");
}
}
}
Another little anomaly is that, for the following line of code:
A a = new B();
a.foo();
The VS compiler (intellisense) would show a.foo() as A.foo().
Hence, it is clear that when a more derived type is assigned to a base type, the 'base type' variable acts as the base type until a method that is overridden in a derived type is referenced.
This may become a little counter-intuitive with hidden methods or methods with the same name (but not overridden) between the parent and child types.
This code sample should help delineate these caveats!
C# is different to java in the parent/child class override behavior. By default in Java all methods are virtual, so the behavior that you want is supported out of the box.
In C# you have to mark a method as virtual in the base class, then you will get what you want.
The new keyword tell that the method in the current class will only work if you have an instance of the class Teacher stored in a variable of type Teacher. Or you can trigger it using castings: ((Teacher)Person).ShowInfo()
The type of variable 'teacher' here is typeof(Person) and this type does not know anything about Teacher class and does not try to look for any methods in derived types. To call method of Teacher class you should cast your variable: (person as Teacher).ShowInfo().
To call specific method based on value type you should use keyword 'virtual' in your base class and override virtual methods in derived classes. This approach allows to implement derived classes with or without overriding of virtual methods. Methods of base class will be called for types without overided virtuals.
public class Program
{
private static void Main(string[] args)
{
Person teacher = new Teacher();
teacher.ShowInfo();
Person incognito = new IncognitoPerson ();
incognito.ShowInfo();
Console.ReadLine();
}
}
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am Person");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am Teacher");
}
}
public class IncognitoPerson : Person
{
}
Might be too late... But the question is simple and the answer should have the same level of complexity.
In your code variable person doesn't know anything about Teacher.ShowInfo().
There is no way to call last method from base class reference, because it's not virtual.
There is useful approach to inheritance - try to imagine what do you want to say with your code hierarchy. Also try to imagine what does one or another tool says about itself. E.g. if you add virtual function into a base class you suppose: 1. it can have default implementation; 2. it might be reimplemented in derived class. If you add abstract function it means only one thing - subclass must create an implementation. But in case you have plain function - you do not expect anyone to change its implementation.
Just wanted to give a brief answer -
You should use virtual and override in classes that could be overridden. Use virtual for methods that can be overriden by child classes and use override for methods that should override such virtual methods.
I wrote the same code as u have mentioned above in java except some changes and it worked fine as excepted. Method of the base class is overridden and so output displayed is "I am Teacher".
Reason: As we are creating a reference of the base class (which is capable of having referring instance of the derived class) which is actually containing the reference of the derived class. And as we know that the instance always look upon its methods first if it finds it there it executes it, and if it doesn't find the definition there it goes up in the hierarchy.
public class inheritance{
public static void main(String[] args){
Person person = new Teacher();
person.ShowInfo();
}
}
class Person{
public void ShowInfo(){
System.out.println("I am Person");
}
}
class Teacher extends Person{
public void ShowInfo(){
System.out.println("I am Teacher");
}
}
Building on Keith S.'s excellent demonstration and every one else's quality answers and for the sake of uber completeness lets go ahead and toss explicit interface implementations in to demonstrate how that works. Consider the below:
namespace LinqConsoleApp
{
class Program
{
static void Main(string[] args)
{
Person person = new Teacher();
Console.Write(GetMemberName(() => person) + ": ");
person.ShowInfo();
Teacher teacher = new Teacher();
Console.Write(GetMemberName(() => teacher) + ": ");
teacher.ShowInfo();
IPerson person1 = new Teacher();
Console.Write(GetMemberName(() => person1) + ": ");
person1.ShowInfo();
IPerson person2 = (IPerson)teacher;
Console.Write(GetMemberName(() => person2) + ": ");
person2.ShowInfo();
Teacher teacher1 = (Teacher)person1;
Console.Write(GetMemberName(() => teacher1) + ": ");
teacher1.ShowInfo();
Person person4 = new Person();
Console.Write(GetMemberName(() => person4) + ": ");
person4.ShowInfo();
IPerson person3 = new Person();
Console.Write(GetMemberName(() => person3) + ": ");
person3.ShowInfo();
Console.WriteLine();
Console.ReadLine();
}
private static string GetMemberName<T>(Expression<Func<T>> memberExpression)
{
MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
return expressionBody.Member.Name;
}
}
interface IPerson
{
void ShowInfo();
}
public class Person : IPerson
{
public void ShowInfo()
{
Console.WriteLine("I am Person == " + this.GetType());
}
void IPerson.ShowInfo()
{
Console.WriteLine("I am interface Person == " + this.GetType());
}
}
public class Teacher : Person, IPerson
{
public void ShowInfo()
{
Console.WriteLine("I am Teacher == " + this.GetType());
}
}
}
Here's the output:
person: I am Person == LinqConsoleApp.Teacher
teacher: I am Teacher == LinqConsoleApp.Teacher
person1: I am Teacher == LinqConsoleApp.Teacher
person2: I am Teacher == LinqConsoleApp.Teacher
teacher1: I am Teacher == LinqConsoleApp.Teacher
person4: I am Person == LinqConsoleApp.Person
person3: I am interface Person == LinqConsoleApp.Person
Two things to note:
The Teacher.ShowInfo() method omits the the new keyword. When new is omitted the method behavior is the same as if the new keyword was explicitly defined.
You can only use the override keyword in conjunction with the virtual key word. The base class method must be virtual. Or abstract in which case the class must also be abstract.
person gets the the base implementation of ShowInfo because the Teacher class can't override the base implementation (no virtual declaration) and person is .GetType(Teacher) so it hides the the Teacher class's implementation.
teacher gets the derived Teacher implementation of ShowInfo because teacher because it is Typeof(Teacher) and it's not on the Person inheritance level.
person1 gets the derived Teacher implementation because it is .GetType(Teacher) and the implied new keyword hides the base implementation.
person2 also gets the derived Teacher implementation even though it does implement IPerson and it gets an explicit cast to IPerson. This is again because the Teacher class does not explicitly implement the IPerson.ShowInfo() method.
teacher1 also gets the derived Teacher implementation because it is .GetType(Teacher).
Only person3 gets the IPerson implementation of ShowInfo because only the Person class explicitly implements the method and person3 is an instance of the IPerson type.
In order to explicitly implement an interface you must declare a var instance of the target interface type and a class must explicitly implement (fully qualify) the interface member(s).
Notice not even person4 gets the IPerson.ShowInfo implementation. This is because even though person4 is .GetType(Person) and even though Person implements IPerson, person4 is not an instance of IPerson.
LinQPad sample to launch blindly and reduce duplication of code
Which I think is what you were trying to do.
void Main()
{
IEngineAction Test1 = new Test1Action();
IEngineAction Test2 = new Test2Action();
Test1.Execute("Test1");
Test2.Execute("Test2");
}
public interface IEngineAction
{
void Execute(string Parameter);
}
public abstract class EngineAction : IEngineAction
{
protected abstract void PerformAction();
protected string ForChildren;
public void Execute(string Parameter)
{ // Pretend this method encapsulates a
// lot of code you don't want to duplicate
ForChildren = Parameter;
PerformAction();
}
}
public class Test1Action : EngineAction
{
protected override void PerformAction()
{
("Performed: " + ForChildren).Dump();
}
}
public class Test2Action : EngineAction
{
protected override void PerformAction()
{
("Actioned: " + ForChildren).Dump();
}
}
class Program
{
static void Main(string[] args)
{
AA aa = new CC();
aa.Print();
}
}
public class AA {public virtual void Print() => WriteLine("AA");}
public class BB : AA {public override void Print() => WriteLine("BB");}
public class DD : BB {public override void Print() => WriteLine("DD");}
public class CC : DD {new public void Print() => WriteLine("CC");}
OutPut - DD
For those who wants to know how CLR is internally calling the new and virtual methods in C#.
When new keyword is used a new-slot of memory is get allocated for CC.Print() and it will not over-ride the base class memory-slot as derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.
When override is used the memory is being override by derived class member, in this case by AA.Print() slot over-ride by BB.Print(); BB.Print() is over-ride by DD.Print().
When we call AA aa = new CC(); compiler will create new slot of memmory for CC.Print() but when it cast as AA, then as per Vtable Map, AA overridable object DD is called.
Reference -
c# - Exact difference between overriding and hiding - Stack Overflow
.NET Framework Internals: How the CLR Creates Runtime Objects | Microsoft Docs
Class ObjName = new Class();
This question is related to the fact that i tumbled over a definition as follows:
public class Thing{
// Stuff
}
public class Animal:Thing{
// Stuff
}
Followed by this declaration Thing x = new Animal();
Related question: How is the first class definition/type related to the second (after the new keyword)?
Link to the related article, by: Matthew Cochran
If I am guessing your meaning correctly...
public class Thing{
}
public class Animal:Thing{
}
This is saying the class Animal derives from class Thing. (Animal : Thing). So if you filled it out a bit more...
public class Thing{
void DoStuff()
{
Console.Write("Doing Stuff");
}
}
public class Animal:Thing{
}
you can do things like this...
var ani = new Animal();
ani.DoStuff();
Because of Inheritance
EDIT: For your benefit in the terms used because they can be difficult enough for beginners (and experts), this would a class definition
public class Thing
{
void DoStuff()
{
Console.Write("Doing Stuff");
}
}
This would be a variable declaration (this is not as common today as it was a few years ago, at least in c# and related languages)
Thing x;
These are variable declaration and assignments - also called "instantiation" as we are creating an instance of the class definition. Using var here is a nice shortcut and you should consider using it more than specifying the type on the left side unless there is a compelling reason to do so.
var x = new Animal();
var y = new Thing();
This Class ObjName = new Class(); creates an object of type Class calling the default constructor and assigns a reference that points to this object to the variable objName.
Furthermore this Thing x = new Animal(); does exactly the same thing (it creates an object and a assigns a reference to this object to a variable). However, here there is a slight difference. An Animal object is a Thing object. In other words, Animal inherits Thing. So a reference to an Animal object can be assigned to a variable, whose type is Thing.
Here is a nice link for inheritance.
Consider this scenario:
public class Base
{
public int i;
}
public class Sub : Base
{
public void foo() { /* do stuff */}
}
And then I want to, given an instance of Base get an cloned instance of Sub (with i=17 in this case) so that I can call foo in the subclass.
Base b = new Base { i=17 };
Sub s = CloneAndUpcast(b);
s.foo();
However, how can I create CloneAndUpcast?
I am thinking that is should be possible to recursively clone all of Base-members and properties using reflection. But quite some work.
Anyone with better, neater ideas?
PS. The scenario where I am thinking about using this is a set of "simple" classes in a tree-like structure (no cyclic graphs or similar here) and all the classes are simple value holders. The plan is to have a stupid layer holding all values and then an similar set of classes (the subclasses) that actually contains some business-logic the value-holders shouldn't be aware of. Generally bad practice yes. I think it works in this case.
You could use AutoMapper to avoid the tedium of writing the copy constructors.
public class MyClass : MyBase
{
public MyClass(MyBase source)
{
Mapper.Map(source, this);
}
}
and you need to run this once when your application starts up
Mapper.CreateMap<MyBase, MyClass>();
You can download AutoMapper from https://github.com/AutoMapper/AutoMapper
Here's one way (out of many possibilities) that you could do something like you're asking. I'm not sure this is very pretty and can be kind of ugly to debug, but I think it works:
class BaseClass
{
public int i { get; set; }
public BaseClass Clone(BaseClass b)
{
BaseClass clone = new BaseClass();
clone.i = b.i;
return clone;
}
}
class SubClass : BaseClass
{
public int j { get; set; }
public void foo() { Console.WriteLine("in SubClass with value of i = {0}", i.ToString()); }
}
class Program
{
static void Main(string[] args)
{
BaseClass b1 = new BaseClass() { i = 17 };
BaseClass b2 = new BaseClass() { i = 35 };
SubClass sub1 = CloneAndUpcast<SubClass>(b1);
SubClass sub2 = CloneAndUpcast<SubClass>(b2);
sub1.foo();
sub2.foo();
}
static T CloneAndUpcast<T>(BaseClass b) where T : BaseClass, new()
{
T clone = new T();
var members = b.GetType().GetMembers(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < members.Length; i++)
{
if (members[i].MemberType== MemberTypes.Property)
{
clone
.GetType()
.GetProperty(members[i].Name)
.SetValue(clone, b.GetType().GetProperty(members[i].Name).GetValue(b, null), null);
}
}
return clone;
}
}
Basically, as you suggested, you use reflection to iterate through the object's properties (I set i and j as public properties) and set the values accordingly in the cloned object. The key is using generics to tell CloneAndUpcast what type you're dealing with. Once you do that, it's pretty straightforward.
Hope this helps. Good luck!
Per the "Gang of Four" : "Favor composition over inheritance" and this is a perfect reason to do so...
If we have a SuperClass that looks like this:
public class SuperClass : Person
The SuperClass can easily decorate the Person class adding properties not found in Person class.
But what happens if the Superclass decorations are only for the GUI? For example a bool value indicating "Selected". We are still able to get all Persons from the DB in a List but we run into trouble trying to create the Superclass and merge the DB results.
foreach( var person in myPersonList){
var sc = new SuperClass();
sc.Selected = false;
sc=person;
}
The compiler complains because Superclass is not a Person to the compiler it's a Superclass. The only way to fill in the properties of the Person subclass is to iterate and set each one... like this.
SuperClass.Name = Person.Name;
SuperClass.Id = Person.ID;
Pretty tedious indeed. But there's a better way.... Don't make Superclass inherit from Person
public class SuperClass{
public Person ThisPerson {get;set;}
public bool Selected {get;set;}
}
This gives us "Containment" The Superclass now contains a Person class.
Now we can do this:
foreach(var person in MyPersonList){
var sc = new Superclass();
sc.Selected = false;
sc.Person = person;
}
The consumer of this class must now qualify the properties of the Superclass/Person like this...
forach(var sc in MySuperClassList){
var selected = sc.Selected;
var name = sc.Person.Name;
}
The beauty of this is that in the future, you can add any other container you want and it will NOT affect any other containers. You can also morph the Superclass to anything it contains. If each of the contained classes become Interfaces, then that's one step futher down the road.
Well, since b isn't a Sub, we can't "clone" it as one.
If Base has an appropriate combination of constructor and public properties to let a constructor in Sub ensure that its base would therefore have the same state as b, then we could use that.
I think I'd by-pass the whole thing though. If all we care about is that s have the same state in its base as b, and it has not other state that we're going to care about (or else we'd have to be passing it through to the CloneAndUpcast method), then do we need s at all?
A static method could take a Base and we could just use static public void foo(Base bc). We could even define it as an extension method static public void foo(this Base bc) and then code the call as b.foo(). The only thing this won't let us do that CloneAndUpcast() lets us do is access protected members.
Clone is a bad practice and your question is the reason for that (subclass cloning).
In general, you should just use copy cotrs instead and have the subclass accept a parent as a parameter.
public Base(){}
public Base(Base pSource){}
public Sub(){}
public Sub(Base pSource, other parameters...){}
public Sub(Sub pSource){}
I'm new at the C# thing.... (.net 3.5)
I want a Dictionary to hold two different types of object, one of the type is generic. while iterating through the list, i will call methods like add and clone.
I have tried it with a base class and subclasses....
namespace ConsoleApplication1 {
class Element{
}
class Child1 : Element {
public Child1 Clone() { return clone; }
}
class Child2<T> : Element {
public Child2<T> Clone() { return clone; }
}
class Program {
static void Main(string[] args) {
Dictionary<string, Element> d = new Dictionary<string, Element>();
d.Add("c1", new Child1());
d.Add("c2s", new Child2<string>());
d.Add("c2i", new Child2<int>());
foreach (KeyValuePair<string, Element> kvp in d) {
Element e = kvp.Value.Clone();
}
}
}
}
Is there a way or solution for my needs?
Thanks!
Anna
You could make Clone either abstract or virtual on the base-type (Element), and override it in the derived types, but you can't change the return type when overriding, so it would have to be Element (nothing more specific). You can redeclare methods (new...), but that gets messy, and you can't override and new a method by the same name/signature in the same type.
But if you're happy for the return type to be Element...
abstract class Element{
public abstract Element Clone();
}
class Child1 : Element {
public override Element Clone() { return /* your code */; }
}
class Child2<T> : Element {
public override Element Clone() { return /* your code */; }
}
Since the type of .Value you get out of your dictionary is Element, you need to make sure Element defines all operations it should have, like your Clone method.
I would:
Make Clone virtual, and add it to Element (or make Element abstract, and Clone abstract instead of virtual)
Override Clone in both Child1 and Child2
This way, the code kvp.Value.Clone() would call the right Clone method depending on the object returned from the dictionary.
Don't create a class hierarchy just for the sake of being able to add different objects to one dictionary though.
If the classes don't have a decent enough hierarchical relationship, you would be better off using an interface like ICloneable, which is already available in the .NET framework.
Then, simply instantiate your Dictionary like:
Dictionary<string, ICloneable> d = new Dictionary<string, ICloneable>();
It's more flexible. Creating a hierarchy for the sake of the commonality of being able to perform Clone(), is not the right solution IMO.
Though I agree with Wim, that implementing ICloneable is probably the better solution, rather than trying to enforce a non-existing class hierachy, please be aware that ICloneable is considered a "bad API" as it does not specify whether it uses shallow- or deepcopy semantics (see for instance http://pro-thoughts.blogspot.com/2009/02/write-deep-clone-forget-about.html or do a google search for "ICloneable C# bad API"