I thought it will call the derived class function because class will give importance to its own function but it is calling base class function please correct me...
class Baseclass
{
public void fun()
{
Console.Write("Base class" + " ");
}
}
class Derived1 : Baseclass
{
new void fun()
{
Console.Write("Derived1 class" + " ");
}
}
class Derived2 : Derived1
{
new void fun()
{
Console.Write("Derived2 class" + " ");
}
}
class test
{
static void Main(string[] args)
{
Derived2 d = new Derived2();
d.fun();
}
}
The base class method is called because only the base class method is accessible.
Why aren't the other methods accessible? Let's look at the method in Derived2:
new void fun()
{
Console.Write("Derived2 class" + " ");
}
What is its access modifier? None, so it defaults to private. This means that you can't access this method from test class!
To make it work, simply add a public modifer:
new public void fun()
{
Console.Write("Derived2 class" + " ");
}
Related
I've read other threads and Eric Lippert's posts on the subject, but haven't seen this exact situation addressed anywhere.
C# optional parameters on overridden methods
Optional parameters and inheritance
I'm trying to implement the following situation:
public class BaseClass
{//ignore rest of class for now
public void DoThings(String str)
{
//dostuff
}
}
public class DerivedClass: BaseClass
{//ignore rest of class for now
new public void DoThings(String str, Int32 someint = 1)
{
//dostuff but including someint, calls base:DoThings in here
}
}
When I do this the compiler gives me the warning in the subject line that I do not need to use the new keyword because the method does not hide the inherited method. However I do not see a way to call the base method from the object instance, so it looks hidden to me.
I want it to actually be hidden. If it is not hidden, there is potential for some other user to some day call the base method directly and break the class (it involves thread safety).
My question is, does the new method actually hide the inherited method (compiler is wrong?) or is the compiler correct and I need to do something else to hide the original method? Or is it just not possible to achieve the desired outcome?
void DoThings(String str) accepts a single parameter
void DoThings(String str, Int32 someint = 1) accepts two parameters
=> the methods are distinct, unrelated methods, which incidentally share the name.
Default parameters are inserted at the call-sites during compilation.
Here is one possible solution:
public class BaseClass
{
public virtual void DoThings(String str)
{
//dostuff
}
}
public class DerivedClass: BaseClass
{
public override void DoThings(String str)
{
DoThings(str, 1); // delegate with default param
}
public void DoThings(String str, Int32 someint)
{
//dostuff
}
}
Note that new makes it possible to call base classes' virtual methods in the first place by having a reference with static type of the base class (e.g. by casting it to the base class):
public class Test
{
public static void Main()
{
var obj = new DerivedClass();
BaseClass baseObj = obj;
obj.DoThings("a");
baseObj.DoThings("b");
((BaseClass)obj).DoThings("c");
}
}
class BaseClass
{
public void DoThings(String str)
{
Console.WriteLine("base: " + str);
}
}
class DerivedClass: BaseClass
{
new public void DoThings(String str, Int32 someint = 1)
{
Console.WriteLine("derived: " + str);
base.DoThings(str);
}
}
Output:
derived: a
base: a
base: b
base: c
If you want callers to never call the overridden method of a base class, mark it virtual and override it (like already shown at the top of this answer):
public class Test
{
public static void Main()
{
var obj = new DerivedClass();
BaseClass baseObj = obj;
obj.DoThings("a");
baseObj.DoThings("b");
((BaseClass)obj).DoThings("c");
}
}
class BaseClass
{
public virtual void DoThings(String str)
{
Console.WriteLine("base: " + str);
}
}
class DerivedClass: BaseClass
{
// "hide" (override) your base method:
public override void DoThings(String str)
{
// delegate to method with default param:
this.DoThings(str);
}
public void DoThings(String str, Int32 someint = 1)
{
Console.WriteLine("derived: " + str);
base.DoThings(str);
}
}
Output:
derived: a
base: a
derived: b
base: b
derived: c
base: c
After discussion in the comments: you do not want to use inheratince here, but rather opt for compisition.
The code could look like the following:
public class Test
{
public static void Main()
{
var obj = new DerivedClass(new BaseClass());
obj.DoThings("a");
// baseObj.DoThings("b"); // not accessible
// ((BaseClass)obj).DoThings("c"); // InvalidCastException!
}
}
class BaseClass
{
public void DoThings(String str)
{
Console.WriteLine("base: " + str);
}
}
class Wrapper
{
private BaseClass original;
public Wrapper(BaseClass original) {
this.original = original;
}
public void DoThings(String str, Int32 someint = 1)
{
Console.WriteLine("wrapped: " + str);
original.DoThings(str);
}
}
Output:
base: a
wrapped: a
the 'new' keyword can't be used where you used it
To hide the member:
public class BaseClass
{ // ignore rest of class for now
public virtual void DoThings(String str)
{
// dostuff
}
}
public class DerivedClass: BaseClass
{ //ignore rest of class for now
public override void DoThings(String str)
{
// dostuff
}
public void DoThings(String str, Int32 someint = 1)
{
// do stuff but including some int, calls base:DoThings in here
}
}
class Baseclass
{
public void fun()
{
Console.Write("Base class" + " ");
}
}
class Derived1 : Baseclass
{
new void fun()
{
Console.Write("Derived1 class" + " ");
}
}
class Derived2 : Derived1
{
new void fun()
{
Console.Write("Derived2 class" + " ");
}
}
class Program
{
public static void Main(string[] args)
{
Derived2 d = new Derived2();
Derived1 e = new Derived1();
d.fun();
e.fun();
}
}
How can I access the result in Derived 1 and Derived 2 and not the base class
Is this overloading or overriding?
new is neither overloading nor overriding. It essentially says 'When I am called, and the object is cast as Derived1, then invoke this'. Note that it's when the object is cast, rather than whenever the object is interacted with.
Your code would appear to work, if you had marked the methods as public. For example:
class Derived1 : Baseclass
{
public new void fun()
{
Console.Write("Derived1 class" + " ");
}
}
class Derived2 : Derived1
{
public new void fun()
{
Console.Write("Derived2 class" + " ");
}
}
Would print
Derived2 class Derived1 class
However, changing your code to the following will reveal the problem with new in this case:
void Main()
{
Derived2 d = new Derived2();
Derived1 e = new Derived1();
ExecuteIt(d);
ExecuteIt(e);
}
void ExecuteIt(Baseclass obj)
{
obj.fun();
}
Prints
Base class Base class
Since the object is cast as Baseclass, and thus the hiding doesn't take effect. To properly implement overriding, you need to do the following:
class Baseclass
{
public virtual void fun()
// ^^^^^^^
{
Console.Write("Base class" + " ");
}
}
class Derived1 : Baseclass
{
public override void fun()
// ^^^^^^ ^^^^^^^^
{
Console.Write("Derived1 class" + " ");
}
}
class Derived2 : Derived1
{
public override void fun()
// ^^^^^^ ^^^^^^^^
{
Console.Write("Derived2 class" + " ");
}
}
Which, when run with:
void Main()
{
Derived2 d = new Derived2();
Derived1 e = new Derived1();
ExecuteIt(d);
ExecuteIt(e);
}
void ExecuteIt(Baseclass obj)
{
obj.fun();
}
Properly outputs
Derived2 class Derived1 class
Why does this code produce the output "Base class" and not "Derived2 class"?
namespace TestConsoleApplication
{
class Baseclass
{
public void fun()
{
Console.Write("Base class" + " ");
}
}
class Derived1: Baseclass
{
new void fun()
{
Console.Write("Derived1 class" + " ");
}
}
class Derived2: Derived1
{
new void fun()
{
Console.Write("Derived2 class" + " ");
}
}
class Program
{
public static void Main(string[ ] args)
{
Derived2 d = new Derived2();
d.fun();
}
}
}
Because you didn't declare the method as public.
You've told it to hide the original definition, rather than override it - which it will do, but the default access modifier is private, not public.
For example, when calling the method from within Derived2:
class Derived2 : Derived1
{
new void fun()
{
Console.Write("Derived2 class" + " ");
}
public void Test()
{
fun();
}
}
class Program
{
public static void Main(string[] args)
{
Derived2 d = new Derived2();
d.Test(); //Prints 'Derived2 class'
}
}
Setting it to public will indeed print Derived2 in your original example
public new void fun()
{
Console.Write("Derived2 class" + " ");
}
I just have one basic question :
public class virtualTest
{
public virtual void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public override void vTest()
{
Console.WriteLine("Derived Class");
}
}
Here i have used function overriding with function vTest()
But if i :
public class virtualTest
{
public void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public void vTest()
{
Console.WriteLine("Derived Class");
}
}
removes virtual and override keywords from respective places , then also code works.
How can this be possible?
Or then what is the use of override and virtual (entire function overriding) if code works fine without virtual and override???
EDIt:
My Method through which i am calling above classes
static void Main(string[] args)
{
derivedVirtualTest objderivedVirtualTest = new derivedVirtualTest();
objderivedVirtualTest.vTest();
virtualTest objvirtualTest = new virtualTest();
objvirtualTest.vTest();
Console.ReadLine();
}
As qwr explained, the main difference in terms of OOP is polymorphism. It means that if you access the class which overrides the base member through a base type reference, the call you perform to the overriddable member is redirected to the override.
In case of a class which shadows/hides the base member, the call is not redirected, and the base class' method is being executed.
So, given:
class Base
{
public virtual void OverrideMe()
{
Console.WriteLine("I'm the base");
}
}
class Derived : Base
{
public override void OverrideMe()
{
Console.WriteLine("I'm derived");
}
}
class Shadowing : Base
{
public void OverrideMe()
{
Console.WriteLine("I'm shadowing");
}
}
And using them this way:
var instances = new Base[] {new Base(), new Derived(), new Shadowing()};
foreach (var instance in instances)
{
instance.OverrideMe();
}
Will produce:
I'm the base
I'm derived
I'm the base
Additional difference is that in case of overriding you can evolve your base class, like changing the signature of the base member or removing it completely, without changing the hiding one. Which in some cases may suit needs exactly and in some - not so much.
In case of overriding you must change the signature of overriding member as well, otherwise your code will fail to compile.
In the second example, maybe you test your code like this:
derivedVirtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Derived Class"
Try this, and you'll see that the function has't been overridden yet:
virtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Base Class"
//This will result "Dervived class" in the first one
It will be needed when your sealed method overriding a method
public class Animal{
public virtual void eat() { Console.WriteLine("eating..."); }
public virtual void run() { Console.WriteLine("running..."); }
}
public class Dog: Animal
{
public override void eat() { Console.WriteLine("eating bread..."); }
public sealed override void run() { //If you skipped override here it will throws an error
Console.WriteLine("running very fast...");
}
}
public class TestSealed
{
public static void Main()
{
BabyDog d = new BabyDog();
d.eat();
d.run();
}
}
I have a abstract base class.
I have 2 derived classes from this base class.
Is there anyway that one of my classes can ignore the string parameter in the abstract overide usage?
Or do I have to just send in a blank one and ignore it? (making readability drop slightly)
Can I have one function that has some sort of optional parameter so that both of the following derived classes would compile?
PS - The following code is riddled with in-compilable code for the example of what I would like to do
PS PS - Yes i have compiled the following code already - see above comment for outcome
public abstract class MyBaseClass
{ //optional string?
public abstract void FunctionCall(int i, string s = "");
}
public class MyDerivedClass : MyBaseClass
{
public override void FunctionCall(int i)
{
MessageBox.Show(i.ToString());
}
}
public class YourDerivedClass : MyBaseClass
{
public override void FunctionCall(int i, string s)
{
MessageBox.Show(s + " " + i.ToString());
}
}
If you don't absolutely need FunctionCall to be abstract, you can declare two versions of it:
public abstract class MyBaseClass
{
public virtual void FunctionCall(int i)
{
this.FunctionCall(i, "");
}
public virtual void FunctionCall(int i, string s)
{
}
}
public class MyDerivedClass : MyBaseClass
{
public override void FunctionCall(int i)
{
MessageBox.Show(i.ToString());
}
}
public class YourDerivedClass : MyBaseClass
{
public override void FunctionCall(int i, string s)
{
MessageBox.Show(s + " " + i.ToString());
}
}
Otherwise, if it must be abstract to ensure it is implemented, you could still add two versions, it just makes the inheritors more verbose:
public abstract class MyBaseClass
{
public abstract void FunctionCall(int i);
public abstract void FunctionCall(int i, string s);
}
public class MyDerivedClass : MyBaseClass
{
public override void FunctionCall(int i, string s)
{
throw new NotImplementedException();
}
public override void FunctionCall(int i)
{
MessageBox.Show(i.ToString());
}
}
public class YourDerivedClass : MyBaseClass
{
public override void FunctionCall(int i)
{
throw new NotImplementedException();
}
public override void FunctionCall(int i, string s)
{
MessageBox.Show(s + " " + i.ToString());
}
}
It will throw a compile error: "Abstract Inherited member 'MyBaseClass.FunctionCall(int, string)' is not implemented".
So no, the short answer is you can't do this.
Instead, you would have to do method overloading and implement BOTH abstract methods.
public abstract class MyBaseClass
{
public abstract void FunctionCall(int i);
public abstract void FunctionCall(int i, string s = "");
}
public class MyDerivedClass : MyBaseClass
{
public override void FunctionCall(int i, string s = "") { }
public override void FunctionCall(int i)
{
MessageBox.Show(i.ToString());
}
}
public class YourDerivedClass : MyBaseClass
{
public override void FunctionCall(int i, string s)
{
MessageBox.Show(s + " " + i.ToString());
}
public override void FunctionCall(int i) {}
}
However this seems quite messy. Perhaps the best option is to always use the optional parameter and simply not pass in a value if it is not needed or handle it as you already seem to be doing.
public class MyDerivedClass : MyBaseClass
{
public override void FunctionCall(int i, string s = "")
{
if (!string.IsNullOrEmpty(s))
MessageBox.Show(i.ToString());
else
// handle other path here
}
}
One possible way is to use extension methods to add missing overrides (which also works with interfaces)
static class MyBaseClassExtensions
{
public void FunctionCall(MyBaseClass this item, int i)
{
item.FunctionCall(i, null);
}
}