On Sunday, August 11, 2019 2:32:14 PM MDT John Colvin via Digitalmars-d-
learn wrote:
> On Sunday, 11 August 2019 at 20:15:34 UTC, Alex 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?

Well, as things stand, _no_ class is 100% abstract, because they all derive
from Object, and Object has virtual functions on it with implementations,
whereas an interface _is_ 100% abstract. Maybe once we have ProtoObject, it
could be argued for allowing 100% abstract classes to be treated as
interfaces, but right now, that wouldn't be possible, and even with
ProtoObject, it arguably wouldn't be worth the extra complication, since if
you really intend to have a 100% abstract class, that's what interfaces are
for.

There's also the weird complications that come with D's COM support, since
that uses interfaces but gets treated differently from how classes are
normally treated, and I don't know how that affects the implementation of
interfaces. If we'd had ProtoObject from the get-go, I wonder if it would
have just been better to implement COM interfaces as being derived from a
specific class that's derived from ProtoObject instead of mucking up
interfaces the way that we currently hove, but I don't know. I haven't ever
actually used D's COM support, so I don't fully understand it.

For the most, D's interfaces and abstract classes follow what you get in
Java and C# (though the weirdness with COM is unique to D as is the ability
to have final functions with an implementation). Basically, it seems like
what we got with interfaces and abstract classes was copied from Java and
then tweaked. I suspect that the separation between interfaces and abstract
classes in Java comes from the fact that Object has functions on it, and
that same logic carried over to D.

In practice, what I would expect to typically happen is that if you're
defining a set of functions that a class needs to have but not providing any
implementations, then you'd use an interface, whereas if you intend to
provide an implementation for any part of it but not all of it, you'd use an
abstract class. I wouldn't expect abstract classes with no functions
(outside of those from Object) or variables being declared on them to be
used much. Maybe someone would have a use case where it would make sense to
have a common base class with no implementations, but I can't think of any
reason why that would be useful other than preventing classes from being
derived from any class from a different class hierarchy, which isn't usually
something that's worth preventing.

Regardless, the whole weirdness that you're running into with void* is not
something that much code would care about, because very little code is going
to do something like cast a reference to void*, and the code that does do
that is @system and expected to deal with it correctly. In general, casting
to void* and then casting to anything other than the original type is
probably asking for trouble. If I understand correctly, with void*, you're
basically doing a reinterpet cast, and that's not usually the type of cast
you want when dealing with class references. If I had code where whether
casting to an interface or abstract class mattered, I'd want to redesign it
so that that didn't matter.

- Jonathan M Davis



Reply via email to