Why does this sometimes mean base? - c#

Given
public class Animal
{
public Animal()
{
Console.WriteLine("Animal constructor called");
}
public virtual void Speak()
{
Console.WriteLine("animal speaks");
}
}
public class Dog: Animal
{
public Dog()
{
Console.WriteLine("Dog constructor called");
this.Speak();
}
public override void Speak()
{
Console.WriteLine("dog speaks");
base.Speak();
}
}
this.Speak() calls Dog.Speak(). Remove Speak() from dog and suddenly this.Speak() calls Animal.Speak(). Why does this behave this way? In other words, why does this mean base or this?
To me, an explicit call to base.Speak() makes more sense. Especially when speak is not virtual, surprisingly Speak() is still called when virtual is removed. I understand IS-A relationships from an OO sense, but I can't wrap my head around this specific problem in C#. This gets especially annoying when people write God class UI's (practically every business does). I'm looking for "Speak()" inside "this" when I should be looking at "base".

Subclases automatically inherit behavior from their base classes. If you don't do anything other than inherit Dog from Animal then this.Speak() and base.Speak() both reference the version of Speak() that was implemented in Animal.
Where special things start happening is if Dog overrides Speak(). This is not possible unless Speak() is virtual. (The virtual keyword doesn't control inheritance, it controlls overriding.)
Only when Dog overrides Speak() does base.Speak() do something special: In that case, calling Speak() (or this.Speak()) will execute Dog's implementation, because it overrides Animal's implementation. This is where base becomes useful: it allows you to get around this behavior by specifying that you want to execute the base class's implementation rather than the override.
A common use of this style is in constructors. For example:
public class Animal
{
private readonly string _name;
public Animal() : this("Animal") { }
protected Animal(string name) { _name = name; }
public void Speak() { Console.WriteLine(_name + " speaks"); }
}
public class NamedAnimal : Animal
{
public NamedAnimal(name) : base(name) { }
}
// usage:
(new Animal()).Speak(); // prints "Animal speaks"
(new NamedAnimal("Dog")).Speak(); // prints "Dog speaks"
In this example, NamedAnimal doesn't have access to the _name field, but it is still able to set it indirectly by calling the base class's constructor. But the base class's signature is the same as one in the base class, so it has to be specified using base.
With non-constructors it's also useful to get at behavior that's not otherwise accessible. For example, if Animal.Speak were virtual then we could use an override to tack behavior onto it rather than simply replacing it:
public class NamedAnimal : Animal
{
public NamedAnimal(name) : base(name) { }
public override Speak()
{
Console.Write("The animal named ");
base.Speak();
}
}
// usage:
(new NamedAnimal("Dog")).Speak(); // Writes "The animal named Dog speaks"

Its not that. Its that if there is a speak method within dog, then it is an override of the base method. If it isn't there, then calling dogInstance.Speak will look for the Speak() method in any of Dog's base classes.

This is one of the very fundamental points of OO. If you don't provide an override, then the parent method is used.
Also, even if you remove virtual, Dog.Speak is called because you're not accessing this polymorphically.

this means this and nothing else.
Just in your first example you have an override for Speak(..) function, so this call that one.
In second case, istead, there is no any override, so it "climbs" on derivation tree and pick the first suitable function. In your case that one is Speak(..) of the Animal.

VB.Net has the MyClass keyword to do just that (as opposed to the My keyword, which is the equivalent of this in C#). Unfortunately, there is no MyClass equivalent keyword in C#.

Related

Override VS Normal Method

Can someone explain the difference between an override and just a normal method, and when an override should be used over the latter?
Every tutorial I have found uses words like "Polymorphism" and "Derived Classes" rather than just explain their application and when they should be used.
I am using C# in particular but an understanding of overrides as a concept would be very helpful.
Thanks for any input on the subject.
Simply put, overrides are for when you want to change the behavior of a method in a derived class. For example, say you had an Animal.Speak() method:
class Animal
{
public virtual void Speak()
{
Console.WriteLine("The animal makes random animal noises.");
}
}
Now, if you had a specific type of animal, you'd want to override that Speak() method to make noises that that type of animal would make:
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("The dog barks.");
}
}
Now if you make a Dog object and tell it to speak, it will bark. Now let's consider if you had a Cat class but didn't override the Speak() method:
class Cat : Animal
{
}
If you had this code:
Animal dog = new Dog();
Animal cat = new Cat();
dog.Speak();
cat.Speak();
You'd see this:
The dog barks.
The animal makes random animal noises.
For example, if there is an predefined class which has a method "ABC" and you want to change its behavior. In that case you have to write the keyword override before the method ABC that you want to change from its default to what you really want to have. Simple words use override when you have to change already existing method. Do not use override when you are creating a new method of any object which already does not exists.
Overriding occurs when you make a method/function/subroutine that has the same name as another function, but has different functionality. One prominent example is the Equals method. This method can be overridden for a custom object to return your concept of equality. For example, if you have a Person object and decide that 2 Persons are equal when they have the same name, you could override the existing Equals method to return whether or not 2 Persons have the same name. Good luck!
What do you mean by "overriden" method?
There are two options:
Override virtual methods in subclasses. Here "method overriding" is a part of polymorphism - one of the concept of object-oriented programming.
For instance, here you have a base class A with some virtual methods:
public class A
{
public void Method1() {}
public virtual void Method2() {}
public virtual void Method3() {}
}
If you create class B, which is derived from A you will have an opportunity to override virtual methods in such case:
public class B : A
{
public override void Method2() {}
public override void Method3() {}
}
In such way you change your base functionality from class A by your new functionality from class B.
So, when you call method from instance of class B , you will get functionality from overriden method in class B:
B instanceB = new B();
instanceB.Method2();
Override method signature. Here you are able to have multiple methods with same name, but with different signatures.
For example, you have such class with 3 methods, which have one name TestMethod, but there are different signatures (different input and output parameter types):
public class TestClass
{
public void TestMethod() {}
public int TestMethod(int value) {}
public string TestMethod(int value) {}
}

Implementing a collection of base classes - should I be needing this much downcasting in derived classes?

I am implementing a collection of classes that exhibit the following pattern:
public class Animal {}
public abstract class AnimalToy
{
public AnimalToy(Animal owner)
{
Owner = owner;
}
public Animal Owner { get; private set; }
/* Various methods related to all toys that use the Owner property */
}
public class Dog: Animal
{
public void Bark() {}
}
public class PlasticBone: AnimalToy
{
public PlasticBone(Dog owner) : base(owner) {}
public void Throw()
{
((Dog)Owner).Bark();
}
}
I have a base class AnimalToy with a property that is a reference to another base class Animal.
I now want to implement a Dog and a PlasticBone toy for that Dog class. PlasticBone is a toy that's only valid for dogs, and in fact the constructor restricts the owner of PlasticBone to be of type Dog.
PlasticBone has a method Throw() that is unique to that class, that uses a method on Dog (Bark()) that is unique to the Dog class. Therefore I need to cast the generic property Owner to Dog before I can access it.
This works just fine, but in the project I am working on this situation comes up again and again and leads to quite ugly code where the methods of derived classes are full of downcasts of base class references. Is this normal? Or is there a better overall design that would be cleaner?
Here's one way to fix it:
public abstract class Animal
{
public abstract void MakeNoise();
}
Let dog implement the MakeNoise and you can just call that in your Toy class:
public void Throw()
{
Owner.MakeNoise();
}
You can make AnimalToy class generic, by this you can avoid casting.
public abstract class AnimalToy<TAnimal> where TAnimal : Animal
{
public AnimalToy(TAnimal owner)
{
Owner = owner;
}
public TAnimal Owner { get; private set; }
}
public class PlasticBone: AnimalToy<Dog>
{
public PlasticBone(Dog owner) : base(owner) {}
public void Throw()
{
Owner.Bark();
}
}
Worth noting that ((Dog)Owner) is not upcast, it is called downcast. upcast is over way around.
I'm going to try to elaborate a little on the discussion in the comments and hopefully provide you with a generalised, polymorphic solution. The general idea is functionally equivalent to what Carra was suggesting but, hopefully, this will help you to apply those concepts to the domain of your actual problem.
To work with your abstraction of your problem; suppose you have your abstract base class defined like so:
public abstract class Animal
{
public abstract void Catch();
}
This is a shift in the semantics of the abstract method; you no longer have an abstract Bark method, you simply have a Catch method, the semantics of which define it as, essentially "react to something being thrown." How the Animal reacts is entirely up to the animal.
So, you'd then define Dog like so:
public class Dog : Animal
{
public override void Catch()
{
Bark();
}
public void Bark()
{
// Bark!
}
}
And change your Throw method to:
public void Throw()
{
Owner.Catch();
}
Now, Bark is specific to Dog, while the generic Catch method is universal to all Animals. The Animal class now specifies that its subclasses must implement a method that reacts to items being thrown to it. The fact that the Dog barks is entirely up to the Dog.
This is the essence of polymorphism - it's not up to the toy to determine what the dog does; it's up to the dog. All the toy needs to know is that the dog can catch it.
More generally, though, I don't like to have two classes that extend independent base classes be logically coupled (parallel hierarchies, as Eric points out) unless one of them explicitly instantiates the other, though it's impossible to offer any real advice on that without seeing your actual solution architecture.

Difference between "protected" and "virtual/override"

I couldn't understand the need or purpose of "protected" when i have "virtual/override" could someone explain me what do i need those 2 things if they are almost the same.
Edit:
Thanks for all the helpers, i now understand that "protected" is only for visibility purposes, while virtual/override is for class behavior.
They are certainly not almost the same.
The protected modifier sets the visibility of a field or method: such a member can only be accessed from the class it is defined in or from a derived class.
The virtual modifier specifies that the method it is applied to can be overridden in a derived class.
These modifiers can be combined: a method can be protected and virtual.
protected means private for current class and derived classes
virtual means it can be used as-is but also be overridden in derived classes
Maybe it is better with some code instead of things you have probably already read, here is a little sample you can play with. Try removing the comments (//) and you can see that the compiler tells you that the properties cannot be accessed
[TestFixture]
public class NewTest
{
[Test]
public void WhatGetsPrinted()
{
A a= new B();
a.Print(); //This uses B's Print method since it overrides A's
// a.ProtectedProperty is not accesible here
}
}
public class A
{
protected string ProtectedProperty { get; set; }
private string PrivateProperty { get; set; }
public virtual void Print()
{
Console.WriteLine("A");
}
}
public class B : A
{
public override void Print() // Since Print is marked virtual in the base class we can override it here
{
//base.PrivateProperty can not be accessed hhere since it is private
base.ProtectedProperty = "ProtectedProperty can be accessed here since it is protected and B:A";
Console.WriteLine("B");
}
}
I can be argued that the Most important distinction about virtual, is that this causes the compiler, when calling a method member polymorphically, which implementation to bind the compiled code to. When you call a member of a class from client code where the actual type of the object is, say derived class foo, but the variable it is being called on is actually typed (declared) as some base class, say bar, Members declared as virtual will bind to the implementation in the actual object type, (or to the most derived base class of the objects type that has an implementation). Members not declared as virtual will bind to the implementation in the type that the variable is declared to be.
A. Virtual. then, if the member is declared as virtual, the implementation in the derived class will be executed even if the variable is declared as a base type.
public class Animal
{ public virtual Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public virtual override Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Bird.Move"
B. Not Virtual. When a member which is not declared as virtual, then the implementation will be chosen based on the declared type of the variable the method is executed on. So if you have a Bird Object, in variable x declared as `Animal', and you call a method that is implemented in both classes, the compiler will bind to the implementation in the Animal class, not in Bird, even though the object is really a Bird.
public class Animal
{ public Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Animal.Move"
I think you need to understand above two things properly, since both has different purpose.
protected is the type or member can only be accessed by code in the same class or struct, or in a derived class.
The virtual keyword is for modify a method, property and allow it to be overridden in a derived class.

C# Virtual & Override Keywords

I thought I had this nailed, and then I go and look at some source at work and am left wondering why there are so many contradictions in what I read from msdn and what I am seeing in source....
My understanding is that the virtual keyword can be used in method declarations to allow any deriving classes to override it.
The override keyword would then need to be used in the derived class when implementing the superclass' virtual method....
For example:
public abstract class A
{
public virtual string GetName();
}
public class B:A
{
//assume there are some defined properties.
public override string GetName()
{
return FirstName;
}
}
I have a few questions:
1) Is it really necessary to define a method as virtual if it has no implementation? Surely it can just be overwritten in the subclass without the use of virtual and override?
2) If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
EDIT:
You're right my code will not compile... I want to know why....I uinderstand your answers but then I saw this:
public abstract class RequestHandler<TRequest, TResponse> : RequestHandler, IRequestHandler<TRequest>, IRequestHandler, IDisposable, ITypedRequestHandler
where TRequest : global::Agatha.Common.Request
where TResponse : global::Agatha.Common.Response, new()
{
protected RequestHandler();
public virtual void AfterHandle(TRequest request);
public virtual void BeforeHandle(TRequest request);
public override Response CreateDefaultResponse();
public TResponse CreateTypedResponse();
public override Response Handle(Request request);
public abstract Response Handle(TRequest request);
}
The above doesnt cause the compiler to complain...
Firstly the above code is invalid. A virtual method still has to have a body with a default implementation. to do what you have done above you would need to use the abstract keyaord instead of virtual.
abstract means that there is no method body provided but that any class deriving from it must implement this method (unless it is abstract too).
I think this pretty much answers your questions....
If it has no implementation then it cannot be virtual, it must be abstract. If it has an implementation that just does nothing then that must be implemented.
The whole point of a virtual class is that it has default behaviour so you can choose whether or not to override it. If it were abstract then you would have to override it (unless you were deriving another abstract class).
Is it really necessary to define a method as virtual if it has no implementation?
You can make the method abstract (it will implicitly make it virtual).
Surely it can just be overwritten in the subclass without the use of virtual and override?
If you just "overwrite" it without explicitly overriding it, it won't be the same method, and calling the method on a variable of the base class won't call the derived method (it won't participate in polymorphism). You would just be "hiding" the method of the base class (the compiler actually warns you about this, if it's really what you want to do you must use the new modifier.)
An example will make it clearer:
class B
{
public virtual void M() { Console.WriteLine("B.M") };
}
class D1 : Base
{
// Hides the base method
public new void M() { Console.WriteLine("D1.M") };
}
class D2 : Base
{
// Overrides the base method
public override void M() { Console.WriteLine("D2.M") };
}
...
D1 d1 = new D1();
d1.M(); // Prints "D1.M"
B b1 = d1;
b1.M(); // Prints "B.M", because D1.M doesn't override B.M
D2 d2 = new D1();
d2.M(); // Prints "D2.M"
B b2 = d2;
b2.M(); // Also prints "D2.M", because D2.M overrides B.M
If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
No, only if it's abstract... a virtual method can have an implementation, and in that case derived classes are not forced to override it.
1) Is it really necessary to define a method as virtual if it has no implementation? Surely it can just be overwritten in the subclass without the use of virtual and override?
As said in other answers, virtual methods need to have implementations. You are confusing it with abstract.
If you were asking whether virtual methods which do have an implementation need to be declared virtual: In C#, yes, it is necessary. In Java, you can override any old method. It was a C# design decision to require overriding to be specifically allowed with the virtual keyword, so that methods cannot be overridden unless intended by the programmer.
If the programmer has not expressed intent by not using virtual, you can still "override" methods, with the new keyword. However, this works a bit differently. Hopefully this code will help illustrate the concept:
class Program
{
static void Main(string[] args)
{
var baseC = new BaseClass();
var extC = new ExtClass();
var lazyC = new LazyClass();
Console.WriteLine(baseC.NewMethod());
Console.WriteLine(baseC.VirtualOverrideMethod());
Console.WriteLine("---");
Console.WriteLine(extC.NewMethod());
Console.WriteLine(extC.VirtualOverrideMethod());
Console.WriteLine("---");
Console.WriteLine(((BaseClass) extC).NewMethod());
Console.WriteLine(((BaseClass) extC).VirtualOverrideMethod()); // Redundant typecast
Console.WriteLine("---");
Console.WriteLine(lazyC.VirtualOverrideMethod());
Console.ReadKey();
}
public class BaseClass
{
public BaseClass()
{
}
public string NewMethod()
{
return "NewMethod of BaseClass";
}
public virtual string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of BaseClass";
}
}
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
class LazyClass : BaseClass
{
}
}
Output:
NewMethod of BaseClass
VirtualOverrideMethod of BaseClass
---
NewMethod of ExtClass
VirtualOverrideMethod of ExtClass
---
NewMethod of BaseClass
VirtualOverrideMethod of ExtClass
---
VirtualOverrideMethod of BaseClass
2) If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
Not at all. virtual is a way of saying, "it's okay if you want to override this method". In fact, I included LazyClass in my code above to show this.
The above doesnt cause the compiler to complain...
I haven't used interfaces much, but that looks like one. In my code, if I change
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
to:
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
I get:
error CS0501: 'OverrideTest.Program.ExtClass.VirtualOverrideMethod()' must declare a body because it is not marked abstract, extern, or partial
From Visual Studio 2010. The same goes for the virtual method of my BaseClass.
The need for virtual is dictated by polymorphism. Think about what happens when you redefine a method in a subclass using new:
class Parent
{
void Foo() { Console.WriteLine("Parent"); }
virtual void Bar { Console.WriteLine("Parent"); }
}
class Child : Parent
{
new void Foo() { Console.WriteLine("Child"); } // another method Foo
override void Bar { Console.WriteLine("Child"); }
}
var child = new Child(); // a Child instance
var parent = (Parent)child; // same object, but statically typed as Parent
c.Bar(); // prints "Child"
p.Bar(); // again, prints "Child" -- expected virtual behavior
c.Foo(); // prints "Child"
p.Foo(); // but this prints "Parent"!!
For this reason, classes that are intended to be derived from (i.e. not sealed) should always mark the methods that can be overridden as virtual -- otherwise there will be confusing runtime behavior like above. There's no difference if the parent implementation actually does anything or not; the point is that it behaves differently.
ok, by declaring the method as virtual (and not wishing to override the method in the subclass), you'd be entering the world of method hiding if you were to introduce a method with the same name into the subclass. You have to define it as thus:
public abstract class A
{
public virtual string GetName()
{
return null;
}
}
public class B : A
{
//assume there are some defined properties.
public new string GetName()
{
return FirstName;
}
}
I'd recommend that you think of the abstract override approach:
public abstract class A
{
public abstract string GetName()
}
// to override
public class B : A
{
//assume there are some defined properties.
public override string GetName()
{
return FirstName;
}
}
this would be quite different. I would strongly recommend that you just override the abstract method in the subclass.
However, here's a quick ref on the subject (old but a good read):
http://www.akadia.com/services/dotnet_polymorphism.html
1) Is it really necessary to define a method as virtual if it has no
implementation? Surely it can just be overwritten in the subclass
without the use of virtual and override?
You can use an abstract methods, that have no body, but they if you derive from that class you must to override that method. All abstact methods have to be overriden in child class.
2) If (1) is incorrect, am I right in thinking that every virtual
method must be overridden in the subclass using it....
No, instead, you can use a virtual keyword to have an implementation inside that, but do not making override in a child class mandatory. Gives you more flexibility, from that point of view.
Usauly they use abstract to create rigid constrains for childs, so every child derived from it must implement specified member of base class.
That's exactly the difference between a virtual and an abstract method:
A virtual method can be overridden by derived classes if the choose to. A virtual method may or may not have a default implementation for inheritors to call into, which is done using the base keyword.
An abstract method must be overridden by derived classes. Its constraints are:
It can only be defined in an abstract class.
It cannot have an implementation, since it's up to the inheritors to define its behavior.

The difference between virtual, override, new and sealed override

I'm pretty confused between some concepts of OOP: virtual, override, new and sealed override. Can anyone explain the differences?
I am pretty clear that if the derived class method is to be used, one can use the override keyword so that the base class method will be overriden by derived class. But I'm not sure about new, and sealed override.
The virtual keyword is used to modify a method, property, indexer or event declaration, and allow it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:
Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.
This is all to do with polymorphism. When a virtual method is called on a reference, the actual type of the object that the reference refers to is used to decide which method implementation to use. When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class. For instance:
public class Base
{
public virtual void SomeMethod()
{
}
}
public class Derived : Base
{
public override void SomeMethod()
{
}
}
...
Base d = new Derived();
d.SomeMethod();
will end up calling Derived.SomeMethod if that overrides Base.SomeMethod.
Now, if you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it. In that case, code like this:
public class Base
{
public virtual void SomeOtherMethod()
{
}
}
public class Derived : Base
{
public new void SomeOtherMethod()
{
}
}
...
Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();
Will first call Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
An overriding property declaration may include the sealed modifier. Use of this modifier prevents a derived class from further overriding the property. The accessors of a sealed property are also sealed.
Any method can be overridable (=virtual) or not. The decision is made by the one who defines the method:
class Person
{
// this one is not overridable (not virtual)
public String GetPersonType()
{
return "person";
}
// this one is overridable (virtual)
public virtual String GetName()
{
return "generic name";
}
}
Now you can override those methods that are overridable:
class Friend : Person
{
public Friend() : this("generic name") { }
public Friend(String name)
{
this._name = name;
}
// override Person.GetName:
public override String GetName()
{
return _name;
}
}
But you can't override the GetPersonType method because it's not virtual.
Let's create two instances of those classes:
Person person = new Person();
Friend friend = new Friend("Onotole");
When non-virtual method GetPersonType is called by Friend instance it's actually Person.GetPersonType that is called:
Console.WriteLine(friend.GetPersonType()); // "person"
When virtual method GetName is called by Friend instance it's Friend.GetName that is called:
Console.WriteLine(friend.GetName()); // "Onotole"
When virtual method GetName is called by Person instance it's Person.GetName that is called:
Console.WriteLine(person.GetName()); // "generic name"
When non-virtual method is called the method body is not looked up - compiler already knows the actual method that needs to be called. Whereas with virtual methods compiler can't be sure which one to call, and it is looked up at runtime in the class hierarchy from down to up starting at the type of instance that the method is called on: for friend.GetName it looks starting at Friend class and finds it right away, for person.GetName class it starts at Person and finds it there.
Sometimes you make a subclass, override a virtual method and you don't want any more overrides down in the hierarchy - you use sealed override for that (saying you are the last one who overrides the method):
class Mike : Friend
{
public sealed override String GetName()
{
return "Mike";
}
}
But sometimes your friend Mike decides to change his gender and thus his name to Alice :) You could either change original code or instead subclass Mike:
class Alice : Mike
{
public new String GetName()
{
return "Alice";
}
}
Here you create a completely different method with the same name (now you have two). Which method and when is called? It depends on how you call it:
Alice alice = new Alice();
Console.WriteLine(alice.GetName()); // the new method is called, printing "Alice"
Console.WriteLine(((Mike)alice).GetName()); // the method hidden by new is called, printing "Mike"
When you call it from Alice's perspective you call Alice.GetName, when from Mike's - you call Mike.GetName. No runtime lookup is made here - as both methods are non-virtual.
You can always create new methods - whether the methods you are hiding are virtual or not.
This applies to properties and events too - they are represented as methods underneath.
By default a method cannot be overridden in a derived class unless it is declared virtual, or abstract. virtual means check for newer implementations before calling and abstract means the same, but it is guaranteed to be overridden in all derived classes. Also, no implementation is needed in the base class because it is going to be re-defined elsewhere.
The exception to the above is the new modifier. A method not declared virtual or abstract can be re-defined with the new modifier in a derived class. When the method is called in the base class the base method executed, and when called in the derived class, the new method is executed. All the new keywords allows you to do is to have two methods with the same name in a class hierarchy.
Finally a sealed modifier breaks the chain of virtual methods and makes them not overridable again. This is not used often, but the option is there. It makes more sense with a chain of 3 classes each deriving from the previous one
A -> B -> C
if A has an virtual or abstract method, that is overridden in B, then it can also prevent C from changing it again by declaring it sealed in B.
sealed is also used in classes, and that is where you will commonly encounter this keyword.
I hope this helps.
public class Base
{
public virtual void SomeMethod()
{
Console.WriteLine("B");
}
}
public class Derived : Base
{
//Same method is written 3 times with different keywords to explain different behaviors.
//This one is Simple method
public void SomeMethod()
{
Console.WriteLine("D");
}
//This method has 'new' keyword
public new void SomeMethod()
{
Console.WriteLine("D");
}
//This method has 'override' keyword
public override void SomeMethod()
{
Console.WriteLine("D");
}
}
Now First thing First
Base b=new Base();
Derived d=new Derived();
b.SomeMethod(); //will always write B
d.SomeMethod(); //will always write D
Now the keywords are all about Polymorphism
Base b = new Derived();
Using virtual in base class and override in Derived will give D(Polymorphism).
Using override without virtual in Base will give error.
Similarly writing a method (no override) with virtual will write 'B' with warning (because no polymorphism is done).
To hide such warning as in above point write new before that simple method in Derived.
new keyword is another story, it simply hides the warning that tells that the property with same name is there in base class.
virtual or new both are same except
new modifier
new and override cannot be used before same method or property.
sealed before any class or method lock it to be used in Derived class and it gives a compile time error.

Categories

Resources