August 11, 2019
On Sunday, 11 August 2019 at 20:32:14 UTC, John Colvin wrote:
>> As I see this, everything you wrote is correct. :)
>>
>> But you compared abstractness with interface usage, initially. So... I would say, interfaces are more like the abstract method case without any function body. But then, you will have to use "override" all across the inherited classes.
>
> Ok. So that means the difference is pretty subtle, give or take a few extra keywords.
>
> Which leaves multiple inheritance as the only significant difference?
>
> From my perspective it looks like there are two massively overlapping features with some quite arbitrary feeling restrictions and differences. E.g. why can I not inherit from multiple 100% abstract empty classes? Wouldn't that be the same as inheriting from multiple interfaces?

The overlap is there, but it is not so massive, I would say. If you inherit from abstract classes, then you do not plan to keep them empty.
So, the overlap you are speaking about is exactly as large as the amount of "100% abstract empty classes". And for these, the approach to keep the interface as a separate interface seems more convenient, as Adam said.
In the end, by forcing an explicit override, some semantic is also implied.
August 14, 2019
On Saturday, 10 August 2019 at 08:20:46 UTC, John Colvin wrote:
> On Friday, 9 August 2019 at 13:39:53 UTC, Simen Kjærås wrote:
>> <snip>
>
> Thanks for the extra detail.
>
> Is there a solid reason to ever use an interface over an abstract class? (Other than multiple inheritance).
>
> I'm such a noob at anything related to OO.

The way I look at it: an interface is a guarantee. By saying

interface A { void foo()}
class B: A {}
class C: A {}

void bar(A a) {}

you guarantee that every class that implements interface A has a function foo and
and bar can be called with anything that implements interface A.
This is completely unrelated to inheritance.

An abstract class is an implementation, most likely a base class. By saying

abstract class A {void foo()}
class B: A {}
class C: B {}

void bar(A a) {}

you express that you want bar to be called with any subclass of A.

e.g. a bitmap button inherits from button which inherits from abstract class widget and implements the signal/slot interfaces.

Another pattern is design by introspection.
An interface defines what something _is_,
by introspection defines what something _CanDo_.
That's to say: I don't care if foo is actually (or inherits from) an InputRange as long as it behaves like it.
1 2 3
Next ›   Last »