method returning child, doesn't overrides declared method returning parent

Steven Schveighoffer schveiguy at yahoo.com
Tue Aug 30 10:50:34 PDT 2011


On Tue, 30 Aug 2011 13:39:35 -0400, Timon Gehr <timon.gehr at gmx.ch> wrote:

> On 08/30/2011 07:16 PM, Steven Schveighoffer wrote:
>> On Tue, 30 Aug 2011 13:06:02 -0400, Timon Gehr <timon.gehr at gmx.ch>  
>> wrote:
>>
>>> On 08/30/2011 06:43 PM, Steven Schveighoffer wrote:
>>>> On Tue, 30 Aug 2011 12:29:59 -0400, Andrei Alexandrescu
>>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>>
>>>>> On 8/30/11 11:06 AM, Steven Schveighoffer wrote:
>>>>>> When I write code that derives from a base class, I'm declaring with
>>>>>> override that I want to implement the base class' function.
>>>>>> When I write code that implements an interface, I'm declaring with
>>>>>> override that I want to implement the interface's function.
>>>>>
>>>>> From the cycle "deadpan answers": I think one should use "override"
>>>>> when one wants to override.
>>>>
>>>> Then your description of cases where override helps prevent bugs  
>>>> should
>>>> reflect that:
>>>>
>>>> (a) User thinks she overrides a specific method but instead  
>>>> introduces a
>>>> new one.
>>>>
>>>> (b) User thinks she introduces a new method but instead overrides one.
>>>>
>>>> I consider implementing an interface method to be hooking, since you  
>>>> are
>>>> hooking calls from said interface.
>>>>
>>>> I guess if we want to avoid solving all hooking problems, even those
>>>> where one does not intend to implement an interface, but accidentally
>>>> does, or introduce large annoyances where someone changes a widely  
>>>> used
>>>> interface to an abstract class, then I guess the status quo is good.
>>>>
>>>> -Steve
>>>
>>> I don't think that you can change a widely used interface into an
>>> abstract class and not introduce annoyances much larger than override
>>> is capable of creating.
>>
>> interface I
>> {
>> int foo();
>> void bar();
>> }
>>
>> ->
>>
>> interface _I
>> {
>> int foo();
>> void bar();
>> }
>>
>> abstract class I : _I
>> {
>> int foo() { return 0; }
>> }
>>
>> Now, everywhere I was implemented before has to change all their
>> implementations of foo() to override, just to compile.
>>
>> There may be some cases where classes already had a base class, but it
>> depends on the context of where I is implemented.
>
> That is what I meant.

I know.  What I'm saying is it's feasible for the nature of an interface  
to be such that you don't have inheritance chains of more than one class.   
Typically a change like this is done for entire libraries where one person  
is in control of all the implementing classes, and the author knows the  
interface to abstract class change will not be a burden.

Technically, the problems created would make such a change not feasible,  
not just annoying.  I'm talking about cases where it is feasible.

>>
>> My point is, what "bug" is it preventing by rejecting override when
>> implementing an interface? The only "bug" I see is that you didn't put
>> override in the signature. That translates to an annoyance, not a real  
>> bug.
>
> This one:
>
> interface I{
>      void method1();
>      void method2();
>      void method3();
> }
>
> class C: I{
>      override void method1(){ ... }
>      override void method2(){ ... }
>      override void method3(){ ... }
> }
>
> => // refactoring implementations of I in C to abstract class D
>
> interface I{
>      void method1();
>      void method2();
>      void method3();
> }
>
> abstract class D: I{
>      override void method1(){ ... }
>      override void method2(){ ... }
>      override void method3(){ ... }
> }
>
> class C: D{
>      // left method2() inside class C by accident
>      override void method2(){ ... } // override makes compiler shut up
> }

We could find cases like this all day.

Make I a class, and this problem also occurs.

Without the compiler having access to the *changes* it cannot be perfect  
in detecting refactoring errors.

-Steve


More information about the Digitalmars-d mailing list