C# Inheritance concept advise - c#

I have a small query related to OOP concept in C#.
I have an interface
interface intf
{
string Hello();
}
A base class
public class BaseClass
{
public string Hello()
{
return "Hello of base class called";
}
}
A child class that is derived from BaseClass and implements the interface intf as well
public class ChildClass : BaseClass, intf
{
string Hello()
{
return "Hello of child class called";
}
}
Now my question is that when I create an object of ChildClass then when I call the hello method it always calls the hello method of BaseClass. Firstly, why does it call the Hello of the BaseClass? Secondly, how can I call the Hello of the ChildClass?
private void Form1_Load(object sender, EventArgs e)
{
ChildClass obj = new ChildClass();
MessageBox.Show(obj.Hello());
}

First of all, you did not provide an access modifier for Hello in ChildClass. This makes it private by default. To access that method from outside of the class, mark it public (or internal if using it from the same namespace). As it stands now, the only publicly visible Hello method is the base class method.
Secondly, once you have resolved the access issue, Hello will hide the method in the base. If this is intentional, it is advisable to use the new keyword with the method
public new string Hello()
If your intention was not to hide the method but instead to override it, mark the method as virtual in the base class and use the override keyword in the child.
public class ChildClass : BaseClass, intf
{
public override string Hello()
{
return "Hello of child class called";
}
}
public class BaseClass
{
public virtual string Hello()
{
return "Hello of base class called";
}
}
This will allow you to always call the child method unless you explicitly call the base method from within the child.
Calls like this from the outside world
((BaseClass)child).Hello();
(child as BaseClass).Hello();
BaseClass baseClass = new ChildClass();
baseClass.Hello();
Will result in the child method being used.
Calls like this from within the child class
base.Hello();
Will result in the base class method being used.

Why call the Hello of base
Your child class implements the interface, so it is considered to contain a public Hello method. But in your child class, Hello is not public. The Hello method in base class is public and is considered to be the implementation of the interface.
How to call Hello of child class
Make the Hello in child class public. Then it will be considered to an implementation of the interface.

Declare the method in the base class virtual and then override it in the child class. That way, the virtual call will resolve to the child class instead of the parent class.
Update:
To answer the question about why it still the base method even after you put new in the method declaration:
By default, class members are private. Therefore, since you did not mark the method as public, the method is private. Therefore the programs is force to called the base method as it's the only one that's accessible.

The way you've currently declared your methods, the method Hello() in the ChildClass in inaccessible, and hence the public method in the BaseClass is called. What you really want is what Esteban said though, declare the base method public virtual, the derived method public override, otherwise your method is just shadowing the base class method.

As other said, make the Hello method in the Child class public override.
Also, IMHO, you should implement the interface in the base class, not the child class. But that has nothing to do with the fact your method doesn't get called.

Related

c# runtime polymorphism with abstract base class

I am trying to clean up an existing code base, and am having trouble with using a generic reference name to the different derived classes of an abstract class.
For instance:
public abstract class Base<T> : Utilities.CommonRequiredObject
{
protected List<T> RawContents = new List<T>();
.
.
public abstract void LoadContents(List<T> Contents); // Each Class needs to load and process differently
protected List<T> Contents;
public virtual void DoSomething() // Default here for common use. Defined in Each class for its specifics (if needed)
{
...
}
public abstract List<T> FunctionToGetContents();
}
public class FOO : Base<string>
{
public override void DoSomething() ...
public override List<string> FunctionToGetContents() ...
}
public class BAR : Base<byte>
{
public override void DoSomething() ...
public override List<byte> FunctionToGetContents() ...
}
Main Logic to try to use common variable. I want to create a new class to use, but want to use it then in a runtime polymorphic way. As the classes have the common functionality, and have overrides where needed, I want to be able to create an instance, and then use it:
IE: Base<T> ObjectToUse;
This way, I can simply refer to the ObjectToUse in the following code and call common methods. As I inherited some common routines from another base class, I am not sure if I can use an interface or not.
if(variable)
{
FOO ObjectToUse = new FOO();
}
else
{
BAR ObjectToUse = new BAR();
}
ObjectToUse.LoadContents(ObjectToUse.FunctionToGetContents());
ObjectToUse.DoSomething();
...
Edit:
Based on the comments I received quickly (thanks again everyone) would it be better than to remove the Generic (Base<T>) and have the classes all of type Base(), then I could define the ObjectToUse simply as Base ObjectToUse; I believe.
This cannot be done.
By utilizing a reference that requires a generic type parameter, you must give it one. You could utilize dynamic here so that the type is run-time evaluated, but thats the best you will get.
Even utilizing something like a template method pattern, you would need to specify the generic type argument. If you just want the DoSomething method for this, it would need to be promoted to a higher base class (or an interface) so you could hold a reference to that type, and call that (non-generic) function.
To your comment, the solution I would take is this; refactor the common code into a template method pattern within the base class. Then have the "triggering" function be a non-generic inherited member from a non-generic base class (or interface). Now, you can hold a reference to that type, and invoke the template method to cause the other calls to occur.
public void DoAwesomeStuff() //inherited from non-generic parent or interface
{
LoadContents(FunctionToGetContents());
DoSomething();
}
Then:
IDoesAwesomeStuff ObjectToUse = new FOO();
ObjectToUse.DoAwesomeStuff();

How to forbid a class method/property to be overridden in C#?

I believe I want a some methods and properties of a class to be unoverridable and use the base's implementation in all derived classes. How to achieve this? sealed keyword doesn't seem to work and says "method can not be sealed because it is not an override".
Members are sealed by default in C# - unless they're marked as virtual, they can't be overridden in derived classes anyway.
They can be shadowed in derived classes, admittedly:
public new void SomeMethod()
{
}
... but that's not the same as overriding. There's no way you can prevent this, but if a caller uses a compile-time type of the base class, they won't end up calling this accidentally anyway.
If you could give us more details of exactly what you're trying to prevent (from both the caller's POV and the code being called) we may be able to help more.
A method that is not already an override will not be overridable unless you mark it as virtual. So it sounds like in your case no action is needed.
class A
{
public void B() {} // can't override
public virtual C() {} // can override
public virtual D() {} // can override
}
The sealed modifier only applies when a method is already an override of a member in the base class. This allows you to prevent overrides in subclasses of that class.
class A1 : A
{
public void B() {} // shadows A.B. Not a virtual method!
public override C() {} // overrides A.C, subclasses can override
public override sealed D() {} // overrides A.D, subclasses cannot override
// (but can shadow)
}
This isn't possible. A derived class can always use the new keyword to hide (not override) its parents methods. The sealed keyword simply stops the derived class from overriding a virtual method, but it could still use new to hide the base method.
The "sealed" keyword can only be used, if you override a method that is virtual, but don't want a class deriving from your implementation to override it again. Declaring the method not virtual is all you need.
As other pointed out that there is in fact a "new" keyword, which allows hiding the method. But as long as you use a reference of your base class, your base method is always called:
class BaseClass
{
public void Foo() { Console.WriteLine("Foo"); }
}
class Derived : BaseClass
{
public new void Foo() { Console.WriteLine("Bar"); }
}
public static void Main()
{
Derived derived = new Derived();
derived.Foo(); // Prints "Bar"
BaseClass baseClass = derived;
baseClass.Foo(); // Prints "Foo"
}
Since providing a base-class only makes sense, as long as you use a "BaseClass"-pointer everywhere, your method cannot be hidden.
This is precisely what sealed keyword is for.
http://msdn.microsoft.com/en-us/library/ms173150.aspx
A class member, method, field,
property, or event, on a derived class
that is overriding a virtual member of
the base class can declare that member
as sealed. This negates the virtual
aspect of the member for any further
derived class. This is accomplished by
putting the sealed keyword before the
override keyword in the class member
declaration.
If you've overridden a method from base class than use sealed.
If you've declared a method in the class and don't want it to be overridden in any derived classes than don't mark it as virtual. Only virtual members can be overridden.

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.

Using a subclass method on a base class object

Let's say I have declared the following classes:
class BaseClass{
/* properties, constructors, getters, setters etc. */
public static BaseClass Create(string url){
/*will return, depending on url, a BaseClass or a SubClass object*/
}
public void Method(){
/* some code here */
}
}
class SubClass: BaseClass{
/* other properties, constructors, getters, setters etc. */
new public void Method(){
/* some other code here */
}
}
Now in my Main method I would like to do something along the lines of:
BaseClass baseClass = BaseClass.Create(url);
if(baseClass.GetType()==typeof(SubClass)){
baseClass.Method();
}
The idea here, of course, is to use Method as it is implemented in SubClass. It may be a silly question but how do I do that? I can't cast a base class into a subclass so I'm not sure...
EDIT
Clarified my question. Even though baseClass was declared as a BaseClass instance, baseClass is SubClass will return trueif url is such that Create returns a SubClass instance.
It looks like you might be looking for polymorphism, but I can't be sure from the description. What is the concrete use case for what you're trying to do?
class BaseClass{
public virtual void Method(){
Console.WriteLine("BaseClass");
}
}
class SubClass : BaseClass{
/* other properties, constructors, getters, setters etc. */
public override void Method(){
Console.WriteLine("SubClass");
}
}
static class Test
{
public void go() {
BaseClass instance = new SubClass();
instance.Method(); // prints "SubClass"
}
}
If it doesn't make sense for the base class to have an implementation, then declare the class and the method as abstract -- this forces the derived classes to override the method, guaranteeing that any instantiated class instance will have a valid implementation.
Well I don't know why you would want to do that?
There is no way that the type of an instance of BaseClass will be equal to the type of SubClass.
That could only be possible if you created a instance of SubClass and then cast it to BaseClass. But in that case you could just cast it back to SubClass to call Method()
If you instansiate the baseClass as BaseClass you will not be able to call the method as SubClass, but if you write
BaseClass baseClass = new SubClass();
if (baseClass is SubClass)
{
SubClass subClass = baseClass as SubClass;
subClass.Method();
}
it will call the method as the SubClass is defined.
First of all: you have to initialise your variable as an instance of SubClass, otherwise there is no way.
Then declare the method in the base class virtual,
or
cast the object to SubClass, and call the Method that way.
So either
class BaseClass{
/* properties, constructors, getters, setters etc. */
virtual public void Method(){
/* some code here */
}
}
or
((SubClass)baseClass).Method();

Run same method in base and derived class

What do I need to do to first run the method in the base class then run the same method in the derived class? Is this a good idea?
I want run common actions in base class and extend it in the derived class in the same method. Is this how it is usually done?
public abstract class MyBase
{
void DoStuff()
{
//some common implementation
}
}
public class MyDerived : MyBase
{
void DoStuff()
{
// DoStuff in the base first
// Then DoStuff in here
}
}
are you talking about something like that?
class base
{
protected virtual void method()
{
// do some stuff in base class, something common for all derived classes
}
}
class derived : base
{
public override void method()
{
base.method(); // call method from base
// do here some more work related to this instance of object
}
}
that's not a bad idea, I do use it a lot when I have some common functionality for all derived classes.
If you want to guarantee that the base class logic is run (and not rely on the derived class being polite), you can do this:
public void Method()
{
//Stuff that should always happen in base class
OnMethod();
}
protected virtual void OnMethod()
{
//Default base class implementation that derived class can either override or extend
}
Use base.TheMethod() to run a method in the base class from a derived class.
If you want to run a method of a derived class from a base class, then you have to cast the base class to the derived class. This means that your class needs to be aware of who is deriving it, which breaks encapsulation and should be avoided.

Categories

Resources