Skip to content

package-private method should not be overridable outside of the package #11339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TomasMikula opened this issue Apr 2, 2017 · 9 comments
Closed

Comments

@TomasMikula
Copy link

This compiles, even though filterImpl is declared private[scala] in TraversableLike.

abstract class MyIterable[A] extends Iterable[A] {
  override def filterImpl(p: A => Boolean, isFlipped: Boolean): MyIterable[A] = ???
}

Another problem is that I cannot have a (private) method of the same name and arguments as a package-private method without overriding the package-private method:

abstract class MyIterable[A] extends Iterable[A] {
  private def filterImpl(p: A => Boolean, isFlipped: Boolean): MyIterable[A] = ???
}
error: overriding method filterImpl in trait TraversableLike of type (p: A => Boolean, isFlipped: Boolean)Iterable[A];
 method filterImpl has weaker access privileges; it should not be private
         private def filterImpl(p: A => Boolean, isFlipped: Boolean): MyIterable[A] = ???
@som-snytt
Copy link

som-snytt commented Apr 3, 2017

Access and matching members for overriding are different. You can widen the access when overriding, just like in Java, pardon the expression.

#6794

@TomasMikula
Copy link
Author

"widen the access when overriding" is fine. The problem is that I can override something I shouldn't have access to in the first place.

@som-snytt
Copy link

Yup, that's the intuition expressed somewhere in the linked tickets.

The spec says http://www.scala-lang.org/files/archive/spec/2.12/05-classes-and-objects.html#overriding that the member you're overriding must have a narrower private[C], not that the member (super.m) must be accessible. Maybe it's a spec bug that the concepts are orthogonal. There, you made me say "orthogonal."

But if a member m is private[p], and you also define m without overriding, and a class in p invokes your x.m, then the second 'm' hijacks the signature through overloading. I think that's why access and overriding can't be conflated. It seems obvious that "my private method foo shouldn't affect subclasses, let me manage my namespace", but maybe a member is a member, and OOP implies a rather tight coupling.

@TomasMikula
Copy link
Author

The last paragraph would apply to private m as well (as opposed to private[p] m), but that works fine.

@som-snytt
Copy link

I think paulp complained about that and then changed it at some point.

@TomasMikula
Copy link
Author

As usual, I'm years behind @paulp.

@paulp
Copy link

paulp commented Apr 3, 2017

@TomasMikula I can maybe save you a little bit of time here: qualified private/protected have no chance whatsoever of ever working correctly.

@som-snytt
Copy link

@paulp has a way of cutting to the chase. Or to the quick.

@som-snytt
Copy link

The spec language in 5.2.1 "private" was changed in 2015 to clarify:

Class-private or object-private members may not be abstract, and may not have protected or override modifiers. They are not inherited by subclasses and they may not override definitions in parent classes.

issue 9321 at scala/scala@99fcdf7

There is also a mention in Scala 3 that they might just get rid of qualified private. Pun on "busted down to private".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants