experts,
below is code for abstract class with virtual method and override in class B.
Can we call method M1 of class A, as we can't instantiate this? thanks,
public abstract class A
{
public virtual int M1(int a, int b)
{
return a + b;
}
}
public class B : A
{
public override int M1(int a, int b)
{
return a - b;
}
}
As soon as B overrides M1 virtual method dispatch will make B.M1() being called, even when you cast instance of B to A.
The only place you can call it is from within B code, using base.M1() syntax:
public override int M1(int a, int b)
{
var temp = base.M1(a, b);
return temp - a - b;
}
However, there can be another class inheriting from A (lets name it C), which does not override M1. In that case, calling M1 on instance of C will invoke A.M1().
You must instantiate a class that implements A1, virtual is a method you CAN override but if you don't it will execute the base class method.
Related
public class a
{
protected virtual int mult(int x)
{
return x * x;
}
}
public class b : a
{
protected override int mult(int x) { return x * x * x; }
}
internal class Program
{
static void Main(string[] args)
{
b jack = new b();
int v = jack.mult(5); // error
// so how can I access mult() in the main class without changing the access modifier to public ??????
}
}
How to access a function whose access modifier is protected and exists in a class that inherits from another class in c#?
Note that the mult function is declared as protected in both class a and class b, which means that it can only be accessed by code within the class or its derived classes. Since b is a derived class of a, the mult function is accessible to code within b.
If you want to access the mult function from a class other than b or a subclass of b, you will need to change the access modifier to the public or provide a public method in b or a subclass of b that calls the mult function.
In this case you are doing all this in the Main method which is in other class than a or b.
I have a base class (A) that I have built with some base functionality, and now want to create a subclass (B) with some custom functionality from an external third class (C), which can still be treated as an object of type A.
As I understand it, C# doesn't allow a class to inherit from more than one class, and the typical approach to this kind of problem is to change the base class to an interface, so that the subclass can still inherit from C, and implement A as an interface. However I also want A to provide some default method implementations, which B may override and call. I can't seem to find any way to call A.someMethod() from B if B has it's own implementation of someMethod().
I've put together a code example which hopefully shows what I'm trying to achieve:
Base Case:
public class A {
// Contains default method implementations and properties
public virtual int someMethod(int i){
return i;
}
}
public class B: A{
// B does not inherit C
public override int someMethod(int i){
return i*base.someMethod(i);
}
}
public class C{
// Package class which B must subclass from
}
B Cannot Inherit from A and C:
public class A {
// Contains default method implementations and properties
public virtual int someMethod(int i){
return i;
}
}
public class B: C, A {
// Theoretically solves the problem, but C# doesn't support multiple inheritance with classes
public override int someMethod(int i){
return i*base.someMethod(i);
}
}
public class C{
// Package class which B must subclass from
}
Can't access default implementation in B, calling someMethod results in a stack overflow
public interface A {
// Contains default method implementations and properties
public virtual int someMethod(int i){
return i;
}
}
public class B: C, A {
// Making A an interface allows B to be stored in a list of type A, but how can I access the default implementation?
int A.someMethod(int i){
return i*(this as A).someMethod(i);
}
}
public class C{
// Package class which B must subclass from
}
Only working solution that I have, but seems very clunky:
public interface A {
// Contains default method implementations and properties
public virtual int someMethod(int i){
return _someMethod(i);
}
public virtual int _someMethod(int i){
return i;
}
}
public class B: C, A {
int A.someMethod(int i){
return i*(this as A)._someMethod(i);
}
}
public class C{
// Package class which B must subclass from
}
Is option 4 the best approach? Or is there a better way to do this?
Is it possible to access the method that has been overridden using the object of the derived class?
using System;
class Bclass
{
public virtual int result(int a,int b)
{
return a + b;
}
}
class Dclass:Bclass
{
public override int result(int a, int b)
{
return a - b;
}
}
public class Program
{
static public void Main(string[] args)
{
Dclass obj1 = new Dclass();
Console.WriteLine(obj1.result(10, 5));
}
}
Is there a way to get the output as 15?
From MSDN documentation:
The override modifier is required to extend or modify the abstract or
virtual implementation of an inherited method, property, indexer, or
event.
override modifier are designed to extend functionality of virtual function. When ever you call overridden function with the help of derived class object it will call overridden function.
To answer your question,
Is it possible to access the method that has been overridden using the
object of the derived class?
There is no way to call virtual method directly using derived class object
Ways to call virtual method:
Approach 1:
Create a new function in derived class and call base.result() from it.
public int BaseResult(int a, int b)
{
return base.result(a, b);
}
and call BaseResult() using derived class instance
Dclass obj1 = new Dclass();
Console.WriteLine(obj1.BaseResult(10, 5));
Try it online
Approach 2:
Create instance of base class and from that access virtual method.
Bclass obj2 = new Bclass();
Console.WriteLine(obj2.result(10, 5));
Unless you need to declare the base method as virtual for some reason, you could also achieve what you want by declaring the derived class method as new, thereby hiding the implementation when using it through an instance of the derived class.
At the same time, you can still access the base implementation by casting the object to the base class.
Following the example you provided:
class Bclass
{
public int result(int a,int b)
{
return a + b;
}
}
class Dclass : Bclass
{
public new int result(int a, int b)
{
return a - b;
}
public int BaseResult(int a, int b)
{
return base.result(a, b);
}
}
public class Program
{
public static void Main(string[] args)
{
Dclass obj1 = new Dclass();
Console.WriteLine(((Bclass)obj1).result(10, 5)); // 15
}
}
More information about the differences between override and new can be found in this MSDN article.
I'm extending a libary class which has a public Method that I don't wan't to be callable from the outside. I know that I can hide it using the "new" keyword, but the problem is, that it has a lot of different declarations.
Something like this:
class Parent() {
public double method(double a, double b) { ... }
public int method(int a, int b) { ... }
public System.Int32 method(System.Int32 a, System.Int32 b) { ... }
}
Now I could do:
class Child() {
// Make method private.
private new double method(double a, double b) { return base.method(a, b) }
private new int method(int a, int b) { return base.method(a, b) }
private new System.Int32 method(System.Int32 a, System.Int32 b) { return base.method(a, b) }
/// Own Code.
}
But I'm wondering if there is not a simpler way to make all overrides of that function private.
I think the first question is whether or not your descendant class needs to be cast as the parent.
If not, then the best way would be to use a facade pattern in which you hide the "parent" and only allow access to it through your methods.
Kind of like:
class Parent {
public double method(double a, double b) { ... }
public int method(int a, int b) { ... }
}
class YourStuff {
private Parent _parent = new Parent();
public int AddNumbers(int a, int b) {
return _parent.method(a,b);
}
}
In this case, the Parent class is hidden.
That's not the way method hiding works. Your private new methods only hide the original methods inside the Child class (but they call what they hide, so nothing's gained).
In a Grandchild class deriving from Child, nothing is hidden anymore because the private new methods are not in scope, so the public methods of Parent are perfectly callable and "naked". Method hiding does not remove the hidden method in any way; it's just a matter of which of the identical methods gets called.
If you want that your library class Parent method which name Method will not be callable from the outside you need to change access modifier. Your class hasn't access modifier, so, be default it is Internal - The type or member can be accessed by any code in the same assembly, but not from another assembly. The same accessibility is for method Method as it has access modifier public. If you want that implemented in class Method can be accessible only for derived class instance you need all access modifiers public for overloaded Method variations to change to protected and then in a child class hide this method overloaded methods. If you want these hidden methods to be used from outside you need to change their access modifiers from private to public. Example of this implementation:
namespace HideBaseClassMethod
{
class Program
{
static void Main(string[] args)
{
Parent myParent = new Parent();
//myParent. - no one of overloaded protected methods are accessible after dot operator
Child myChild = new Child();
myChild.Method(2.5, 4.3); //double
myChild.Method(2, 4);//int
Parent myChildCreatedAsParent = new Child();
//myChildCreatedAsParent. - no one of overloaded protected methods are accessible after dot operator
}
}
class Parent
{
protected double Method(double a, double b)
{
Console.WriteLine($"I am a parent double method {a} + {b}");
return a + b;
}
protected int Method(int a, int b)
{
Console.WriteLine($"I am a parent integer method {a} + {b}");
return a + b;
}
}
class Child:Parent
{
public new double Method(double a, double b)
{
Console.WriteLine($"I am a child double method {a} * {b}");
return a * b;
}
public new int Method(int a, int b)
{
Console.WriteLine($"I am a child integer method {a} * {b}");
return a + b;
}
}
}
The result of this program execution will be:
I am a child double method 2.5 * 4.3
I am a child integer method 2 * 4
I'm wondering if the following is possible:
class A
{
public int SomeMethod()
{
return 1;
}
}
class B : A
{
public override int SomeMethod()
{
return 3;
}
}
class DrivingClass
{
public static void Main()
{
B classB = new B();
A classA = (A)classB;
Assert.IsEqual(3, classA.SomeMethod());
}
}
This fails of course expecting 3 but actual is 1. Is there a way (without typecasting it back to B) for classA.SomeMethod() to call the overridden version since it started out as B(although I assume this knowledge is lost once casted).
UPDATE:
Class A is already written and for all intents and purposes can not be edited. I can only control class B. Knowing the class B will be casted to type A, I simply want my implementation to be used when SomeMethod() is called on my typecasted B.
SomeMethod needs to be declared as virtual in A in order to successfully override it in B.
public virtual int SomeMethod() // in A
public override int SomeMethod() // in B
With this properly in place
A a = new B();
int value = a.SomeMethod();
Debug.Assert(value == 3); // succeeds
If you instead have
public int SomeMethod() // in A
public new int SomeMethod() // in B, or just
public int SomeMethod() // in B
Then the above assertion fails. The method in B hides the base method, but only via the B reference. When operating under the reference of A, you get the base behaviors.
A a = new B();
int value = a.SomeMethod(); // gets 1 from A, not 3 from B
UPDATE: Class A is already written and for all intents and purposes can not be edited. I can only control class B. Knowing the class B will be casted to type A, I simply want my implementation to be used when SomeMethod() is called on my typecasted B.
Methods are not virtual by default in C#. If the authors of A did not design it with extensibility in mind (at least, as far as overriding SomeMethod), you will not be able to replace or override that behavior with B when it is being treated as A. However, if you are in a position to control the casting, or rather the dependency of the code, you can perhaps invert it so that A actually adheres to the contract of B, not the other way around. Consider the Adapter Pattern, for example.
interface IB
{
int SomeMethod();
}
class B : IB
{
public int SomeMethod() { return 3; }
}
class ABAdapter : IB
{
private A a;
public ABAdapter(A a) { this.a = a; }
public int SomeMethod() { return a.SomeMethod(); }
}
In this example, you've used the adapter to pattern to make A actually fulfill the contract of B, via the IB interface. So code that might once have depended upon A or B can now depend upon IB. The ABAdapter simply delegates to the A implementation.
public void DoSomething(IB ib) // given
A a = new A();
DoSomething(new ABAdapter(a)); // invoke with A
DoSomething(new B()); // invoke with B
You haven't declared SomeMethod to be virtual in A, so this clearly isn't your real code (as otherwise B can't override it) but when you make that change, it will return 3. If it didn't, polymorphism would be completely broken.
Now, the other change we could make to the code you've posted is in B. If you use:
public new int SomeMethod()
{
return 3;
}
Then your assertion would fail - because it would be calling A.SomeMethod() which is shadowed or hidden by B.SomeMethod(), not overridden. Basically, if you want polymorphic behaviour, you need to use override, and it has to be on a virtual method.
I suggest reading up on the topic here
In the article it shows these code examples:
class A
{
public void F() { Console.WriteLine("A.F"); }
public virtual void G() { Console.WriteLine("A.G"); }
}
class B: A
{
new public void F() { Console.WriteLine("B.F"); }
public override void G() { Console.WriteLine("B.G"); }
}
class Test
{
static void Main() {
B b = new B();
A a = b;
a.F(); //prints A.F
b.F(); //prints B.F
a.G(); //prints B.G (due to virtual method override)
b.G(); //prints B.G
}
}
Given your edit stating that you cannot redefine class A, I'm afraid you're more or less out of luck.
It's possible to derive B from A, and then declare new int SomeMethod(), but you won't be able to call that method with an A reference. You could use a run-time type check:
int CallSomeMethod(A obj)
{
var b = obj as B;
return b == null ? obj.SomeMethod() : b.SomeMethod();
}