- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Strange behavior in simple class hierarchy
Thu, 2012-01-19, 22:11
Hello,
I'm confuse about the following lines. Can someone please explain if
this is a bug or I'm missing something (that should be very simple)?
The result of the last command (println(a)) shouldn't be "obj: new
test" ?
It seems that class "sub" has a val named "name" and when changing
"a.name" what gets changed is the var "name" in the class "one".
If so, how can I declare class "sub" so that there is only one var
named "name" in class "one" (the argument "name" in the constructor
of class "sub" should be directly passed to class "one" and not stored
in any way in class "sub")?
It seems that using "override" is not an option (would end up with two
variables in memory, one for each object "one" and "sub"). Also, we
can't override a var with another var (I don't know why).
Thanks,
Marcos
----------------------------
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java
1.6.0_30)
.
Type in expressions to have them evaluated.
Type :help for more information.
scala> class one(var name:String)
defined class one
scala> class sub(name:String) extends one(name) {override def toString
= "obj: "+name}
defined class sub
scala> val a = new sub("test")
a: sub = obj: test
scala> a.name = "new test"
a.name: String = new test
scala> println(a)
obj: test
------------------------------------------------
Thu, 2012-01-19, 23:41
#2
Re: Strange behavior in simple class hierarchy
Simply put, when you write "class sub(name: String)" you are shadowing
a public declaration with a private one. You are not overriding the
public declaration, because this is private, not public.
The solution is pretty simple: never use as parameter name a name used
by a super class.
Yes, it's annoying, particularly since parameter names are part of a
public interface, given that Scala supports named parameters.
On Thu, Jan 19, 2012 at 19:11, Marcos Ackel wrote:
> Hello,
>
> I'm confuse about the following lines. Can someone please explain if
> this is a bug or I'm missing something (that should be very simple)?
>
> The result of the last command (println(a)) shouldn't be "obj: new
> test" ?
>
> It seems that class "sub" has a val named "name" and when changing
> "a.name" what gets changed is the var "name" in the class "one".
>
> If so, how can I declare class "sub" so that there is only one var
> named "name" in class "one" (the argument "name" in the constructor
> of class "sub" should be directly passed to class "one" and not stored
> in any way in class "sub")?
>
> It seems that using "override" is not an option (would end up with two
> variables in memory, one for each object "one" and "sub"). Also, we
> can't override a var with another var (I don't know why).
>
> Thanks,
>
> Marcos
>
> ----------------------------
> Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java
> 1.6.0_30)
> .
> Type in expressions to have them evaluated.
> Type :help for more information.
>
>
> scala> class one(var name:String)
> defined class one
>
> scala> class sub(name:String) extends one(name) {override def toString
> = "obj: "+name}
> defined class sub
>
> scala> val a = new sub("test")
> a: sub = obj: test
>
> scala> a.name = "new test"
> a.name: String = new test
>
> scala> println(a)
> obj: test
>
> ------------------------------------------------
Thu, 2012-01-19, 23:51
#3
Re: Strange behavior in simple class hierarchy
Thank you!
I used this workaround:
class One(var name:String)
class Sub(name:String) extends One(name) {override def toString =
"obj: "+ (this:One).name}
Couldn't use "super.name": compiler error (seems compiler bug)
The problem seems an specification flaw to me...
Some of the proposed workarounds proposed at the thread do NOT work,
like:
class sub(_) extends one(_) // error: identifier expected but '_'
found.
Thanks again.
Marcos
On Jan 19, 7:47 pm, Trond Olsen wrote:
> There was a thread a month ago about this. Seehttp://groups.google.com/group/scala-language/browse_thread/thread/f6....
Fri, 2012-01-20, 00:21
#4
Re: Re: Strange behavior in simple class hierarchy
On Thu, Jan 19, 2012 at 20:34, Marcos Ackel wrote:
>
> Some of the proposed workarounds proposed at the thread do NOT work,
> like:
>
> class sub(_) extends one(_) // error: identifier expected but '_'
> found.
That's not a proposed workaround. It's a proposed *change* to the
language, to avoid this problem.
Fri, 2012-01-20, 01:51
#5
Re: Strange behavior in simple class hierarchy
Thanks for answering. Now I understand - and facing this way it works
nicely. Thank you.
I finally wrote:
-------------------
scala> class One(var name:String)
defined class One
scala> class Sub(_name:String) extends One(_name) {override def
toString = "obj: "+name}
defined class Sub
scala> val a = new Sub("test")
a: Sub = obj: test
scala> a.name = "new test"
a.name: String = new test
scala> println(a)
obj: new test
-------------------------
On Jan 19, 8:28 pm, Daniel Sobral wrote:
> Simply put, when you write "class sub(name: String)" you are shadowing
> a public declaration with a private one. You are not overriding the
> public declaration, because this is private, not public.
>
> The solution is pretty simple: never use as parameter name a name used
> by a super class.
>
> Yes, it's annoying, particularly since parameter names are part of a
> public interface, given that Scala supports named parameters.
>
>
>
>
>
>
>
>
>
> On Thu, Jan 19, 2012 at 19:11, Marcos Ackel wrote:
> > Hello,
>
> > I'm confuse about the following lines. Can someone please explain if
> > this is a bug or I'm missing something (that should be very simple)?
>
> > The result of the last command (println(a)) shouldn't be "obj: new
> > test" ?
>
> > It seems that class "sub" has a val named "name" and when changing
> > "a.name" what gets changed is the var "name" in the class "one".
>
> > If so, how can I declare class "sub" so that there is only one var
> > named "name" in class "one" (the argument "name" in the constructor
> > of class "sub" should be directly passed to class "one" and not stored
> > in any way in class "sub")?
>
> > It seems that using "override" is not an option (would end up with two
> > variables in memory, one for each object "one" and "sub"). Also, we
> > can't override a var with another var (I don't know why).
>
> > Thanks,
>
> > Marcos
>
> > ----------------------------
> > Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java
> > 1.6.0_30)
> > .
> > Type in expressions to have them evaluated.
> > Type :help for more information.
>
> > scala> class one(var name:String)
> > defined class one
>
> > scala> class sub(name:String) extends one(name) {override def toString
> > = "obj: "+name}
> > defined class sub
>
> > scala> val a = new sub("test")
> > a: sub = obj: test
>
> > scala> a.name = "new test"
> > a.name: String = new test
>
> > scala> println(a)
> > obj: test
>
> > ------------------------------------------------
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
Sat, 2012-01-21, 15:51
#6
Re: Strange behavior in simple class hierarchy
Another suggestion, that I think it's more intuitive and more
integrated with the language, would be to do nothing if the code says
nothing. For example:
class One(var city: String)
class Sub(city: String) extends One(city)
=> "city" would be just a temporary variable, defining no field in
class Sub. Today "city" turns out to be a private val field. Also,
today there is no way of using the same name to the inherited field
without having another field embedded in the Sub class.
class Sub2(private val city1: String)
=> now it's a private val
class Sub3(val city1: String)
=> public val field
If you use the same field name ("city"), will have to solve the
conflict of names:
class Sub4( private override val city: String ) extends One(city)
class Sub5( override val city: String ) extends One(city)
-----
I'm not sure if the current policy of not allowing override of a var
with a var is a good one (even though it seems that there is no point,
as both are mutable). One could use this in some cases. It seems to me
that the compiler could allow it, as there is no conflict or explicit
error:
class Sub6(private override var city: String) extends One(city)
class Sub4(override var city: String) extends One(city)
This ends up with var fields named "city" in all classes, but there is
no conflict. And the user could use both if needed.
Marcos
On Jan 19, 9:11 pm, Daniel Sobral wrote:
> On Thu, Jan 19, 2012 at 20:34, Marcos Ackel wrote:
>
> > Some of the proposed workarounds proposed at the thread do NOT work,
> > like:
>
> > class sub(_) extends one(_) // error: identifier expected but '_'
> > found.
>
> That's not a proposed workaround. It's a proposed *change* to the
> language, to avoid this problem.
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
On 19 January 2012 22:11, Marcos Ackel <mvackel@yahoo.com> wrote: