Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use a class declared in Implementation section from Interface section

If I understand correctly, the interface section is visible to other units, and the implementation section is visible only in the current .pas file.

I have two classes, class TA should be visible to the outside, other class TB should not, but I need a field of type TB in TA.

interface
    
type
  TA = class
    //something
    B : TB;
  end;
    
//something
    
implementation
    
type
  TB = class
    //something
  end;

It doesn't work like that. I also cannot use a forward declaration. Is there a way?

Or, is there a way to declare TB in the interface section but make it kind-of private?

like image 227
Bruice Avatar asked Mar 24 '21 22:03

Bruice


People also ask

Can an interface implement a class?

A class can implement more than one interface at a time. A class can extend only one class, but implement many interfaces. An interface can extend another interface, in a similar way as a class can extend another class.

Can a class implement an interface and extend a class?

Note: A class can extend a class and can implement any number of interfaces simultaneously.

CAN interface have implemented methods?

Interfaces are declared using the interface keyword, and may only contain method signature and constant declarations (variable declarations that are declared to be both static and final ). All methods of an Interface do not contain implementation (method bodies) as of all versions below Java 8.

Can multiple classes implement the same interface in Java?

A class can implement multiple interfaces and many classes can implement the same interface.


1 Answers

A type cannot be used before it is declared (in terms of line numbers). In particular, this means that you cannot use a type declared in the implementation section in the interface section.

However, consider the following example:

unit VisibilityTest;

interface

type
  TFrog = class
  strict private type
    TFrogMetabolism = class
      procedure DoAnabolismStuff;
      procedure DoCatabolismStuff;
    end;
  strict private
    FMetabolism: TFrogMetabolism;
  public
    procedure Croak;
    procedure Walk;
    procedure Jump;
  end;

implementation

{ TFrog.TFrogMetabolism }

procedure TFrog.TFrogMetabolism.DoAnabolismStuff;
begin

end;

procedure TFrog.TFrogMetabolism.DoCatabolismStuff;
begin

end;

{ TFrog }

procedure TFrog.Jump;
begin

end;

procedure TFrog.Croak;
begin

end;

procedure TFrog.Walk;
begin

end;

end.

Here the TFrog class is visible to other units, as well as its Croak, Walk, and Jump methods.

And it does have a (strict private in this example) field of type TFrogMetabolism, a type which can only be used inside TFrog -- and therefore only inside this unit -- because of the preceding strict private specification.

This should give you some ideas. A few variants are possible:

  • If you remove strict from strict private type, the TFrogMetabolism class can be used everywhere inside this particular unit, and not only in TFrog.

  • If you replace private with protected, the class can also be used in classes that aren't TFrog but are derived from TFrog.

like image 160
Andreas Rejbrand Avatar answered Sep 20 '22 10:09

Andreas Rejbrand