why virtual is allowed while implementing the interface methods? - c#

I have one specific query with the interfaces.
By default interface methods are abstract and virtual so if we implement that interface and gives definition in the class we actually override that method but when we mark the method as a virtual again in the implementing class why the compiler is not considering that we are actually trying to hide the original interface virtual method.
Like if we have a virtual method in the base class and derived class again marked the method as virtual in that case compiler gives the warning that you are hiding the base class method so use new if you are intentionally hiding the base class method.
public interface ITestInterface
{
void virtualmethod(); // this method is by default virtual.
}
public class TestInterface :ITestInterface
{
public virtual void virtualmethod()
{
// Now compiler should consider that i am actually hiding the interface virtual method.
}
}
if you build the above code for interface and open in ILDASM you will see the code like this:
.method public hidebysig newslot abstract virtual
instance void virtualmethod() cil managed
{
}//end of method ITestInterface::virtualmethod

Methods that are implemented from an interface are not virtual by default. You are merely providing an implementation of the contract defined in the interface definition. By marking the method as virtual, you are allowing derived classes to provide additional or separate implementation while still honoring the contract as defined.
Consider this example:
interface IAnimal
{
string Speak();
}
class Dog : IAnimal
{
public string Speak()
{
return "Bark!";
}
}
The Dog class is implementing the interface by providing an implementation of the contract IAnimal. There are no virtual methods here and no overriding.
Now consider this example:
interface IAnimal
{
string Speak();
}
class Dog : IAnimal
{
public virtual string Speak()
{
return "Bark!";
}
}
class GoldenRetriever : Dog
{
public override string Speak()
{
return "I am a golden retriever who says "
+ base.Speak();
}
}
Now the Dog class has declared Speak to be virtual which allows derived classes to provide an additional or new implementation. This does not break the contract with IAnimal as any call to the Speak method still returns a string.
Ok, one last example. Remember that interfaces don't require an implementation - they only require that the contract is satisfied. This means that the interface only cares that a member exists in the implementing class that has a matching signature. This means that we could also do this:
interface IAnimal
{
string Speak();
}
abstract class Dog : IAnimal
{
public abstract string Speak();
}
class GoldenRetriever : Dog
{
public override string Speak()
{
return "I am a golden retriever";
}
}
Notice now that the Dog class provides no implementation at all for Speak yet has satisfied the requirements of the contract.
Interfaces are also inherited from class to class so in all the examples above both Dog and GoldenRetriever implement the IAnimal interface. Neither class hide the Speak method - both classes implement it.
Ok, I think your confusion may be coming from the fact that the virtual method is defined in an interface, not a class. Here is the IL for the interface I defined above:
.class private interface abstract auto ansi IAnimal
{
.method public hidebysig newslot abstract
virtual instance string Speak() cil managed
{
}
}
While you are correct that the method is defined as virtual you also need to notice that the type here is designated as an interface. This is purely an implementation detail of the MSIL generated by Microsoft's C# compiler - another compiler could easily generate different code as long as semantically it provided the same result.
The important thing here is this: even though the method is declared as virtual in the interface that does not mean that it is the same thing as a virtual method declared in class.

Interface is not Base Class, so implementation methods are not overriden. Interface only declares the methods, Interface methods are not virtual by default, infact interfaces only declare the methods that are available on the class that implements that interface.
Declaration can not be virtual.
Implementation can or cannot be virtual that is completely dependent on the implementer's logic.

There is a mix-up of the term 'virtual' here, between IL and C#.
They do not completely correspond. Virtual in the IL sense means "it's called indirect" via a VMT(virtual method table), that is about the same mechanism for class overriding and interface implementation.
In the IL sense, an interface member must be marked virtual - there is no way around.
But if you look in the implementation, it's marked as 'virtual final'. That is something you cannot achieve in C#. 'Final' means, it cannot be overriden. It does not become virtual in the meaning of C#, unless you declare it manually as 'virtual' or 'abstract' in C#.
The implicit interface implementation of C# (it doesn't exist in VB.NET or IL) is quiet powerful. It does attach the Method of the implementing class, that matches in Name-Parameters-ReturnValue (the Signature, or SigAndName in the IL wording).
This includes using base class implementations for the methods.
public interface ITest
{
double MethodC(double a, double b, double c, double d);
}
internal class BaseClass
{
public double MethodC(double a, double b, double c, double d)
{
return a+b+c+d;
}
}
internal class OtherClass : BaseClass , ITest
{
}
This actually works fine.
But C# is doing a Trick here, Cause you use the BaseClass.MethodC as an interface implementation, it's marked as final virtual in the BaseClass.
Yes, the way how BaseClass is implemented, depends on how BaseClass is used.
BaseClass.MethodC is modified, cause it's used to implement ITest.MethodC in a derived class. This even works over file and project boundaries, as long as the source code of BaseClass is in the same solution.
So the output of the compilation of a project, is not the same, if you compile it by itself, or in a big solution together with other products. This is quiet noticable.
If the source code of BaseClass is not available, if you just linked into a DLL, then C# will generate a Wrapper to use the BaseClass implementation.
It will actually do this:
internal class OtherClass : BaseClass , ITest
{
double ITest.MethodC(double a, double b, double c, double d)
{
return base.MethodC(a, b, c, d)
}
}
This is done in secret, but it's absolutely necessary to have a method marked as virtual in the IL sense.

Related

Abstract modifier on interface method

Today I was copying some methods from an abstract class to an Interface and I realized that the compiler does not underline the abstract keyword. I tried to look up the documentation but found nothing about it.
I also put it into SharpLab but see no difference between the two.
public interface ITestAbstract
{
public abstract void MyTest();
}
public interface ITest
{
public void MyTest();
}
My guess is, that it is allowed since, by default interface methods are actually abstract methods, or am I missing something out?
This feature was added in C# 8 - Default Interface Methods:
Modifiers in interfaces
The syntax for an interface is relaxed to permit modifiers on its members. The following are permitted: private, protected, internal, public, virtual, abstract, sealed, static, extern, and partial.
This means that you are not allowed to modify your methods with abstract before this.
One of the purposes is to support reabstraction. Example from the docs:
interface IA
{
void M() { WriteLine("IA.M"); }
}
interface IB : IA
{
abstract void IA.M();
}
class C : IB { } // error: class 'C' does not implement 'IA.M'.

How does the C# compiler distinguish between a concrete subclass impl of an abstract method and an overload in the abstract base?

If you have a base class
public abstract class AbsHashtableish<TKey, TValue>
{
public abstract TKey ConvertToKey(string key);
public abstract bool KeyExists(TKey key);
public virtual bool KeyExists(string key)
{
Console.WriteLine("In Base");
return KeyExists(ConvertToKey(key));
}
}
and a concerete class
public class ConcreteHashtableish: AbsHashtableish<string, Dinosaur>
{
...
public override string ConvertToKey(string key)
{
return key;
}
public override bool KeyExists(string key)
{
Console.WriteLine("In Sub");
return _list.Contains(key);
}
}
and client A
AbsHashtableish<string, Dinosaur> concreteA = new ConcreteHashtableish<string, Dinosaur>();
and client B
ConcreteHashtableish<string, Dinosaur> concreteB = new ConcreteHashtableish<string, Dinosaur>();
What are the rules (and if possible, the reasoning behind them) for determining whether the code shown above is sufficient to compile and if so:
Is there a difference between calling KeyExists on concreteA vs concreteB?
Assuming we can somehow enter the base class method KeyExists(string key), will we be able to get out of it?
For question #2, what I mean is that if somehow the compiler is able to compile this code, does it do so by effectively hiding the base method from the client - because if that code was reached, it would result in an infinite loop?
Calling KeyExists on both convreteA and concreteB is eventually the same.
The Common Language Runtime (CLR) knows to invoke methods on the actual type (using a Virtual Method Table). This is the whole point of Polymorphism. It allows you to refer concrete implementations as abstract ones, but the actual methods getting called are of the concrete types.
In the particular example you gave, you can't use the base class implementation of KeyExists from outside the derived class, simply because you can't create an instance of an abstract class. If it wasn't abstract, you can create:
AbsHashtableish<string, Dinosaur> baseA = new AbsHashtableish<string, Dinosaur>();
And AbsHashtableish.KeyExists will get called.
EDIT: (Thanks to Oliver for noting)
You can always call the base class implementation from inside a derived class. In this case you would call:
base.KeyExists(key)

Multiple inheritance with Abstract class and Interface

I have written the following code in C#.NET
public interface IWork
{
void func();
}
public abstract class WorkClass
{
public void func()
{
Console.WriteLine("Calling Abstract Class Function");
}
}
public class MyClass:WorkClass,IWork
{
}
On compiling, I didn't get any error. Compiler is not forcing me to implement the method "func();" in "MyClass", which has been derived from the interface "IWork".Latter, I can gracefully create a instance of the class "MyClass" and call the function "func()". Why the compiler is not forcing me to implement the "func()" method in the "MyClass"(which has been derived from "IWork" interface? Is it a flaw in C#?
While reading about this subject, I found I couldn't easily put it all together in my head, so I wrote the following piece of code, which acts as a cheat-sheet for how C# works. Hope it helps someone.
public interface IMyInterface
{
void FunctionA();
void FunctionB();
void FunctionC();
}
public abstract class MyAbstractClass : IMyInterface
{
public void FunctionA()
{
Console.WriteLine( "FunctionA() implemented in abstract class. Cannot be overridden in concrete class." );
}
public virtual void FunctionB()
{
Console.WriteLine( "FunctionB() implemented in abstract class. Can be overridden in concrete class." );
}
public abstract void FunctionC();
}
public class MyConcreteClass : MyAbstractClass, IMyInterface
{
public override void FunctionB()
{
base.FunctionB();
Console.WriteLine( "FunctionB() implemented in abstract class but optionally overridden in concrete class." );
}
public override void FunctionC()
{
Console.WriteLine( "FunctionC() must be implemented in concrete class because abstract class provides no implementation." );
}
}
class Program
{
static void Main( string[] args )
{
IMyInterface foo = new MyConcreteClass();
foo.FunctionA();
foo.FunctionB();
foo.FunctionC();
Console.ReadKey();
}
}
Gives the following output:
FunctionA() implemented in abstract class. Cannot be overridden in concrete class.
FunctionB() implemented in abstract class. Can be overridden in concrete class.
FunctionB() implemented in abstract class but optionally overridden in concrete class.
FunctionC() must be implemented in concrete class because abstract class provides no implementation.
To better understand the concept behind interfaces, I just give you the correct code of your implementation:
public interface IWork{
void func();
}
public abstract class WorkClass,IWork{
public void func(){
Console.WriteLine("Calling Abstract Class Function");
}
}
public class MyClass:WorkClass{
...
}
The basic rule: You need to include the interface always where the implementation is. So if you create a method within an abstract classes and define an interface of this method, you'll need to implement the interface into your abstract class and then all subclasses will automatically implement this interface.
As a matter of fact, interfaces have 2 kind of functions you can use them for:
1) As a "real" interface providing a generic handling of any class implementing the interface, so you can handle several kind of classes just by one interface (without knowing their real class names). While "handling" means: Calling a method.
2) As a help for other (framework) programmers not to mess up with your code. If you want to be sure that an method won't be replaced with another name, you define an interface for your class containing all "must have" method names. Even if the method is called nowhere, your programmer will get an compile error message when he changed the method name.
Now you can easily handle your Myclass just by the interface IWork.
Because the abstract class implements the interface.
If your class MyClass would not inherit from WorkClass you would get an error saying 'MyClass' does not implement interface member 'IWork.func()'.
But you also inherit from WorkClass, which actually implements the methods that the interface requires.
You can mark func() as abstract if you want to force the classes that inherits from it to implement it like this:
public abstract class WorkClass
{
public abstract void func();
}
I tried with the classes above in my solution.
It inherits the abstract class so the derived class have the func() method definition. This is the reason it was not able to show compiled errors.
func() is not marked as abstract in the WorkClass so you don't need to implement it in any classes that derive from WorkClass.
WorkClass implements the IWork interface so you don't need to implement it in MyClass because it inherits func() from WorkClass.
Since the func method in the abstract class is a non-virtual method, so the compiler thinks this method is a implementation of the interface.
When you extend MyClass to WorkClass, the method func() (which has been defined), is inherited.
So, when the interface IWork is implemented, the method 'func()' has already been defined. So, there are no more undefined methods in MyClass.
So, the class MyClass is a concrete class, due to which you are able to create a MyClass object without any compilation errors.

Difference between abstract class and interface [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Interface vs Base class
I am not understanding the difference between an abstract class and an interface. When do I need to use which art of type?
Try thinking of it like this:
An abstract class creates an "is-a" relationship. Volkswagon is a Car.
An interface creates a "can-do" relationship. Fred can IDrive.
Moreover, Fred can IDrive, but Fred is a Person.
When we create an interface, we are basically creating a set of methods without any implementation that must be overridden by the implemented classes. The advantage is that it provides a way for a class to be a part of two classes: one from inheritance hierarchy and one from the interface.
When we create an abstract class, we are creating a base class that might have one or more completed methods but at least one or more methods are left uncompleted and declared abstract. If all the methods of an abstract class are uncompleted then it is same as an interface. The purpose of an abstract class is to provide a base class definition for how a set of derived classes will work and then allow the programmers to fill the implementation in the derived classes.
article along with the demo project discussed Interfaces versus Abstract classes.
An abstract class is class probably with some abstract methods and some non-abstract methods. They do stuff (have associated code). If a new non-abstract class, subclasses the abstract class it must implement the abstract methods.
I.E.
public abstract class A {
public string sayHi() { return "hi"; } // a method with code in it
public abstract string sayHello(); // no implementation
}
public class B
: A
{
// must implement, since it is not abstract
public override string sayHello() { return "Hello from B"; }
}
Interface is more like a protocol. A list of methods that a class implementing that interface must have. But they don't do anything. They have just method prototypes.
public interface A
{
string sayHi(); // no implementation (code) allowed
string sayHello(); // no implementation (code) allowed
}
public class B
: A
{
// must implement both methods
string sayHi() { return "hi"; }
string sayHello() { return "hello"; }
}
Both are often confused because there is no protocol/interface in C++. So the way to simulate an interface behavior in that language is writing a pure virtual class (a class with only pure virtual functions).
class A {
virtual int a() = 0; // pure virtual function (no implementation)
}

Abstract class does not implement interface

I have an interface so class writers are forced to implement certain methods. I also want to allow some default implemented methods, so I create a abstract class. The problem is that all classes inherit from the base class so I have some helper functions in there.
I tried to write : IClass in with the abstract base, but I got an error that the base didn't implement the interface. Well of course because I want this abstract and to have the users implement those methods. As a return object if I use base I can't call the interface class methods. If I use the interface I can't access base methods.
How do I make it so I can have these helper classes and force users to implement certain methods?
Make sure methods in the base class have the same name as the interface, and they are public. Also, make them virtual so that subclasses can override them without hiding them.
interface IInterface {
void Do();
void Go();
}
abstract class ClassBase : IInterface {
public virtual void Do() {
// Default behaviour
}
public abstract void Go(); // No default behaviour
}
class ConcreteClass : ClassBase {
public override void Do() {
// Specialised behaviour
}
public override void Go() {
// ...
}
}
Move the interface methods into the abstract class and declare them abstract as well. By this, deriving classes are forced to implement them. If you want default behaviour, use abstract classes, if you want to only have the signature fixed, use an interface. Both concepts don't mix.
Having faced with the same problem recently, I've came up with a somewhat more elegant (to my mind) solution. It looks like:
public interface IInterface
{
void CommonMethod();
void SpecificMethod();
}
public abstract class CommonImpl
{
public void CommonMethod() // note: it isn't even virtual here!
{
Console.WriteLine("CommonImpl.CommonMethod()");
}
}
public class Concrete : CommonImpl, IInterface
{
void SpecificMethod()
{
Console.WriteLine("Concrete.SpecificMethod()");
}
}
Now, according to C# spec (13.4.4. Interface mapping), in the process of mapping IInterface on Concrete class, compiler will look up for CommonMethod in CommonImpl too, and it doesn't even have to be virtual in the base class!
The other significant advantage, compared to Mau's solution, is that you don't have to list every interface member in the abstract base class.

Categories

Resources