1) Why does the following codes differ.
C#:
class Base
{
public void foo()
{
System.Console.WriteLine("base");
}
}
class Derived : Base
{
static void Main(string[] args)
{
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
public new void foo()
{
System.Console.WriteLine("derived");
}
}
Java:
class Base {
public void foo() {
System.out.println("Base");
}
}
class Derived extends Base {
public void foo() {
System.out.println("Derived");
}
public static void main(String []s) {
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
}
2) When migrating from one language to another what are the things we need to ensure for smooth transition.
The reason is that in Java, methods are virtual by default. In C#, virtual methods must explicitly be marked as such.
The following C# code is equivalent to the Java code - note the use of virtual in the base class and override in the derived class:
class Base
{
public virtual void foo()
{
System.Console.WriteLine("base");
}
}
class Derived
: Base
{
static void Main(string[] args)
{
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
public override void foo()
{
System.Console.WriteLine("derived");
}
}
The C# code you posted hides the method foo in the class Derived. This is something you normally don't want to do, because it will cause problems with inheritance.
Using the classes you posted, the following code will output different things, although it's always the same instance:
Base b = new Derived();
b.foo(); // writes "base"
((Derived)b).foo(); // writes "derived"
The fixed code I provided above will output "derived" in both cases.
The C# code will compile with warnings, since you are hiding methods there.
In Java, class-methods are always virtual, whereas in C# they're not, and you have to mark them explicitly as 'virtual'.
In C#, you'll have to do this:
public class Base
{
public virtual void Foo()
{
Console.WriteLine ("Base");
}
}
public class Derived : Base
{
public override void Foo()
{
Console.WriteLine ("Derived.");
}
}
Related
I would like to ask you for an explanation of this example:
public class A : B
{
public override void Method()
{
Console.WriteLine("A");
}
}
public class B
{
public virtual void Method()
{
Console.WriteLine("B");
}
}
Equation:
void Main()
{
B b = (B)new A();
b.Method(); // result A
}
Why upcasting did not work in this case?
How microsoft docs say:
If you want your derived class to have a member with the same name as a member in a base class, you can use the new keyword to hide the base class member. The new keyword is put before the return type of a class member that is being replaced. The following code provides an example:
Why we need to use new if hiding is intended, when we can directly create ClassA object and call printA method of classA
I'm confused why do we need this new keyword here when we have the option to directly create class object and call the required method:
class Program
{
static void Main()
{
classA clsA = new ClassB();
clsA.printA();
}
}
public class classA
{
public classA()
{
Console.WriteLine("ClassA constructor");
}
public void printA()
{
Console.WriteLine("ClassA-PrintA Method");
}
}
class ClassB : classA
{
public ClassB()
{
Console.WriteLine("ClassB constructor");
}
public void printB()
{
Console.WriteLine("ClassB-PrintB Method");
}
public new void printA()
{
Console.WriteLine("Class B extending ClassA.PrintA Method");
}
}
Difference between below code implementation when anyway we have to call PrintA method of class A in both the cases...
1) Using new keyword with the method in the both the base and derived class ------------------------------------------------------------------
class Program
{
static void Main()
{
classA clsA = new classA();
clsA.printA();
}
}
public class classA
{
public classA()
{
Console.WriteLine("ClassA constructor");
}
public virtual void printA()
{
Console.WriteLine("ClassA-PrintA Method");
}
}
class ClassB : classA
{
public ClassB()
{
Console.WriteLine("ClassB constructor");
}
public new void printA()
{
Console.WriteLine("Class B extending ClassA.PrintA Method");
}
}
2) Without using new keyword and no printA implementation in ClassB ----------------------------------------------------------------
class Program
{
static void Main()
{
classA clsA = new classA();
clsA.printA();
}
}
public class classA
{
public classA()
{
Console.WriteLine("ClassA constructor");
}
public void printA()
{
Console.WriteLine("ClassA-PrintA Method");
}
}
class ClassB : classA
{
public ClassB()
{
Console.WriteLine("ClassB constructor");
}
}
what is the real time need of new keyword.
new keyword requirement is there to draw your attention to the fact that the method in the parent class will be hidden and not overridden.
Hiding isn't really one of the best practices when it comes to OOP, virtual methods are more common. IMHO the developers of the c# compiler decided that if the class declares a member with the signature that is equivalent to that of any other member's down the inheritance chain, and there is no override prefix - it might be a mistake, so the compiler asks whether hiding is intentional.
You don't need the new keyword unless you wish to hide the base class member, and then you do need the keyword as that is how the C# language is designed. The code would not compile without it.
Typically, you declare a function in your base class and not redefine in the derived class, or you define the base class function virtual (can be overridden) or abstract (must be overriden).
So: ClassB could be written without any printA function at all as it is already declared in the base class and is not abstract:
class ClassB : classA
{
public ClassB()
{
Console.WriteLine("ClassB constructor");
}
public void printB()
{
Console.WriteLine("ClassB-PrintB Method");
}
}
The above will compile and printA will be callable from ClassB but will use the implementation in ClassA.
Furthermore, consider this:
classA clsA = new ClassB();
clsA.printA();
new ClassB().printA();
Output:
ClassA constructor
ClassB constructor
ClassA-PrintA Method
ClassA constructor
ClassB constructor
Class B extending ClassA.PrintA Method
Do you see that when you instantiate a ClassB but store it in a ClassA variable you get the output from the ClassA version of the function, whereas new ClassB.printA() returns the output from the ClassB version?
It sounds to me like you want to have ClassB.PrintA() output different from ClassA.PrintA(), but you want to be able to call ClassA.PrintA() from an instance of ClassB too. You can do it by declaring ClassA.PrintA() as virtual:
public class classA
{
public virtual void printA()
{
Console.WriteLine("ClassA-PrintA Method");
}
}
and overriding the function in ClassB:
class ClassB : classA
{
public void printB()
{
Console.WriteLine("ClassB-PrintB Method");
}
public override void printA()
{
Console.WriteLine("Classb-PrintA Method");
// Let's also call the ClassA version, just to show you how it works
base.printA();
}
}
And just to prove the point, we've called the ClassA version too using the base keyword.
void Main()
{
new ClassB().printA();
}
Console output:
Classb-PrintA Method
ClassA-PrintA Method
This question already has answers here:
new keyword in method signature
(9 answers)
Closed 9 years ago.
I have seen methods that are declared like this:
public void new SortItems()
What does this actually do? I know that the new keyword is used to invoke constructors, but I have also seen it on method definitions like the example above.
When use this way, it's a modifier. It's used to hide an inherited member rather than to override it. This is useful if the base method is sealed. Here's a quick example to demonstrate the difference between overriding and hiding inherited members:
public class Foo
{
public virtual void OverriddenMethod() { Console.WriteLine("foo"); }
public void HiddenMethod() { Console.WriteLine("foo"); }
}
public class Bar : Foo
{
public override void OverriddenMethod() { Console.WriteLine("bar"); }
public new void HiddenMethod() { Console.WriteLine("bar"); }
}
void Main()
{
Bar bar = new Bar();
Foo foo = bar;
bar.OverriddenMethod(); // "bar"
bar.HiddenMethod(); // "bar"
foo.OverriddenMethod(); // "bar"
foo.HiddenMethod(); // "foo"
}
Further Reading
new Modifier (C# Reference)
It should be like this:
public new void SortItems(){
//...
}
This new keyword is used to shadow the base member (method, property, ...) which has the same name (for property, event...) and same signature (for method), in this case it is the method SortItems. It's different from the new in creating new instance. No matter using new to shadow the conflicted member in base class or not, to access the base member you have to use the keyword base to access it in the derived class.
When used in a method signature, it means that the implementation details are different for the class defining them. The problem with this approach is that it is not used polymorphically so:
class Thing
{
void DoSomething()
{
Console.WriteLine("Thing");
}
}
class Other : Thing
{
new void DoSomething()
{
Console.WriteLine("Other");
}
}
var thing = new Thing();
thing.DoSomething(); \\ prints Thing
var other = new Other();
other.DoSomething(); \\ prints Other
((Thing)other).DoSomething(); \\ prints Thing
It is the opposite of override. Say you have:
public class A
{
public virtual void f() { Console.WriteLine( "A" ); }
}
public class B : A
{
public override void f() { Console.WriteLine( "B" ); }
}
public class C : A
{
public new void f() { Console.WriteLine( "C" ); }
}
And then in main:
A b = new B();
A c = new C();
b.f();
c.f();
(c as C).f();
This would print:
B
A
C
It will only call the new method when the type is that of the defining class.
Expecting "Hello from the derived." but getting "Hello from the base.".
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public virtual new void Method()
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
So why isn't the derived class's method called. And more importantly, how can I get the derived classes method to get called without casting x to the Derived type?
In my actual application, IBase has several other related methods and Derived only replaces two of the methods in IBase.
When you use the new modifier you are specifically saying that the method is not part of the virtual dispatch chain for that hierarchy, so calling the method by the same name in the base class will not result in redirection to the child class. If you mark the method with override instead of new then you will see the virtual dispatch that you are expecting to see.
You will also need to remove virtual from the derived class's method as you cannot mark an override method as virtual (it already is).
If you really don't want to override the method then it may be more appropriate, in your situation, to not use inheritance at all. You may simply want to use interfaces exclusively:
public interface IFoo
{
void Foo();
}
public class A : IFoo
{
public void Foo()
{
Console.WriteLine("I am A, hear me roar!");
}
}
public class B : IFoo
{
public void Foo()
{
Console.WriteLine("I am B, hear me roar!");
}
}
private static void Main(string[] args)
{
IFoo foo = new A();
foo.Foo();
foo = new B();
foo.Foo();
Console.WriteLine();
Console.WriteLine("Press any key to exit . . .");
Console.ReadKey(true);
}
This is basic polymorphism at work.
For the behavior you're looking for, you would need to set your derived method to override the inherited method:
public class Derived : Base
{
public override void Method()
{
Console.WriteLine("Hello from the derived.");
}
}
Use the override keyword instead of virtual new in your child class.
Therefore, your code should look like:
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public override void Method() // The magic happens here!
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
As described here, the new keyword is used to hide the parent method, which is not what you're looking for.
new keyword creates a new method and says that the base method is hidden. But it is only for consumers of your derived class, since the base class code does not know anything about it.
override keyword overrides the base class implementation with a new one.
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
// the next line was changed.
public override void Method()
{
Console.WriteLine("Hello from the derived.");
// note that if you want to call the original implementation, you do it like this:
base.Method();
}
}
static void Main(string[] args)
{
Base x = new Derived();
x.Method();
}
}
The new'd Method in Derived only exists in a Derived instance, where it effectively hides the base implementation.
But IBase type only knows the Base's implementation, so it calls that.
To answer your question, to call the derived's implementation you'd do:
Derived d = new Derived();
d.Method();
((IBase)d).Method();
//Prints:
//Hello from the derived.
//Hello from the base.
Given the following C# class definitions and code:
public class BaseClass
{
public virtual void MyMethod()
{
...do something...
}
}
public class A : BaseClass
{
public override void MyMethod()
{
...do something different...
}
}
public class B : BaseClass
{
public override void MyMethod()
{
...do something different...
}
}
public class AnotherObject
{
public AnotherObject(BaseClass someObject)
{
someObject.MyMethod(); //This calls the BaseClass method, unfortunately.
}
}
I would like to call the MyMethod() that is actually found in A or B, assuming the object passed in is actually an instance of A or B, not that which is found in BaseClass. Short of doing something like this:
public class AnotherObject
{
public AnotherObject(BaseClass someObject)
{
A temp1 = someObject as A;
if (A != null)
{
A.MyMethod();
}
B temp2 = someObject as B;
if (B != null)
{
B.MyMethod();
}
}
}
How can I do it?
Which method is called is determined via polymorphism on the type that is passed into the AnotherObject constructor:
AnotherObject a = new AnotherObject(new A()); // invokes A.MyMethod()
AnotherObject b = new AnotherObject(new B()); // invokes B.MyMethod()
AnotherObject c = new AnotherObject(new BaseClass()); //invokes BaseClass.MyMethod()
Sorry, but you are completely mistaken; this would go against the entire point of virtual methods. If someObject is an A then A.MyMethod will be invoked. If someObject is a B then B.MyMethod will be invoked. If someObject is a BaseClass and not an instance of a type derived from BaseClass then BaseClass.MyMethod will be invoked.
Let's use everyone's favorite example:
class Animal {
public virtual void Speak() {
Console.WriteLine("i can haz cheezburger?");
}
}
class Feeder {
public void Feed(Animal animal) { animal.Speak(); }
}
class Cat : Animal {
public override void Speak() { Console.WriteLine("Meow!"); }
}
class Dog : Animal {
public override void Speak() { Console.WriteLine("Woof!"); }
}
Then:
Animal a = new Animal();
Animal c = new Cat();
Animal d = new Dog();
Feeder f = new Feeder();
f.Feed(a);
f.Feed(c);
f.Feed(d);
This will print:
i can haz cheezburger?
Meow!
Woof!
Again, this is the entire point of virtual methods.
Further, we can go to the specification. From 10.6.3 (Virtual methods)
In a virtual method invocation, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke.
(Bolding and italics in original.)
In precise terms, when a method named N is invoked with an argument list A on an instance with a compile-time type C and a run-time type R (where R is either C or a class derived from C), the invocation is processed as follows:
• First, overload resolution is applied to C, N, and A, to select a specific method M from the set of methods declared in and inherited by C. This is described in §7.5.5.1.
• Then, if M is a non-virtual method, M is invoked.
• Otherwise, M is a virtual method, and the most derived implementation of M with respect to R is invoked.
(Bolding not in original.)
Then, we need the definition of "most derived implementation of M." This is a nice recursive definition:
The most derived implementation of a virtual method M with respect to a class R is determined as follows:
• If R contains the introducing virtual declaration of M, then this is the most derived implementation of M.
• Otherwise, if R contains an override of M, then this is the most derived implementation of M.
• Otherwise, the most derived implementation of M with respect to R is the same as the most derived implementation of M with respect to the direct base class of R.
Thus, in our example above with Cat : Animal and Dog : Animal, when the parameter a to Feeder.Feed(Animal) is an instance of Cat then Cat.Speak is the most derived implementation. This is why we will see "Meow!" and not "i can haz cheezburger?"
If MyMethod() is abstract on the base class, then the version in the derived classes will be used. So if you don't need to call the instance in the base class, this would be an option.
static void Main(string[] args)
{
A classA = new A();
B classB = new B();
DoFunctionInClass(classA);
DoFunctionInClass(classB);
DoFunctionInClass(classA as BaseClass);
Console.ReadKey();
}
public static void DoFunctionInClass(BaseClass c)
{
c.MyMethod();
}
public abstract class BaseClass
{
public abstract void MyMethod();
}
public class A : BaseClass
{
public override void MyMethod()
{
Console.WriteLine("Class A");
}
}
public class B : BaseClass
{
public override void MyMethod()
{
Console.WriteLine("Class B");
}
}
If someObject passed in is class A, then A.MyMethod is called, not the base class implementation. Also look at the is keyword.
Because you've typed it as a BaseClass instead of an A or a B, the baseclass is the begin point for the method calls.
You might try using a generic:
public class AnotherObject
{
public AnotherObject<T>(T someObject) where T : BaseClass
{
someObject.MyMethod(); //This calls the BaseClass method, unfortunately.
}
}
I'm not sure how well this will fly in the constructor, but you might be able to move this to a different method.