Quote Originally Posted by chronozphere View Post
in java it is possible to expose methods/variables ONLY to the other classes in the package. In pascal this is possible too, with the restriction that all those classes must be defined within a single unit. It's that last requirement that I don't like. Would be nicer to bundle multiple units into packages and add some kind of "package wide private" access modifier.
In pascal it is possible to expose methods/variables ONLY to the other classes in the unit. In java this is possible too, with the restriction that all those classes must be defined within a single package. It's that last requirement that I don't like. Would be nicer to bundle multiple packages into units and add some kind of "unit wide private" access modifier.

Quote Originally Posted by chronozphere View Post
It's tempting for me to use interfaces, but as I'm using inheritance aswell, things get really complex. Imagine that there are classes Y and Z that are derived from X, each having extra methods that should only be called from either A or B. It means that I have to build multiple interface hierarchies. In the end, it just makes things really really complex, only for the sake of keeping some methods hidden.
It's not a good practice in general when a single class used by several clients completely differently. Seems that there should be two classes.

Quote Originally Posted by chronozphere View Post
@Mirage: Can you show me an example of aggregation? I've heard that word often, but I don't really know how it solves my problem. Thanks!
Sure. Aggregation is the same as composition:
Code:
type
 TA = class
    procedure P();
    procedure Q();
 end;

 TB = class
    procedure R();
    procedure S();
 end;

  TX = class()
  private
    FA: TA;
    FB: TB;
  public
    property ForA: TA read FA;
    property ForB: TB read FB;
  end;
Here two aggregated classes are used to serve different clients.
Methods can be called like this: X.ForA.P(), X.ForB.R(), etc.

Also you can aggregate the X class. Example with interface delegation which Delphi supports:

Code:
 type
  IXForA = interface
    procedure P();
    procedure Q();
  end;

  IXForB = interface
    procedure R();
    procedure S();
  end;

implementation

type
  TX = class
  private
    procedure P();
    procedure Q();
    procedure R();
    procedure S();
  end;

 TA = class(TInterfacedObject, IXForA)
 private
   FX: TX;
 public
   property X: TX read FX implements IXForA;
 end;

 TB = class(TInterfacedObject, IXForB)
 private
   FX: TX;
   property X: TX read FX implements IXForB;
 end;
This way methods can be called as A.P() where A: IXForA;

The both aggregation approaches can use or do not use interfaces and/or delegation.