Abstract modifier on interface method - c#

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'.

Related

What is the difference between declaring an abstract function within an interface and declaring a function in a non-abstract form?

I have a question while studying C#.
When I declare the interface, I usually declare it like the code below
public interface IRequireInitialization
{
void Init();
}
public class TESTManager : IRequireInitialization
{
public void Init(){ throw new NotImplementedException(); }
}
but my friend said that I should add abstract before the declaration of the interface member function.
I didn't feel any big difference in implementing the interface, what's the difference? And if there is a difference, when should I use it?
public interface IRequireInitialization
{
abstract void Init();
}
public class TESTManager : IRequireInitialization
{
public void Init(){ throw new NotImplementedException(); }
}
C# 8 introduced default interface methods. This allows to define a default implementation (body) for a method in the interface itself.
As part of this proposal they relaxed the syntax to allow modifiers for interface methods:
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.
A method in an interface is abstract by default and abstract modified just makes that explicit:
similarly, although abstract is the default on interface members without bodies, that modifier may be given explicitly.

Hiding/restricting generic base class direct usage from other assemblies [duplicate]

I have a common assembly/project that has an abstract base class, then several derived classes that I want to make public to other assemblies.
I don't want the abstract base class to show up in these other assemblies in Intellisense, so I thought I'd make it internal, but I get this error:
Inconsistent accessibility: base class 'Settings' is less accessible than class 'IrcSettings' ....
I don't really get this. I am forced to make the abstract Settings class public, and thus visible outside this assembly.
How can I make this class internal instead?
As I understand, you want your abstract class to only be implemented by other classes in the same assembly (e.g. it is internal) but the derived classes could be public.
The way to do this is to make the abstract base class public, but give it an internal default constructor:
public abstract class MyClass
{
internal MyClass() { }
}
This will allow MyClass (and hence its members) to be visible and usable to classes outside your assembly, but classes outside your assembly cannot inherit from it (will get a compile error).
Edit: If classes which can be seen by external assemblies inherit from MyClass, you cannot prevent MyClass from also being seen - e.g., showing up in Intellisense. However, you can prevent them from being used by following the above.
The abstract base class has to be public, as the entire inheritance heirarchy for a class has to be visible. This ensures the polymorphism works and is valid; however all the base classes' members can be internal (including the constructor), and hence not usable outside your assembly
There really isn't much of a benefit to what you're trying to achieve but what you're actually looking to achieve is similar to this.
Have your abstract base class in 1 assembly with everything internal. In the AssemblyInfo for that assembly you need to add
[assembly:InternalsVisibleTo("cs_friend_assemblies_2")]
Then in another assembly you have all the classes you want publicly available. Note you will still be able to access the base class from intellisense for any code inside cs_friend_assemblies_2 or whatever you name your assembly but not any where else.
You can't simultaneously make the class available to other assemblies for inheritance but also private so it can't be visible to other consumers. You can make the class internal, and expose it to a specific assembly (if it's a friend assembly) using the [InternalsVisibleTo] attribute, but I don't think this is what you want.
If you want to keep code (other than derived classes) from being able to instantiate your base class, you could give it a protected constructor:
abstract class MyBaseClass
{
protected MyBaseClass() { ... } // only inheritors can access this...
}
You can hide the class members from Intellisense using the EditorBrowsable attribute:
abstract class MyBaseClass
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public void SomeMethodToBeHidden() { }
}
It should be noted that some people have reported problems with the IDE not always respecting this attribute.
As far as I'm concerned, this is a non-problem. Observe:
public abstract class Foo {
public void virtual Bar() {
// default implementation
}
}
public class NormalFoo : Foo { }
public class SpecialFoo : Foo {
public override void Bar() {
// special implementation
}
}
var foolist = new List<Foo>();
foolist.Add( new NormalFoo() );
foolist.Add( new SpecialFoo() );
foreach (var f in foolist) {
f.Bar();
}
The above wouldn't work at all without polymorphism -- being able to refer to instances of different derived classes through their common interface, the abstract base class. What you want to do is take that away and cripple the usability of your class hierarchy. I don't think you should continue down this path.
Will the other assemblies ever inherit from your abstract base class or any of the public classes that do inherit from your abstract base class?
If so, you have to make the abstract base class public. Just make methods you don't want visible outside the assembly internal.
If not, maybe interfaces can help? Define public interfaces, make your public classes implement them, and provide a factory to get instances. That way the only thing intellisense sees outside the assembly is the interface.
Does that help?
A way to work around this limitation is to use composition instead of inheritance (there are other good reasons to do this too). For example, instead of:
internal abstract class MyBase
{
public virtual void F() {}
public void G() {}
}
public class MyClass : MyBase // error; inconsistent accessibility
{
public override void F() { base.F(); /* ... */ }
}
Do this:
public interface IMyBase
{
void F();
}
internal sealed class MyBase2 : IMyBase
{
public void F() {}
public void G() {}
}
public sealed class MyClass2 : IMyBase
{
private readonly MyBase2 _decorated = new MyBase2();
public void F() { _decorated.F(); /* ... */ }
public void G() { _decorated.G(); }
}
You can omit the IMyBase interface entirely if the public doesn't need to know about it and your internals don't either.

Can an abstract class have only method signatures without implementation like interfaces?

Like Interfaces, can an abstract class have only method signatures without implementation? If yes:
How do abstract classes differ from interfaces?
How can another class, which has an abstract class as its base class, implement the body of the base class methods?
An abstract class can contain implementations, but it doesn't have to. This is one thing that makes it different from interfaces.
abstract class classA
{
abstract public void MethodA();
public void MethodB()
{
Console.WriteLine("This is MethodB inside ClassA");
}
}
class classB : classA
{
public override void MethodA()
{
Console.WriteLine("This is MethodA inside class B");
}
}
If you implement a method in the abstract base class and want to be able to override it later, you need to declare the method as virtual.
virtual protected void MethodC(){
//this can be overridden
}
in Java:
q1: The abstract class can contain method definitions AND normal methods while an interface cannot.
q2: from http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
//this is the abstract class
public abstract class GraphicObject {
abstract void draw();
}
//this is the implementation
class Rectangle extends GraphicObject {
void draw() {
...
}
}
Like Interfaces, can an abstract class have only method signature without implementation? If yes:
Yes, but can also have implementation ...
You can also have method implementation in the abstract class unlike interfaces, but you can not create an instance of an abstract class
Interfaces and Abstract Classes
Abstract Class versus Interface
Like Interfaces, can an abstract class have only method signature without implementation?
Yes. Abstract class can have method implementation.
How it differs from Interface?
Variables declared in an interface is by default final. An abstract class may contain non-final variables.
Members of a interface are public by default. An abstract class can have the usual flavors of class members like private, protected, etc..
Interface is absolutely abstract and cannot be instantiated; An abstract class also cannot be instantiated, but can be invoked if a main() exists.
In comparison with abstract classes, interfaces are slow as it requires extra indirection.
Refer the following links:
http://forums.asp.net/t/1240708.aspx/1
http://java.sys-con.com/node/36250
http://www.codeproject.com/Articles/11155/Abstract-Class-versus-Interface
Interface is a fully abstract class,
Means only signatures, no implementations, no data members.
On the other hand abstract class by defenition needs at least one abstract method.
Also it can have implementations.
And it also can contain data members which will be inherited to its inheritors.
The inheritor needs to implement the abstract method with the same signature in order to implement it
in JAVA Yes,
if you use abstract class this way, then there is no difference between interface and abstract class. what dose abstract class really matter is you can offer common implementation which expect to be inherited by sub class, that's interface is not able to do.
yes, as I said, that abstract class behave the same way as interface, you can just override the methods in sub class
For example:
public abstract class AbstractClassWithoutImplementation {
public abstract String methodA();
}
public class Implementation extends AbstractClassWithoutImplementation {
#Override
public String methodA() {
// TODO Auto-generated method stub
return "Yes";
}
public static void main(String[] args){
Implementation im = new Implementation();
System.out.println(im.methodA());
}
}
An abstract class is a class that cannot be instantiated. It is in between a concrete class (fully implemented) and an interface (not at all implemented).
It can contain regular members (variables, methods etc) that are fully implemented.
It can also contain abstract members that are not implemented. Any member that is not implemented, say a method signature, must be marked abstract.
So to answer your questions:
Like Interfaces, can an abstract class have only method signature without implementation?
Your wording is not clear enough to give a yes or no answer. An abstract class can have implemented methods, and it can have abstract methods that are not implemented which must be marked as abstract. It cannot have methods without implementation unless they are marked abstract.
If yes: How it differs from Interface?
Because it allows implementation of members.
How another class, for which this Abstract Class is acting as a base class, can implement the body of that method?
Simply needs to implement all the abstract members.
public abstract class A
{
public abstract void Test();
}
public class B : A
{
public void Test(){ return; }
}
Like Interfaces, can an abstract class have only method signature without implementation? If yes:
Yes, An abstract class can have all abstract methods even if it has a single abstract method it must be abstract.You can declare a class as abstract even if it doesn't have any abstract method.
How it differs from Interface?
In Interface ALL methods are abstract public bet in Abstract class it is not necessary that .Please read about Interface vs Abstract Class
How another class, for which this Abstract Class is acting as a base class, can implement the body of that method?
If your BaseClass is Abstract and ChildClass is extending Base class you can implement abstract method in ChildClass otherwise make ChildClass abstract also.
public class ChildClass extends BaseClass{
void display(){
/// Your Implementation here
}
}
abstract class BaseClass{
abstract void display();
}

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.

why virtual is allowed while implementing the interface methods?

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.

Categories

Resources