Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a class extend traits with method of the same signature?

Why do I get the error below? How to workaround it?

I assumed that since A and B compile to (interface,class) pairs, it's a matter of choosing the right static method call to implement when compiling C. I would expect the priority to be according to order.

scala> trait A { def hi = println("A") } defined trait A  scala> trait B { def hi = println("B") } defined trait B  scala> class C extends B with A <console>:6: error: error overriding method hi in trait B of type => Unit;  method hi in trait A of type => Unit needs `override' modifier        class C extends B with A  scala> trait A { override def hi = println("A") } <console>:4: error: method hi overrides nothing        trait A {override def hi = println("A")} 

Note that in Ruby this works well:

>> module B; def hi; puts 'B'; end; end => nil >> module A; def hi; puts 'A'; end; end => nil >> class C; include A; include B; end => C >> c = C.new => #<C:0xb7c51068> >> c.hi B => nil 
like image 523
IttayD Avatar asked Dec 02 '09 21:12

IttayD


People also ask

Can a class extend a trait?

Classes and objects can extend traits, but traits cannot be instantiated and therefore have no parameters.

Can traits extend other traits?

Unlike a class, what's important to remember, is that you cannot add extends or implements to a trait. You can't instantiate a trait, either. Their sole purpose is to support our classes, and not to replace them. Traits can have methods, just like classes do.

Can a trait extend an abstract class?

A class can extend only one abstract class, but it can implement multiple traits, so using traits is more flexible.

Can traits be instantiated?

Unlike the other types, however, traits cannot be instantiated. Traits look about the same as any other type of class. However, like objects, they cannot take class parameters.


1 Answers

This works for me in 2.8 and 2.11, and would allow you to be non-intrusive in traits A or B:

trait A { def hi = println("A") } trait B { def hi = println("B") }  class C extends A with B {   override def hi = super[B].hi   def howdy = super[A].hi // if you still want A#hi available }  object App extends Application {   (new C).hi // prints "B" } 
like image 147
Mitch Blevins Avatar answered Sep 22 '22 04:09

Mitch Blevins