abstract class 'does not implement interface member ...'

  • Thread starter Ben Voigt [C++ MVP]
  • Start date
B

Ben Voigt [C++ MVP]

Peter Duniho said:
Since your original specifically asked about that compiler error, I hope
you can see where at least some of my confusion originated. :)


Can you elaborate on why having an explicit-but-internal interface doesn't
accomplish what you want? It seems to me that that _does_ give you
internal visibility, without any additional runtime cost.

No, it doesn't. You can't override such a method, which you could with a
real internal method. Then you need *another* virtual method, declared with
the correct visibility, with a private explicit implementation forwarder.
That requires an extra v-table slot, and an extra function call at runtime,
because it is called polymorphically, thus preventing the JIT from inlining.
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
"internal" just isn't the same as "enclosing class", it doesn't enforce
encapsulation anywhere near as well, in fact it breaks it because
Intellisense will show those "internal" members to all coders working on the
same assembly.

Try using that class from outside the enclosing class and you won't be
able to - because the nested class itself isn't visible outside the
enclosing class.
A private interface declared in the enclosing class works, with explicit
implementation, but then you have to qualify every call with the interface
name... still not very nice.

True.
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
How about "you don't, you see only members in my most derived types and in
public interfaces".

Ick - I wouldn't like that at all.
That principle totally eliminates inheritance as a means of reusing
implementation details. But I guess that's what the .NET architects wanted,
because they didn't provide non-public inheritance.

I think you must be meaning something beyond the obvious, because the
idea that .NET stops you reusing implementation details via inheritance
is crazy in itself. Do you think that every class in the framework
reimplements all of its public members, rather than ever relying on the
base class's implementation? Do you do that when coding in .NET? Do you
always override *all* the virtual methods in *every* class? If not, you
*are* reusing implementation details via inheritance.

So, given that that can't be what you mean, what *do* you mean?
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
Try using that class from outside the enclosing class and you won't be
able to - because the nested class itself isn't visible outside the
enclosing class.

Guess you missed this in my earlier post: "the nested class itself is
publicly visible, ala list::iterator, but carries data only meaningful to
the enclosing class."
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
Ick - I wouldn't like that at all.


I think you must be meaning something beyond the obvious, because the
idea that .NET stops you reusing implementation details via inheritance
is crazy in itself. Do you think that every class in the framework
reimplements all of its public members, rather than ever relying on the
base class's implementation? Do you do that when coding in .NET? Do you
always override *all* the virtual methods in *every* class? If not, you
*are* reusing implementation details via inheritance.

So, given that that can't be what you mean, what *do* you mean?

I mean that when you use inheritance, it's not an implementation detail.
It's a part of the public interface.
 
P

Peter Duniho

No, it doesn't. You can't override such a method, which you could with
a real internal method.

You seem to have shifted tracks here. I thought we were talking about the
question of restricting access to an interface implementation. When did
the question of whether the method can be overridden or not come up, and
in what way does the protection level of the method play a part?

Pete
 
B

Ben Voigt [C++ MVP]

Peter Duniho said:
You seem to have shifted tracks here. I thought we were talking about the
question of restricting access to an interface implementation. When did
the question of whether the method can be overridden or not come up, and
in what way does the protection level of the method play a part?

Only the entire thread, the title of which begins with "abstract class",
thereby strongly suggesting overrides. And starting out with the statement
that the implementation would be provided in a more derived class.

But in any case, I elaborated on why that method didn't work, as you
requested. Trust me, I'd already considered that before posting in the
first place.

In any case, once again, the question is:

How do you define an interface on an public abstract class, giving the
members less than public visibility, the implementation of which is provided
in the more derived class? Bonus for not requiring extra runtime
indirection, a call through the interface v-table should be enough.
 
B

Ben Voigt [C++ MVP]

And sorry for my abrupt tone. I appreciate your help. It's just that
everyone seems to rewrite my question to fit the answer. Also it's way late
and I need to go sleep.

TTYL.
 
P

Peter Duniho

Only the entire thread, the title of which begins with "abstract class",
thereby strongly suggesting overrides. And starting out with the
statement that the implementation would be provided in a more derived
class.

Sorry...I didn't realize that was still a question. Since you _can_
declare an interface method as "abstract", I'm not really clear on what
the problem is yet. Is it your assertion that even though you can declare
the interface method as abstract, you are not permitted to override it in
a derived class?

The only issue I ran into trying to do what it _appeared_ to me you were
trying to do was the protection level of the abstract method. Because the
interface requires everything to be public, you can't make the method
internal (or anything else for that matter). But you certainly can make
it abstract.

(But it turns out, you can't make it abstract and explicit at the same
time...my lightbulb finally goes on...see below)
[...]
In any case, once again, the question is:

How do you define an interface on an public abstract class, giving the
members less than public visibility, the implementation of which is
provided in the more derived class? Bonus for not requiring extra
runtime indirection, a call through the interface v-table should be
enough.

I think I finally see what your objection is. My apologies if I should
have seen this earlier, but I have to say your initial post was not at all
clear about what you were asking about, at least not to me (see my
previous comments about the compiler error you quoted versus what you're
actually asking about).

Anyway, I see that I get the CS0106 error when I try to combine abstract
and explicit interface implementation. The help topic for this error
reads, in part: "The abstract keyword is not allowed on an explicit
interface declaration because an explicit interface implementation can
never be overridden."

For what it's worth, I made the assumption that you could combine abstract
and an explicit interface declaration to do what you want. You even
seemed to reinforce this idea when you wrote "Why are only public
(implicit interface
implementation) and private (explicit implementation) allowed?" I haven't
found a way to use an explicit implementation at all, except when the
implementation is actually defined in the class declaring it (that is,
it's not virtual or abstract). Your statement seems to me to say that it
_is_ allowed, which is what got me confused.

Not that that really matters...more a point of reference in case you're at
all curious why it is I didn't get what you were trying to say.

So, to sum up:

* You can override an implicit interface definition, including an
abstract one
* You cannot override an explicit interface definition, and
* You cannot make an interface implementation anything except public
(whether that implementation is abstract or concrete, implicit or
explicit, green or yellow, whatever)

I'll ignore the first one, since that's something you _can_ do. :)

I don't fully understand the second one, and the third one would only make
sense to me if you had the option of overriding explicit interface
definitions. Since you can't, I would agree that it would be useful to be
able to at least modify the access of an implemented method of an
interface to match the protection level of the interface itself.

I can see why if the interface were public, for example, the
implementation would have to be public, but I'm at a loss to explain why
when the interface is internal, the implementation still needs to be
public.

In other words, at this point I think I finally see what you're
complaining about, and I don't have an answer. Maybe someone else does
(I'm actually a bit surprised that no one else has jumped in yet with a
good explanation of what's going on here).

Pete
 
J

Jon Skeet [C# MVP]

Guess you missed this in my earlier post: "the nested class
itself is publicly visible, ala list::iterator, but carries data only
meaningful to the enclosing class."

If it only carries data meaningful to the enclosing class then why
have you made it public?

Jon
 
J

Jon Skeet [C# MVP]

On Jun 12, 7:43 am, "Ben Voigt [C++ MVP]"
I mean that when you use inheritance, it's not an
implementation detail. It's a part of the public interface.

Right - yes indeed. I hope you can see why I was confused!

Maybe it's just because I haven't done much C++, but it feels to me
like that's only natural. Is making it an implementation detail a
common concept outside C++?

I tend to prefer composition over inheritance anyway, which may be why
I've never felt it to be a problem.

Jon
 
P

Peter Duniho

If it only carries data meaningful to the enclosing class then why
have you made it public?

I think he means _some_ of the data it carries is meaningful only to the
enclosing class. Presumably the class itself is public for a good reason.

I got the impression he went to bed (which is where I should be going
too), so you'll have to wait until tomorrow to find out if I'm right. :)

Pete
 
P

Peter Duniho

On Jun 12, 7:43 am, "Ben Voigt [C++ MVP]"
I mean that when you use inheritance, it's not an
implementation detail. It's a part of the public interface.

Right - yes indeed. I hope you can see why I was confused!

Maybe it's just because I haven't done much C++, but it feels to me
like that's only natural. Is making it an implementation detail a
common concept outside C++?

At the risk of taking this thread away from the topic that Ben actually
wanted to talk about...

I'm unclear on the statement that "when you use inheritance, it's not an
implementation detail. It's a part of the public interface".

The way I read that, it's saying that in C#, inheritance is specifically
about defining the public methods a class exposes.

But I have to say, that's not the extent to which I use inheritance at
all, even in C#. You can inherit protected members, just as you can in
C++, and they provide the same benefit: an _implementation_ that is
reusable by the derived class. For that matter, private members may be
part of the inherited implementation as well.

So I'm confused about why inheritance is _not_ an implementation detail.

Since you both seem to agree on the point, maybe one of you can explain
what you're talking about to me. :)

Thanks,
Pete
 
J

Jon Skeet [C# MVP]

I think he means _some_ of the data it carries is meaningful only to the
enclosing class. Presumably the class itself is public for a good reason.

In that case, one obvious way round it is to keep the class private,
but implement a public interface exposing the members he wants to be
public. That keeps creation etc tightly within the confines of the
enclosing class, while keeping public things public.
I got the impression he went to bed (which is where I should be going
too), so you'll have to wait until tomorrow to find out if I'm right. :)

True.

Jon
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
In that case, one obvious way round it is to keep the class private,
but implement a public interface exposing the members he wants to be
public. That keeps creation etc tightly within the confines of the
enclosing class, while keeping public things public.

But you also end up with a runtime dynamic cast every time the client passes
said object back to you.
 
B

Ben Voigt [C++ MVP]

Peter Duniho said:
On Jun 12, 7:43 am, "Ben Voigt [C++ MVP]"
I mean that when you use inheritance, it's not an
implementation detail. It's a part of the public interface.

Right - yes indeed. I hope you can see why I was confused!

Maybe it's just because I haven't done much C++, but it feels to me
like that's only natural. Is making it an implementation detail a
common concept outside C++?

At the risk of taking this thread away from the topic that Ben actually
wanted to talk about...

I'm unclear on the statement that "when you use inheritance, it's not an
implementation detail. It's a part of the public interface".

The way I read that, it's saying that in C#, inheritance is specifically
about defining the public methods a class exposes.

But I have to say, that's not the extent to which I use inheritance at
all, even in C#. You can inherit protected members, just as you can in
C++, and they provide the same benefit: an _implementation_ that is
reusable by the derived class. For that matter, private members may be
part of the inherited implementation as well.

So I'm confused about why inheritance is _not_ an implementation detail.

Implementation details can be changed without any changes by the client.
Inheritance clearly breaks through encapsulation. You can't inherit from an
internal or otherwise visibility-restricted class, and therefore the client
can always use your class in ways that changes to inheritance would break.
 
J

Jon Skeet [C# MVP]

But you also end up with a runtime dynamic cast every time the client passes
said object back to you.

That's true - I hadn't considered the case where the object is passed
bi-directionally.

Jon
 
P

Peter Duniho

Implementation details can be changed without any changes by the client.
Inheritance clearly breaks through encapsulation. You can't inherit
from an
internal or otherwise visibility-restricted class, and therefore the
client
can always use your class in ways that changes to inheritance would
break.

Ahh...I see what you mean. I agree that's true. And in fact, I'll go one
further and point out that you can't even hide a public class as you
inherit it.

However, you can inherit from a class that has no public members, right?.
The interface issue aside (which I think I agree with you on), it is
possible to design a class that provides only functionality
(implementation details) but not a publicly accessible API (the methods
would be available only to the inheritor).

If you are dealing with a third-party class that you want to incorporate
without exposing to the client of your own class, I agree that's harder.
But as Jon says, there's always containment as an alternative to
inheritance.

I suppose C# could have included the access protection modifier in the
inheritance declaration portion of a class, as C++ does. There are in
fact a variety of things C++ allows that aren't possible or require
workarounds in C#. But I've just come to accept that these are design
decisions made with respect to simplifying the language. I can't say I
fully understand them, but I don't find them all that troublesome either.

What I do find troublesome is when I run across something in C# that _is_
very complicated and/or non-intuitive. It makes it a little harder to
just accept the other simplifications when C# does include things that can
easily cause even an experienced programmer to stumble.

Pete
 
C

Christof Nordiek

Ben Voigt said:
in message
Ok, but since the interface is internal, I should be allowed to:

public interface IInvocable
{
object Operation { get; }
}

internal interface IInvocableInternals : IInvocable
{
bool OperationValidate(string args);

string ProxiedOperation { get; }
}

public abstract class InvocableInternals : IInvocableInternals
{
internal abstract string ProxiedOperation { get; }
public object Operation { get { return ProxiedOperation; } }
}

The Method ProxiedOperation in InvocableInternals is not accepted as
implementation of ProxiedOperation of IInvocable, because it's neither
public nor an explicit interface implementation.
You could try following

public abstract class InvocableInternals: IInvocableInternals
{
string IInvocableInternals.ProxiedOperation{get {return
ProxiedOperation;}}

internal abstract string ProxiedOperation {get;}

......
}

hth
Christof
 
C

Christof Nordiek

Jon Skeet said:
However, that wouldn't solve your problem here - because interface
members are themselves implicitly public, so all the implementations
have to be public. It's very odd that the interface being internal
doesn't make all its members internal too.
If the interface is public, all it's implemantations have to be public. But
if the interface is internal, the implementation of it's members remain
internal if they are implemented implicitly.

But yes, an extention of the interface mapping rules, such that members of
an internal interface can map on internal members may be usefull.

Christof
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top