Jump to page: 1 2
Thread overview
[Issue 2524] New: final override inconsistent when implementing interfaces
Dec 18, 2008
d-bugmail
Dec 19, 2008
d-bugmail
Jan 01, 2009
d-bugmail
Jan 19, 2009
d-bugmail
Jan 20, 2009
d-bugmail
Jan 20, 2009
d-bugmail
Jan 20, 2009
d-bugmail
Jan 20, 2009
d-bugmail
Jan 20, 2009
d-bugmail
Jan 20, 2009
d-bugmail
Jan 20, 2009
d-bugmail
Jan 21, 2009
d-bugmail
Jan 21, 2009
d-bugmail
Jan 21, 2009
d-bugmail
Jan 21, 2009
d-bugmail
Jan 23, 2012
Walter Bright
Jan 23, 2012
Walter Bright
December 18, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2524

           Summary: final override inconsistent when implementing interfaces
           Product: D
           Version: 1.038
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid, spec
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: schveiguy@yahoo.com


The following code builds:

interface I
{
  void foo();
}

class C : I
{
  override void foo();
}

But the following does not work:

class C : I
{
  final override void foo();
}

testfinaloverride.d(8): function testfinaloverride.C.foo does not override any
function

The two cases should be consistent.  The spec is unclear to me as to whether implementing an interface function qualifies as overriding a function or not.

I would vote for the case where override requires either to override a base class function or implement an interface function, since it is a pain if you change a base class to an interface, you'd have to remove all the override keywords.  So I'm marking it as rejects-valid.

The spec should also specifically lay out what override does in the case of interfaces.


-- 

December 19, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #1 from maxmo@pochta.ru  2008-12-19 03:27 -------
It compiles in D2, though silent interface method implementation looks strange for me.


-- 

January 01, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524


burton-radons@shaw.ca changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |burton-radons@shaw.ca




------- Comment #2 from burton-radons@shaw.ca  2009-01-01 10:57 -------
(In reply to comment #1)
> It compiles in D2, though silent interface method implementation looks strange for me.

I've tested this with DMD 2.022 and 2.021 and I get this error in both cases.


-- 

January 19, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524


schveiguy@yahoo.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |samukha@voliacable.com




------- Comment #3 from schveiguy@yahoo.com  2009-01-19 11:31 -------
*** Bug 2593 has been marked as a duplicate of this bug. ***


-- 

January 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #4 from 2korden@gmail.com  2009-01-20 02:59 -------
My report is also a duplicate of this bug.
Note that Walter closed it with the following comment:

«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.»


-- 

January 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524


2korden@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |2korden@gmail.com




------- Comment #5 from 2korden@gmail.com  2009-01-20 02:59 -------
*** Bug 2538 has been marked as a duplicate of this bug. ***


-- 

January 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #6 from samukha@voliacable.com  2009-01-20 04:55 -------
I don't think #2538 is a duplicate of this. It's the "private" part of "final private" that makes the method non-virtual. Implementing interface methods with final methods is absolutely legal.


-- 

January 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #7 from schveiguy@yahoo.com  2009-01-20 11:09 -------
In fact, private implies final (non-virtual), and does not put the function in the vtable (meaning it cannot override a base function).  From the spec: "All non-static non-private non-template member functions are virtual."  If someone casts your class to an interface, do you want them to now be able to call your private function?


-- 

January 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #8 from smjg@iname.com  2009-01-20 12:25 -------
(In reply to comment #7)
> In fact, private implies final (non-virtual), and does not put the function in the vtable (meaning it cannot override a base function).  From the spec: "All non-static non-private non-template member functions are virtual."

The sentence you've quoted states nothing about functions that _are_ private.

Moreover, a final method _can_ override a method in a base class.  Even so, an interface has its own vtable, so the virtuality or not of a function with respect to its class (or a class from which it is derived) should have nothing to do with whether it can implement an interface method.

> If someone casts your class to an interface, do you want them to now be able to call your private function?

Probably not.  But the way it's attempted in issue 2538 brings us back to the problem of inheritance protection.  But we can talk about this there.


-- 

January 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #9 from 2korden@gmail.com  2009-01-20 16:40 -------
(In reply to comment #7)
> In fact, private implies final (non-virtual), and does not put the function in
> the vtable (meaning it cannot override a base function).

Protection should be orthogonal to "virtuality" attributes. Here is an example:

class A
{
    private void foo() {
        writefln("A.foo");
    }
}

class B : A
{
    private override void foo() {
        super.foo();
        writefln("B.foo");
    }
}


> From the spec: "All non-static non-private non-template member functions are virtual."

I believe this is a design flow. Same as "package implies final".

> If someone casts your class to an interface, do you want them to now be able to call your private function?
> 

Of course, why would you inherit or override it other than to allow virtual behavior? Here is an example:

interface INetworkListener {
    void acceptNetworkPacket();
}

class NetworkManager
{
    static void registerNetworkListener(INetworkListener listener) { ... }
}

class SoundManager : private INetworkListener
{
    this() {
        NetworkManager.registerNetworkListener(this);
    }

    private void acceptNetworkPacket() {
        // ...
    }
}

No-one should know that SoundManager implements INetworkListener interface. Since "acceptNetworkPacket" method is an implementation detail, I don't want it to be visible from the outside of this class (to prevent accidential invokation). Thus I mark it private.

Note that private interface inheritance is harmless as it doesn't shadow Object's methods (opCmp, opEquals, toString etc).


-- 

« First   ‹ Prev
1 2