10

When an abstract class implements an interface, it is required to also either define or declare the methods (as asked before):

public interface MyInterface
{
  void Method();
}

public abstract class MyAbstractClass : MyInterface
{
  public abstract void Method(); // required, even though MyAbstractClass does not implement
}

public class MyClass : MyAbstractClass
{
  public override void Method()
  {
  }
}

public interface MyInterface2 : MyInterface
{
  // no need to declare Method() -- why can't abstract classes do the same for unimplemented methods?
}

What is the design rationale of the c# language to require the definition of abstract methods of abstract classes that implement interfaces? It seems completely redundant for an abstract class to be required to define a method that it does not implement (and to make it even worse, for the class that actually implements the method to have to mark the method as override). I see no reason why an abstract class could not behave like MyInterface2, which inherits from MyInterface but does not need to declare MyInterface's methods.

Community
  • 1
  • 1
Jimmy
  • 5,131
  • 9
  • 55
  • 81
  • 3
    That's kind of how Interfaces work. They guarantee a method exists, even if the abstract class declares it as abstract; it means whoever inherits the class MUST implement the method, which means the interface is upheld. EDIT: This is my miniscule understanding of how it works. – Adam Sears Feb 18 '14 at 19:25
  • 4
    Otherwise you'd get an odd hierarchy where anything derived from your abstract class would need to remember that it derived from a class that implemented said interface. – Sam I am says Reinstate Monica Feb 18 '14 at 19:26
  • You could add the interface to your concrete class, instead of to the abstract class, if you don't mean for the abstract class to have the interface methods. – crush Feb 18 '14 at 19:26
  • It feels like a sloppy mental model – Sam I am says Reinstate Monica Feb 18 '14 at 19:27
  • It's redundant *in this case* because the abstract class doesn't do anything. – Preston Guillot Feb 18 '14 at 19:29
  • I see no reason why abstract classes could not behave like interfaces that inherit from other interfaces; the inheritor interface is not required to declare the inheritee's methods & properties. – Jimmy Feb 18 '14 at 20:33
  • @PrestonGuillot: so when is it not redundant? – Jimmy Feb 18 '14 at 20:35
  • 1
    I don't see why this question is marked as opinion-based. The c# language designers seem rather rational about the design of the language, and this question is asking what the rationale is for a specific requirement. Question reworded to emphasize this. – Jimmy Feb 18 '14 at 23:49

3 Answers3

7

An abstract class is a fully-fledged type, just except it cannot be instantiated. Hence its full contract must be declared even though some of its methods are not implemented. A user of a particular abstract class must be able to bind to all its methods, be they coming from interfaces or directly declared in the abstract class. It the methods from interfaces were not (at least) declared (if not even implemented) in the abstract class, the used couldn't bind to them.

Further, classes and interfaces are somewhat loosely-coupled. A class may declare a method, which is later mapped to a same-signature method in an interface which is implemented by its descendant. Hence it is again a “good idea” from the language-design viewpoint to require all methods of interfaces being directly implemented on an abstract class to be actually declared in it.

You can think of an interface as a detachable feature (except when explicit implementations are used). The abstract class may live on its own and its direct users need not to know of any of its interfaces.

It's a design feature that only virtual methods can be left without an implementation, because the technical mechanism of virtual methods needs to be leveraged for the whole concept of abstract classes work in practice.


UPDATE: Example:

public interface IFoo { void M(); }

public abstract class Bar : IFoo
{
    public virtual abstract void M();

    public void N() { }
}

public class Baz : Bar 
{
    public override void M() { … } 
}

… 

public void Method(Bar par)
{
    par.M();
}

…

Baz x = new Baz();
Method(x);

The Method see the instance denoted by the variable x as Bar — neither as Baz nor as IFoo. In other words, the user of class Bar does not care of whether it implemented one, two, ten, or no interface at all. All it does is access its members. It rely's on Bar's contract, not of IFoos contract. Hence if Bar implements IFoo, it must define all members from IFoo.

Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
  • I think the answer is going in the right direction, though I don't understand why you say "an abstract class is a fully-fledged type", if "it cannot be instantiated". Users of an inheritor interface can bind to its methods just fine, even though an inheritor interface does not define the inheritee's methods. – Jimmy Feb 18 '14 at 20:41
  • By “fully-fledged type” I mean it is complete in terms of its *declaration* aspect. It can be used everywhere a type is permitted. The only exception being it cannot be instantiated on runtime, because it *is* incomplete in terms of its *implementation* aspect. The reason for abstract classes is just that: allow incomplete implementations, but require complete declarations. – Ondrej Tucny Feb 18 '14 at 21:56
  • So where can abstract classes be used but not interfaces? – Jimmy Feb 18 '14 at 22:42
  • Classes are a richer concept. Regardless if they are abstract or not. There is not “trivial” answer to your last question. – Ondrej Tucny Feb 18 '14 at 22:49
  • Perhaps, and thanks for taking the time to answer of course, but that still seems unsatisfying to me. I wish John Skeet would jump in! – Jimmy Feb 18 '14 at 23:06
  • Furthermore: when an abstract class inherits from another abstract class, the inheritor does not need to define the inheritees's abstract methods. Thus, once again I don't see why when an abstract class implements an interface it should be forced to define the methods it does not implement. There may be an excellent reason, but I just don't see it. – Jimmy Feb 20 '14 at 15:41
  • Sorry, but I don't see how your example helps prove your point. If Method's parameter was of type Baz, then Method could call par.N(), even though N() is not declared in Baz (it is inherited Bar). To me, that is the same as allowing abstract methods inherited from an interface to not be defined. – Jimmy Feb 20 '14 at 23:59
  • Well that is *not* that same — that's inheritance :-) I think you should better read some book about OOP principles. As of now, it seems you tend to be an “unbeliever” instead of thinking about the arguments. – Ondrej Tucny Feb 21 '14 at 08:16
  • I try not to be subject to irrational skepticism, though I am sure I am not immune to it. I guess I am indeed mixing inheritance & implementation, but I don't think that is wrong, in this case. Abstract classes *do* blur the distinction between inheritance & implementation (hence the fine differences between interfaces & abstract classes, as shown (for example) at http://stackoverflow.com/a/6188877/68936. – Jimmy Feb 21 '14 at 14:44
  • "The most important technical distinction between creating a derived class and implementing an interface is that a derived class can only inherit from one base class, but a class can implement any number of interfaces." (http://msdn.microsoft.com/en-us/library/ms973861.aspx). That seems like a pretty thin distinction to me. This makes me think that (assuming there is no other issue), it would be reasonable for abstract classes that implement interfaces to "inherit" methods they do not implement from interfaces that they "implement/inherit from". – Jimmy Feb 21 '14 at 14:52
6

A method you create in an abstract class that implements the interface doesn't need to be abstract. Abstract classes can contain non-abstract methods too and you can define a full implementation of the interface there. The inheriting classes wouldn't need to override any of those methods.

Also, this is described in MSDN for abstract classes:

An abstract class must provide implementation for all interface members.

An abstract class that implements an interface might map the interface methods onto abstract methods.

Notice the word "might", it's not "has to".

Please also note what MSDN says about implementing an interface:

When a class or struct implements an interface, the class or struct must provide an implementation for all of the members that the interface defines.

This is true for all kinds of classes and structures.

Community
  • 1
  • 1
Szymon
  • 42,577
  • 16
  • 96
  • 114
  • Nice reference to MSDN; documentation is always a good place to start. – Adam Sears Feb 18 '14 at 19:30
  • 1
    I think the OP's concern is why there has to be *any* declaration of an interface method in an abstract class at all, regardless if itself abstract or specific. Your answer seems to discuss something else. – Ondrej Tucny Feb 18 '14 at 19:37
  • @OndrejTucny I was just adding a bit more specifically on that topic. Also, I upvoted your answer as it provides good explanation too. – Szymon Feb 18 '14 at 19:40
  • 1
    I think after the edit your answer is technically complete. On the other hand, my answer provides rather a meta-explanation, without a need for completeness from some format point of view. We should join them together :-) – Ondrej Tucny Feb 18 '14 at 20:30
  • @OndrejTucny: Correct - my concern is why there has to be any declaration of an interface method in an abstract class at all – Jimmy Feb 18 '14 at 20:38
  • @Jimmy First of all, you just need to implement all interface methods as the language requires that. Secondly, you may have methods with code in an abstract class and you wouldn't need to override them in inherited classes. – Szymon Feb 18 '14 at 21:17
  • @Szymon My question is "why does the language require the declaration of abstract methods". Stating that the language requires it is not much of an answer, and secondly I am not asking about "methods with code". – Jimmy Feb 18 '14 at 22:41
1

A class which implements IFoo with method void Bar() has the option of whether or not it wishes to expose a public method Bar(), or whether it wishes to use a non-public member to implement the interface [C# requires the direct implementation method to be either public or private; vb.net also allows protected scope, which is often the most useful sort for abstract classes].

There are two useful ways via which an abstract class could implement IFoo.Bar():

public abtract void Bar();

// or

protected abstract void IFoo_Bar(); // Note that the exact name is arbitrary
void IFoo.Bar() { IFoo_Bar(); }

Both implementations are reasonable. The first would make an unjustified presumption that a class would want to have a public method which appears nowhere in its code; the latter would require the compiler to 'guess' at what name should be given to the abstract method. Because there is no behavior which would be clearly better than any alternative, C# requires the programmer to specify which behavior is desired.

supercat
  • 77,689
  • 9
  • 166
  • 211