BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
What do Delphi and other compilers do?
At first sight, I'd rather forbid this in GPC (as usual, with an exception in `--borland-pascal', but perhaps a warning even there?).
program Foo;
type a = object procedure p; end;
b = object (a) private procedure p; { ??? } end;
procedure a.p; begin end;
procedure b.p; begin end;
begin end.
Oh, wait a second, it gets really strange ...
unit U;
interface
type a = object procedure p; end;
b = object (a) private procedure p; end;
implementation
procedure a.p; begin WriteLn ('a.p') end;
procedure b.p; begin WriteLn ('b.p') end;
var v: b;
begin v.p end.
program Foo;
uses U;
var v: b;
begin v.p end.
Under BP, this says:
b.p a.p
What does it mean actually? It means that `b' has *two* methods called `p'. Within the unit, one of them shadows the other, and outside of the unit, the first one is hidden (or non-existent because not exported), and the second one becomes visible. That's crazy, isn't it?
Frank
Frank Heckenbach wrote:
BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
Only if the privacy degree of the overriding method is _lower_ than that of the the overridden one. E.g. the following declaration would make sense due to the principles of OO programming:
type
a = object protected procedure p; virtual; end;
b = object (a) public procedure p; virtual; end;
The other way around -- making a method "more private" -- would contradict the principle of polymorphy.
Yours,
Markus
Markus Gerwinski wrote:
Frank Heckenbach wrote:
BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
Only if the privacy degree of the overriding method is _lower_ than that of the the overridden one. E.g. the following declaration would make sense due to the principles of OO programming:
type
a = object protected procedure p; virtual; end; b = object (a) public procedure p; virtual; end;
The other way around -- making a method "more private" -- would contradict the principle of polymorphy.
I agree. (markus9.pas)
Frank
Frank Heckenbach wrote:
Markus Gerwinski wrote:
Frank Heckenbach wrote:
BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
Only if the privacy degree of the overriding method is _lower_ than that of the the overridden one. E.g. the following declaration would make sense due to the principles of OO programming:
type
a = object protected procedure p; virtual; end; b = object (a) public procedure p; virtual; end;
The other way around -- making a method "more private" -- would contradict the principle of polymorphy.
I agree. (markus9.pas)
Both ways make some sense. "Normal" way is to extend the interface (so making a method public looks more natural). However, to support encapsulation one may create a "view", where only some method are visible. BP may be misguided here, but ability to make method private sometimes may do as substitute for views. Limiting visibility have nothing to do with polymorphy -- the method still have to be in VMT, but may called only where static type (= interface) allows.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Markus Gerwinski wrote:
Frank Heckenbach wrote:
BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
Only if the privacy degree of the overriding method is _lower_ than that of the the overridden one. E.g. the following declaration would make sense due to the principles of OO programming:
type
a = object protected procedure p; virtual; end; b = object (a) public procedure p; virtual; end;
The other way around -- making a method "more private" -- would contradict the principle of polymorphy.
I agree. (markus9.pas)
Both ways make some sense. "Normal" way is to extend the interface (so making a method public looks more natural). However, to support encapsulation one may create a "view", where only some method are visible. BP may be misguided here, but ability to make method private sometimes may do as substitute for views. Limiting visibility have nothing to do with polymorphy -- the method still have to be in VMT, but may called only where static type (= interface) allows.
But such a "view" could easily be bypassed by passing the object (polymorphically) to a formal parameter of the parent type, so I don't see what it gains, apart from confusion. Or actually worse, since you'd allow a private method to be called from outside (without dirty tricks, just through the VMT in a "public" place).
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Both ways make some sense. "Normal" way is to extend the interface (so making a method public looks more natural). However, to support encapsulation one may create a "view", where only some method are visible. BP may be misguided here, but ability to make method private sometimes may do as substitute for views. Limiting visibility have nothing to do with polymorphy -- the method still have to be in VMT, but may called only where static type (= interface) allows.
But such a "view" could easily be bypassed by passing the object (polymorphically) to a formal parameter of the parent type, so I don't see what it gains, apart from confusion. Or actually worse, since you'd allow a private method to be called from outside (without dirty tricks, just through the VMT in a "public" place).
The same is true for real views (or restricted types). The point is that any code which is allowed to know parent type is allowed to call the method -- you restrict access to the method by restricting access to the parent. In EP modules you may export only child, so only dirty tricks will get you at the parent. And even if not strictly enforced making method provate still serves as documentation and catches some mistakes. In short -- I think that there are good reasons to turn public method into privete method. If (when) we implement Object Pascal views we will have better apporach, but it still may be good idea to remain BP compatible.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Both ways make some sense. "Normal" way is to extend the interface (so making a method public looks more natural). However, to support encapsulation one may create a "view", where only some method are visible. BP may be misguided here, but ability to make method private sometimes may do as substitute for views. Limiting visibility have nothing to do with polymorphy -- the method still have to be in VMT, but may called only where static type (= interface) allows.
But such a "view" could easily be bypassed by passing the object (polymorphically) to a formal parameter of the parent type, so I don't see what it gains, apart from confusion. Or actually worse, since you'd allow a private method to be called from outside (without dirty tricks, just through the VMT in a "public" place).
The same is true for real views (or restricted types). The point is that any code which is allowed to know parent type is allowed to call the method -- you restrict access to the method by restricting access to the parent. In EP modules you may export only child, so only dirty tricks will get you at the parent.
Then there's no point making the parent method public in the first place.
And even if not strictly enforced making method provate still serves as documentation and catches some mistakes. In short -- I think that there are good reasons to turn public method into privete method. If (when) we implement Object Pascal views we will have better apporach, but it still may be good idea to remain BP compatible.
BP compatible? Including the strangeness of an object having two methods of the same name (not as parent methods, but in the same type, see original mail)?
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Both ways make some sense. "Normal" way is to extend the interface (so making a method public looks more natural). However, to support encapsulation one may create a "view", where only some method are visible. BP may be misguided here, but ability to make method private sometimes may do as substitute for views. Limiting visibility have nothing to do with polymorphy -- the method still have to be in VMT, but may called only where static type (= interface) allows.
But such a "view" could easily be bypassed by passing the object (polymorphically) to a formal parameter of the parent type, so I don't see what it gains, apart from confusion. Or actually worse, since you'd allow a private method to be called from outside (without dirty tricks, just through the VMT in a "public" place).
The same is true for real views (or restricted types). The point is that any code which is allowed to know parent type is allowed to call the method -- you restrict access to the method by restricting access to the parent. In EP modules you may export only child, so only dirty tricks will get you at the parent.
Then there's no point making the parent method public in the first place.
Consider: A - public B(A) - private C(B) - public "view"
And even if not strictly enforced making method provate still serves as documentation and catches some mistakes. In short -- I think that there are good reasons to turn public method into privete method. If (when) we implement Object Pascal views we will have better apporach, but it still may be good idea to remain BP compatible.
BP compatible? Including the strangeness of an object having two methods of the same name (not as parent methods, but in the same type, see original mail)?
Well, BP behaviour is crazy. AFAIKS they just do not export private methods. IMHO correct (and more useful) is to export the method as private so an attempt to call it produces diagnostic. I wonder what BP does if a method is virtual? Do they just ignore `private'?
Now, feature that behaves differently depending on dialect should be avoided, so I agree with you -- it is better to give error message at definition time by default.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Both ways make some sense. "Normal" way is to extend the interface (so making a method public looks more natural). However, to support encapsulation one may create a "view", where only some method are visible. BP may be misguided here, but ability to make method private sometimes may do as substitute for views. Limiting visibility have nothing to do with polymorphy -- the method still have to be in VMT, but may called only where static type (= interface) allows.
But such a "view" could easily be bypassed by passing the object (polymorphically) to a formal parameter of the parent type, so I don't see what it gains, apart from confusion. Or actually worse, since you'd allow a private method to be called from outside (without dirty tricks, just through the VMT in a "public" place).
The same is true for real views (or restricted types). The point is that any code which is allowed to know parent type is allowed to call the method -- you restrict access to the method by restricting access to the parent. In EP modules you may export only child, so only dirty tricks will get you at the parent.
Then there's no point making the parent method public in the first place.
Consider: A - public B(A) - private C(B) - public "view"
Still, what's the point in declaring A's method public if you don't export A?
I agree that (real) views can be useful, but IMHO they don't fit well into the BP model. They may require to go through a parent type in order to access certain feature, which is never required otherwise in BP.
(Of course, when we later add views as part of OOE, it may be possible that they can be combined with BP objects, but this would be an explicit mixture of dialects, whereas in this example we're on pure BP syntax with (as it seems) unintended strange effects.)
And even if not strictly enforced making method provate still serves as documentation and catches some mistakes. In short -- I think that there are good reasons to turn public method into privete method. If (when) we implement Object Pascal views we will have better apporach, but it still may be good idea to remain BP compatible.
BP compatible? Including the strangeness of an object having two methods of the same name (not as parent methods, but in the same type, see original mail)?
Well, BP behaviour is crazy. AFAIKS they just do not export private methods. IMHO correct (and more useful) is to export the method as private so an attempt to call it produces diagnostic.
Yes, that's what GPC does.
I wonder what BP does if a method is virtual? Do they just ignore `private'?
Seems so. This code says `b.p' twice:
unit U;
interface
type a = object constructor c; procedure p; virtual; end;
b = object (a) private procedure p; virtual; end;
implementation
constructor a.c; begin end;
procedure a.p; begin WriteLn ('a.p') end;
procedure b.p; begin WriteLn ('b.p') end;
var v: b;
begin v.c; v.p end.
program Foo;
uses U;
var v: b;
begin v.c; v.p end.
Now, feature that behaves differently depending on dialect should be avoided, so I agree with you -- it is better to give error message at definition time by default.
Yes, I think it's better to leave the rest for (future) real view declarations.
Frank
Frank Heckenbach a écrit:
BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
What do Delphi and other compilers do?
At first sight, I'd rather forbid this in GPC (as usual, with an exception in `--borland-pascal', but perhaps a warning even there?).
program Foo;
type a = object procedure p; end;
b = object (a) private procedure p; { ??? } end;
procedure a.p; begin end;
procedure b.p; begin end;
begin end.
Oh, wait a second, it gets really strange ...
unit U;
interface
type a = object procedure p; end;
b = object (a) private procedure p; end;
implementation
procedure a.p; begin WriteLn ('a.p') end;
procedure b.p; begin WriteLn ('b.p') end;
var v: b;
begin v.p end.
program Foo;
uses U;
var v: b;
begin v.p end.
Under BP, this says:
b.p a.p
What does it mean actually? It means that `b' has *two* methods called `p'. Within the unit, one of them shadows the other, and outside of the unit, the first one is hidden (or non-existent because not exported), and the second one becomes visible. That's crazy, isn't it?
Yes. Try: ------------------------------ program Foo;
type a = object procedure p; end;
b = object (a) private procedure p; { ??? } end;
procedure a.p; begin writeln('a.p'); end;
procedure b.p; begin a.p; writeln('b.p'); end;
var va:a; vb:b;
begin va.p; vb.p; end. ------------------------
the answer (you can follow step by step) is
a.p a.p b.p
This has nothing to do with private. You obtain the same results when commenting out private.
The procedures are overriden only with the keyword "virtual". Otherwise they coexist and you can call either with prefixing.
In fact the behaviour is also the same with virtual, but you need to add constructors and call them, otherwise it compiles but you obtain a bad crash.
Now I just tried with gpc, with or without virtual, the behavior is exactly the same.
The only difference is that private is not taken into account by gpc now (I no more obtain a warning ? ), and this was probably your problem. Your original question was: is it wise to allow overriding private/public methods ? In such a case both methods can be called from inside the objects with prefixing, and only the public one can be called directly from the outside world. For me this seems only a source of confusion, but may be someone has an idea for an useful application ?
Maurice
Maurice Lombardi wrote:
Frank Heckenbach a écrit:
BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
What do Delphi and other compilers do?
At first sight, I'd rather forbid this in GPC (as usual, with an exception in `--borland-pascal', but perhaps a warning even there?).
program Foo;
type a = object procedure p; end;
b = object (a) private procedure p; { ??? } end;
procedure a.p; begin end;
procedure b.p; begin end;
begin end.
Oh, wait a second, it gets really strange ...
unit U;
interface
type a = object procedure p; end;
b = object (a) private procedure p; end;
implementation
procedure a.p; begin WriteLn ('a.p') end;
procedure b.p; begin WriteLn ('b.p') end;
var v: b;
begin v.p end.
program Foo;
uses U;
var v: b;
begin v.p end.
Under BP, this says:
b.p a.p
What does it mean actually? It means that `b' has *two* methods called `p'. Within the unit, one of them shadows the other, and outside of the unit, the first one is hidden (or non-existent because not exported), and the second one becomes visible. That's crazy, isn't it?
Yes. Try:
[...]
This has nothing to do with private. You obtain the same results when commenting out private. The procedures are overriden only with the keyword "virtual". Otherwise they coexist and you can call either with prefixing.
Yes, so that's something different. Please note that in my example both variables are of type `b', and no explicit parent method calling is done. It's exactly the same code in the program and the end of the unit (also semantically -- at least so it should --, since the type `b' which is used refers to the same type in the unit and the program).
So this isn't so much about inheritance, but about there being (apparently) different scopes for private and public methods in BP -- but not quite, since you still get an error if you define both in the same object type.
The only difference is that private is not taken into account by gpc now (I no more obtain a warning ? ),
`private' works on a unit/module/program scope (which is BP compatible, as you can check for yourself), that's why I made a unit in my test program. (It may be debatable if that's useful, but that's another issue -- it may be meant as a substitute for C++ `friend's or so ...)
Frank
On 22 Oct 2003 at 13:59, Frank Heckenbach wrote:
BP seems to allow overriding a public method with a private one (and vice versa). Does this seem reasonable?
What do Delphi and other compilers do?
Same as BP.
[...]
Under BP, this says:
b.p a.p
Same result from Delphi (up to version 7.0), Virtual Pascal, Free Pascal, and TMT Pascal.
What does it mean actually? It means that `b' has *two* methods called `p'. Within the unit, one of them shadows the other, and outside of the unit, the first one is hidden (or non-existent because not exported), and the second one becomes visible.
Seems so.
That's crazy, isn't it?
Not sure ...
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/