Access to protected method m not permitted because prefix type A[T] does not conform to ...

1,232 views
Skip to first unread message

Eugen Labun

unread,
Mar 3, 2012, 10:56:41 AM3/3/12
to scala...@googlegroups.com
Hi All,

I got a strange error, here is a mininal REPL example:


scala> abstract class A[T] {protected def m: T}; class A1[T](a: A[T]) extends A[T] {def m = a.m}

<console>:9: error: method m in class A cannot be accessed in A[T]
Access to protected method m not permitted because
prefix type A[T] does not conform to
class A1 in object $iw where the access take place
abstract class A[T] {protected def m: T}; class A1[T](a: A[T]) extends A[T] {def m = a.m}
^

The same error also occurs when using compiler.

If ´m´ is declared public in the parent type, then everything is OK. But I should be able to access
protected members in a subclass, no?

May be, I'm missing something obvious?


Thank you,

EL

Eugen Labun

unread,
Mar 3, 2012, 11:05:47 AM3/3/12
to scala...@googlegroups.com
forgot to mention, Scala 2.9.1

Dave

unread,
Mar 3, 2012, 11:52:45 AM3/3/12
to scala-user
scala> abstract class A[T] {protected def m: T}; class A1[T](a:
A1[T]) extends
A[T] {def m = a.m}
defined class A
defined class A1

argument a must be the same as the enclosing class because of
security
argument a cannot be supertype A[T] otherwise an other subtype of A[T]
could have access to A1[T} to call m

Eugen Labun

unread,
Mar 3, 2012, 12:54:26 PM3/3/12
to scala...@googlegroups.com
Hi Dave,

yes, with a parameter of the same type it works, of course.
But, for my purposes, it must be the supertype.


Here is yet another, even more simple example with the same error:

scala> :paste
// Entering paste mode (ctrl-D to finish)

class A {
protected def m {}
}
class B extends A {
protected def n(a: A) {a.m}
}

// Exiting paste mode, now interpreting.

<console>:12: error: method m in class A cannot be accessed in A


Access to protected method m not permitted because

prefix type A does not conform to
class B where the access take place
protected def n(a: A) {a.m}
^


I also found this (closed - not a bug) ticket https://issues.scala-lang.org/browse/SI-1383
and a short thread ´Bug in implementation of "protected"?´
http://comments.gmane.org/gmane.comp.lang.scala.user/8247 (with an example much like my example from
the prev. post).

In that thread, Martin says """
No, this is as intended. If you doubt it, compile the same example
with javac -- you should get the same result. This is a
little-understood subtlety in the meaning of protected: you can only
access a protected member from something that's as least as
specialized as your class. So in C you can access protected A-members
of other C objects, but not the same members of A objects.
"""


Here is a Java equivalent of the above Scala code:

class A {
protected void m() {}
}

class B extends A {
protected void n(A a) {a.m();}
}


It compiles *without* errors. (JDK 1.6.30)

So, the meaning of ´protected´ seems to be different in Scala and Java.

Is this really inteded?


Kind regards,
EL

Dave

unread,
Mar 3, 2012, 1:14:08 PM3/3/12
to scala-user
> Is this really inteded?

Yes and it doesn't matter if it is constructor argument or method
argument.
The argument type is not allowed to be wider than the enclosing class


> So, the meaning of ´protected´ seems to be different in Scala and Java.

Yes,
Java allows also objects from the same package as where the supertype
is defined
so to get java protected semantics you write protected[packagenameofA]
as modifier

Like so:
testprotected.scala
===================
package testprotected
abstract class A[T] {protected[testprotected] def m: T}
class A1[T](a: A[T]) extends A[T] {def m = a.m}

Btw: REPL doesn't support package definitions yet so you have to use
the compiler (already made an enhancement request for this)


Scala's protected semantics is stricter.




On 3 mrt, 18:54, Eugen Labun <la...@gmx.net> wrote:
> Hi Dave,
>
> yes, with a parameter of the same type it works, of course.
> But, for my purposes, it must be the supertype.
>
> Here is yet another, even more simple example with the same error:
>
> scala> :paste
> // Entering paste mode (ctrl-D to finish)
>
> class A {
>    protected def m {}}
>
> class B extends A {
>    protected def n(a: A) {a.m}
>
> }
>
> // Exiting paste mode, now interpreting.
>
> <console>:12: error: method m in class A cannot be accessed in A
>   Access to protected method m not permitted because
>   prefix type A does not conform to
>   class B where the access take place
>           protected def n(a: A) {a.m}
>                                    ^
>
> I also found this (closed - not a bug) tickethttps://issues.scala-lang.org/browse/SI-1383
> and a short thread ´Bug in implementation of "protected"?´http://comments.gmane.org/gmane.comp.lang.scala.user/8247(with an example much like my example from
> > could have access to A1[T} to call m- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -
Reply all
Reply to author
Forward
0 new messages