Shouldn't private methods be virtual too?

Robert Fraser fraserofthenight at gmail.com
Tue Jun 10 20:21:46 PDT 2008


Michel Fortin wrote:
> On 2008-06-10 19:02:13 -0400, Robert Fraser <fraserofthenight at gmail.com> 
> said:
> 
>>> Making Base's method public or protected changes the output to 
>>> "Derived.foo" as I'd expect.
>>
>> I agree, but last time I asked this it seemed like an unwinnable 
>> battle (everyone else said private should imply "final"). More 
>> controversial was whether "package" should imply "final" (which it 
>> does now, but I think it should not).
> 
> Ok, so we're two to think protection attributes should be orthogonal 
> with the final attribute of a member function, although I can't say I'm 
> strongly in favor of one or the other.
> 
> Package and private are pretty much the same thing: one makes the 
> function accessible to the current module only, the other makes the 
> function accessible to the current package only. If one has the side 
> effect of making the function final, then the other should too if we are 
> to preserve consistency.

I've thought a lot about this issue, and I believe you're right they 
/should/ be consistent here -- a "package" is a limited set of modules 
controlled (supposedly) by one programmer or a small team, so API 
changes aren't a deal here.

However, if there's going to be some nonsensical restriction that 
"private" implies "final" making "package" imply "final" is simply too 
strong of a restriction. There's often times you want to expose a method 
within a package for convenience, but don't want it to be part of the 
public API. Since most class overriding takes place within a package, 
restricting there's enough of a need for virtual package function to 
justify the inconsistency.

I'd rather make it so that the concepts were orthogonal , though.

> As a side note, it's pretty amusing to see that even this compiles 
> perfectly fine:
> 
>     class Base {
>         final package void foo() { writefln("Base.foo"); }
>     }
> 
>     class Derived : Base {
>         override final package void foo() { writefln("Derived.foo"); }
>     }
> 
> In Functions[1], it is said that "Functions marked as final may not be 
> overridden in a derived class, unless they are also private", so I take 
> it to mean that it is correct to override a final private function in 
> derived class, and by extension this is true for package functions too, 
> and thus, there are no bugs here. Funny, isnt' it?
> 
> [1]: http://www.digitalmars.com/d/2.0/function.html

Java figured out perfectly good semantics for package-protection years 
ago. Having "protected" and "private" accessible within the same module 
throws a wrench into it (i.e. we can't totally copy it), but why we need 
to tie concepts lie protection and virtuality together is beyond me.



More information about the Digitalmars-d mailing list