Thread overview
interfaces and the protected attribute
Dec 01, 2005
Kris
Dec 01, 2005
Sean Kelly
December 01, 2005
I've stumbled upon something that I'd like clarification upon: whether it's by design or not.

interface IWumpus
{
  int foo();
  int bar();
}

class Wombat : IWumpus
{
   int foo() {}
   protected int bar() {}  // note the protected attribute!
}

void main()
{
    Wombat wombat = new Wombat;

    wombat.foo();  // visible
    wombat.bar();  // not visible!

    IWumpus wumpus = wombat;
    wumpus.foo();  // visible
    wumpus.bar();  // visible
}

(these would probably need to be in different modules).

Anyway, I'm not entirely sure what to think about this behaviour. On the one hand it is really nice being able to limit exposure of the implementation. On the other hand, is it truly consistent? BTW: replacing protected with private causes an error ~ which tends to imply the feature is by design.

Regardless, I'm more than happy to leverage this useful facility ~ just need to know if it might be removed in the future?


December 01, 2005
Kris wrote:
> I've stumbled upon something that I'd like clarification upon: whether it's by design or not.
> 
> interface IWumpus
> {
>   int foo();
>   int bar();
> }
> 
> class Wombat : IWumpus
> {
>    int foo() {}
>    protected int bar() {}  // note the protected attribute!
> }
> 
> void main()
> {
>     Wombat wombat = new Wombat;
> 
>     wombat.foo();  // visible
>     wombat.bar();  // not visible!
> 
>     IWumpus wumpus = wombat;
>     wumpus.foo();  // visible
>     wumpus.bar();  // visible
> }
> 
> (these would probably need to be in different modules).
> 
> Anyway, I'm not entirely sure what to think about this behaviour. On the one hand it is really nice being able to limit exposure of the implementation. On the other hand, is it truly consistent? BTW: replacing protected with private causes an error ~ which tends to imply the feature is by design.
> 
> Regardless, I'm more than happy to leverage this useful facility ~ just need to know if it might be removed in the future? 

It's consitent with C++ visibility rules, so I expect it will stay.  The alternative would be a somewhat odd consistency between inheriting from a class vs. implementing an interface.  ie.

class Marmoset
{
    void howl() {}
}

interface DuckbilledCritter
{
    void quack();
}

class Mongrel : Marmoset, DuckbilledCritter
{
protected:
    void quack() {}
    void howl() {}
}

It makes sense that overriding an inherited class method should be allowed to change visibility rules, so this is unlikely to change.  And while it's a tad odd that Mongrel's public interface doesn't contain a quack() method, I think it's better than treating the two situations differently.


Sean
December 02, 2005
Sean Kelly wrote:
> Kris wrote:
> 
>> I've stumbled upon something that I'd like clarification upon: whether it's by design or not.
> 
> It's consitent with C++ visibility rules, so I expect it will stay.  The alternative would be a somewhat odd consistency between inheriting from a class vs. implementing an interface.  ie.

WTF? C++ must be a bit brain dead then?

I though the protection attributes were designed to prevent the programmer from doing something bad. Overriding the method with stricter attributes should be a compile-time error. For example this code doesn't make any sense:

#module 1:

interface I { void foo(); }
class C : I { protected void foo() {} }

#module 2:

void func(I i) {
 i.foo();	// allowed

 C c = cast(C) i;
 c.foo();	// not allowed
}

void func(C c) {
 c.foo();	// not allowed

 I i = c;
 i.foo();	// allowed
}

As you can see, overriding the protection doesn't have any effect.
December 05, 2005
Jari-Matti Mäkelä wrote:
> 
> WTF? C++ must be a bit brain dead then?
> 

Agreed. This is something that's broken in C++ and it would be great to fix this in D! The minimum visibility of members forms part of the contract of a class, and should hold for all objects of that class regardless of whereabouts in the type hiearachy they appear. This is fairly fundamental.

It would be really nice if we could fix this =)

Munch