1) How could the following be designed so that toString is called for the traits mixed in? Tried to have each trait's toString prepend a call its parent trait toString, but that failed.
scala> trait A {
| val a: String
| override def toString = a
| }
defined trait A
scala> trait B {
| val b: String
| override def toString = b
| }
defined trait B
scala> val a = new A {val a="A"}
a: java.lang.Object with A = A
scala> println(a)
A
scala> val b = new B {val b="B"}
b: java.lang.Object with B = B
scala> println(b)
B
scala> val ab = new A with B {val a="A"; val b="B"}
ab: java.lang.Object with A with B = B
scala> println(ab)
B
scala> val ba = new B with A {val a="A"; val b="B"}
ba: java.lang.Object with B with A = A
scala> println(ba)
A
2) Why do I not get the same output from these two statements then both ab and ba have A mixed in?
scala> println(if(ab.isInstanceOf[A]) ab.asInstanceOf[A])
B
scala> println(if(ba.isInstanceOf[A]) ba.asInstanceOf[A])
A
scala> trait A {
| val a: String
| abstract override def toString = a + super.toString
| }
defined trait A
scala> trait B {
| val b: String
| abstract override def toString = b + super.toString
| }
defined trait B
scala> val ab = new A with B { val a = "A"; val b = "B" }
ab: java.lang.Object with A with B = BA$anon$1@384e9bea
scala> println(ab)
BA$line3.$read$$iw$$iw$$anon$1@384e9bea
scala> val ba = new B with A { val a = "A"; val b = "B" }
ba: java.lang.Object with B with A = AB$anon$1@24748417
scala> println(ba)
AB$line5.$read$$iw$$iw$$anon$1@24748417
The $line...etc is from the default toString.
2) Because what the compiler thinks a type is have no relevance to
method overrides. If it did, then inheritance would be pretty silly.
Any place where you had def f(x: A), it wouldn't matter what class you
actually passed to f, x would always act like an A.
--
Daniel C. Sobral
I travel to the future all the time.
trait Base {
override def toString = ""
}
trait A extends Base {
val a: String
abstract override def toString = (if(super.toString.size > 0) (super.toString+ "\n\t") else "") + a
}
trait B extends Base {
val b: String
abstract override def toString = (if(super.toString.size > 0) (super.toString + "\n\t") else "") + b
}
val a = new A {val a="A"}
println(a)
val b = new B {val b="B"}
println(b)
val ab = new Base with A with B {val a="A"; val b="B"}
println(ab)
val ba = new Base with B with A {val a="A"; val b="B"}
println(ba)
Erik Peterson
m: (281) 804-9023
e...@ardec.com
The reason there's a message is that it had a habit of crashing the
compiler, because super needs a lot of special handling and there are
some places more likely to take programmers by surprise than other
places. But what is the situation where you think you'd get an an
answer from super.isInstanceOf[Foo] than you wouldn't get from
this.isInstanceOf[Foo] ? There's a pretty tiny zone of potential
difference there, and if I grant for the sake of argument a legitimate
need to see into that zone, it won't work right anyway.