www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2538] New: Private inheritance doesn't work for interfaces

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538

           Summary: Private inheritance doesn't work for interfaces
           Product: D
           Version: 2.022
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: 2korden gmail.com


Whenever I inherit from interface privately, compiler rises an error that
inherited abstract methods are not implemented:

module test;

interface NetworkListener
{
    void onConnect();
}

class SoundManager : private NetworkListener
{
    private final void onConnect()
    {
    }
}

test.d(8): class test.SoundManager interface function NetworkListener.onConnect
isn't implemented

I use private inheritance because I don't want my classes to be used as
listeners by anyone but the class itself (or module it is declared in). Use
case: it is an implementation detail that SoundManager is also a
NetworkListener (because I allow tuning sounds from authoring tool via debug
connection).

Both DMD1.x and DMD2.x are affected.


-- 
Dec 22 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538


2korden gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Private inheritance doesn't |Private inteface method
                   |work for interfaces         |implementation is not
                   |                            |considered a valid





I was a bit wrong. Marking a method final is a cause of a problem, not the
private inheritance itself.


-- 
Dec 22 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID





A "final private" method is not virtual, and hence won't work for an interface
method. That's why the error message appears. You can make it an enhancement
request if you like.


-- 
Dec 25 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538


2korden gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement
             Status|RESOLVED                    |REOPENED
           Keywords|rejects-valid               |
         Resolution|INVALID                     |
            Summary|Private inteface method     |Final method is not involved
                   |implementation is not       |in inteface method
                   |considered a valid          |resolution





Yes, I would.


-- 
Dec 25 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538


2korden gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |DUPLICATE







*** This bug has been marked as a duplicate of 2524 ***


-- 
Jan 20 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538


smjg iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com





See issue 2524 comment 8.  However, this brings us back to the problem of
inheritance protection, previously brought up in issue 177 and issue 2563.  We
already have why it doesn't make sense for classes in D; it doesn't make sense
for interfaces for a different reason.  The point of private inheritance is to
implement an "implemented in terms of" relationship, but interfaces contain no
implementation.  So the "implementing" class would gain nothing over not
implementing the interface at all.  I think the same would apply to protected
inheritance....


-- 
Jan 20 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538







 See issue 2524 comment 8.  However, this brings us back to the problem of
 inheritance protection, previously brought up in issue 177 and issue 2563.  We
 already have why it doesn't make sense for classes in D; it doesn't make sense
 for interfaces for a different reason.  The point of private inheritance is to
 implement an "implemented in terms of" relationship, but interfaces contain no
 implementation.  So the "implementing" class would gain nothing over not
 implementing the interface at all.  I think the same would apply to protected
 inheritance....
 
My interpretation of the spec is that private methods are never virtual and never go into a vtable. As stated by the spec the exact set of functions that are virtual are: "All non-static non-private non-template member functions are virtual" It is impossible for a static, template, or private function to be virtual, which means it cannot be in a vtable. final methods can be virtual (meaning they are in a vtable), they just cannot be overridden. I would propose that it should be an error to implement an interface with private protection. It makes no sense, as an interface is used where you do not know the implementation, but a private symbol can only be used in the file it's declared in, so you *should* know the implementation by looking at the file. --
Jan 20 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538







 I would propose that it should be an error to implement an interface with
 private protection.  It makes no sense, as an interface is used where you do
 not know the implementation, but a private symbol can only be used in the file
 it's declared in, so you *should* know the implementation by looking at the
 file.
 
Maybe it doesn't make sense to you, but it certainly does to me (see my examples). I believe I've brought enough examples where private and package methods are desired to have polymorphic behavior. --
Jan 20 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538






Your examples can be implemented using other means.  See my responses in Bug
2524.  What you are asking for is runtime protection checking.


-- 
Jan 20 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538


maxmo pochta.ru changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
           Priority|P2                          |P5
         Resolution|DUPLICATE                   |





I think, purpose of private interface implementation was well described. D is
just not aimed at fanatical incapsulation and everyone failing to
overincapsulate his code is advised to give it up and make everything public.
This won't wreak much havoc after all :)
Marking this as low-priority RFE.


-- 
Jan 22 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2538






Workaround:
---
module Test;

interface NetworkListener
{
    void onConnect();
}

class SoundManager : private NetworkListener
{
    protected final void onConnect()
    {
    }
}

void main()
{
        auto a=new SoundManager();
        auto b=cast(NetworkListener)a;
        b.onConnect();
}
---


-- 
Jan 22 2009