Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference with these two sets of code [closed]

What is the difference between these two pieces of code

type
  IInterface1 = interface
    procedure Proc1;
  end;

  IInterface2 = interface
    procedure Proc2;
  end;

  TMyClass = class(TInterfacedObject, IInterface1, IInterface2)
  protected
    procedure Proc1;
    procedure Proc2;
  end;

And the following :

type
  IInterface1 = interface
    procedure Proc1;
  end;

  IInterface2 = interface(Interface1)
    procedure Proc2;
  end;

  TMyClass = class(TInterfacedObject,  IInterface2)
  protected
    procedure Proc1;
    procedure Proc2;
  end;

If they are one and the same, are there any advantages, or readability issues with either.

I guess the second means you cannot write a class that implements IInterface2 without implementing IInterface1, whilst with the first you can.

like image 912
Steve Avatar asked Dec 18 '22 10:12

Steve


2 Answers

The two snippets of code have very different effects, and are in almost no way equivalent, if we are talking about Delphi for Win32 (Delphi for .NET has different rules).

  1. A class that implements its interface must implement all the members of that interface's ancestors, but it does not implicitly implement the ancestors. Thus, attempts to assign instances of type TMyClass to locations of type IInterface1 will fail for the second case.
  2. Related to the previous point, if IInterface1 and IInterface2 both had GUIDs, dynamic casts (using Supports or 'as') of interface references with a target type of IInterface1 would fail on instances of TMyClass in the second case.
  3. The interface IInterface2 has an extra method in the second case, which it does not in the first.
  4. Values of type IInterface2 in the second case are assignable to locations of type IInterface1; this is not true for the first case.

See for yourself in this example:

    type
      A_I1 = interface
      end;

      A_I2 = interface(A_I1)
      end;

      A_Class = class(TInterfacedObject, A_I2)
      end;

    procedure TestA;
    var
      a: A_Class;
      x: A_I1;
    begin
      a := A_Class.Create;
      x := a; // fails!
    end;

    type
      B_I1 = interface
      end;

      B_I2 = interface
      end;

      B_Class = class(TInterfacedObject, B_I1, B_I2)
      end;

    procedure TestB;
    var
      a: B_Class;
      x: B_I1;
    begin
      a := B_Class.Create;
      x := a; // succeeds!
    end;

    begin
      TestA;
      TestB;
    end.
like image 102
Barry Kelly Avatar answered Dec 24 '22 00:12

Barry Kelly


First off, I'm assuming that the second example's declaration for IInterface2 is a typo and should be

IInterface2 = interface(Interface1)

because inheriting from itself is nonsensical (even if the compiler accepted it).

And "inheriting" is the key word there for answering your question. In example 1 the two interfaces are completely independent and you can implement one, the other, or both without problems. In example 2, you are correct that you can't implement interface2 without also implementing interface1, but the reason why that's so is because it makes interface1 a part of interface2.

The difference, then, is primarily structural and organizational, not just readability.

like image 39
Dave Sherohman Avatar answered Dec 24 '22 02:12

Dave Sherohman