Jump to content
aehimself

Reintroducing overloaded methods - is it possible?

Recommended Posts

I think the answer is no but maybe I just did not find the correct way - yet.

 

Imagine the following:

TBase = Class
public
 Var1: String;
 Class Function New(inJSONString: String): TBase; Overload; Virtual;
 Class Function New(inVar1: String): TBase; Overload; Virtual;
End;

TChild = Class(TBase)
public
 Var2: Integer;
 Class Function New(inJSONString: String): TChild; ReIntroduce; Overload;
 Class Function New(inVar1: String; inVar2: Integer): TChild; ReIntroduce; Overload;
End;

When I type TChild.New, all four variants are accessible. So the question is: is it possible to completely reintroduce the base classes all overloaded methods, so in the child only the newly declared are accessible?

Share this post


Link to post
On 12/31/2019 at 12:15 PM, Stefan Glienke said:

That code would not even compile as the two New overloads in TBase don't differ from each other parameter wise.

Did not pay enough attention when writing the example 🙂 Let me correct myself:

TBase = Class
public
 Var1: Integer;
 Class Function New(inJSONString: String): TBase; Overload; Virtual;
 Class Function New(inVar1: Integer): TBase; Overload; Virtual;
End;

TChild = Class(TBase)
public
 Var2: String;
 Class Function New(inJSONString: String): TChild; ReIntroduce; Overload;
 Class Function New(inVar1: Integer; inVar2: String): TChild; ReIntroduce; Overload;
End;

Share this post


Link to post

you won't see the 4 overloads from a 2nd unit, only from this one where the classes are declared

 

Ah everything is Public. You can't hide it.

Edited by Attila Kovacs

Share this post


Link to post

Yes, that was my fear too. Solution is rather easy though - don't use overloads 🙂 I started to experiment and came to the realization that Self can be used in a class function / procedure. It only won't reference an instance, only the class of the calling object - even if it is a child. The below works perfectly:

TBase = Class
strict protected
 Function GetAsJSON: String; Virtual;
 Procedure SetAsJSON(inJSONString: String); Virtual;
public
 Var1: Integer;
 Class Function New(inJSONString: String): TBase;
 Class Function New2(inInteger: Integer): TBase; Virtual;
 Property AsJSON: String Read GetAsJSON Write SetAsJSON;
End;

TChild = Class(TBase)
strict protected
 Function GetAsJSON: String; Override;
 Procedure SetAsJSON(inJSONString: String); Override;
public
 Var2: String;
 Class Function New2(inInteger: Integer; inString: String): TChild; ReIntroduce;
End;

//

Class Function TBase.New(inJSONString: String): TBase;
Begin
 Result := Self.Create;
 Result.AsJSON := inJSONString;
End;

Class Function TBase.New2(inInteger: Integer): TBase;
Begin
 Result := Self.Create;
 Result.Var1 := inInteger;
End;

Class Function TChild.New2(inInteger: Integer; inString: String): TChild;
Begin
 Result := TChild(inherited New2(inInteger));
 Result.Var2 := inString;
End;

I don't like that there are two "New" methods now, but it feels a lot more clean.

Share this post


Link to post

What if you create a TBaseBase with protected overloaded methods and public in TBase(TBaseBase) TChild(TBaseBase)

or TBase with protecdted overloaded methods and public in TBaseExposed(TBase) and TChild(TBase) ?

 

Or you go from New() to .FromJSON(JSON: string): TMyClass and .FromInteger(I: integer): TMyClass?

 

Or creating records with Implicit operators for string and integer/whatever, then you could write Child := '{somejson}'; or Child := 1; (did I go too far?:)

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×