Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala - implementing trait method with parameter that is child of expected type

I'm very new to Scala so forgive me if this is a real easy question but I could not find anything to help me or I could not figure out the right search terms. How can I make this work?

scala> trait Foo
defined trait Foo

scala> class FooImpl extends Foo
defined class FooImpl

scala> trait Bar { def someMethod(foo: Foo) }
defined trait Bar

scala> class BarImpl extends Bar { def someMethod(foo: FooImpl) {} }
<console>:10: error: class BarImpl needs to be abstract, since method someMethod in trait Bar of type (foo: Foo)Unit is not defined
(Note that Foo does not match FooImpl)
       class BarImpl extends Bar { def someMethod(foo: FooImpl) {} }

Why doesn't FooImpl match Foo since Foo is a trait? I'm guessing I need to alter the signature of someMethod in Bar to say that I'm expecting something that extends Foo or "with Foo" but I can't seem to find documentation for this.

like image 911
ShatyUT Avatar asked Jan 22 '26 05:01

ShatyUT


1 Answers

The problem is that the Bar trait's someMethod declaration specifies that any kind of Foo can be passed as an argument. You can think of this as its "contract". The contract says that any implementation of Bar will have a method someMethod that will accept any kind of Foo.

Your BarImpl class is an implementation of Bar and has a someMethod implementation. Unfortunately, its implementation of someMethod only accepts FooImpl kinds of Foo objects: not any kind of Foo. Since it doesn't allow you to pass in Foo objects that aren't FooImpl objects, it violates the contract specified by the trait definition. Implementations can't be more restrictive than the contract specifies.

As an example:

class FooImplB extends Foo
val bar: Bar = new BarImpl
val foo: Foo = new FooImplB
bar.someMethod(foo)

Here we declare a Bar called bar and a Foo called foo. According to the definition of Foo I should be able to pass foo into bar.someMethod. Except that BarImpl.someMethod only accepts FooImpl kinds of Foos and not FooImplBs! So we have a problem.

like image 71
dhg Avatar answered Jan 25 '26 15:01

dhg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!