Implementing inner traits in Scala like we do with inner interfaces in Java

余生长醉 提交于 2019-11-30 18:55:31
pagoda_5b

The inner type Q is defined only for specific instance implementation of the T trait. Since scala has path-dependent types, each instance of T will have his own subtrait Q.

scala> trait T {
     |   trait Q
     | }
defined trait T

scala> class C extends T {
     |   def getQ: this.Q = new this.Q {}
     | }
defined class C

scala> val inC = (new C).getQ
inC: C#Q = C$$anon$1@3f53073a


scala> val c = new C
c: C = C@1a7e4ff0

scala> new c.Q {}
res4: c.Q = $anon$1@36bbb2f5

If you need an interface for a generic behavior for your clients to implement, and not dependent on a specific C instance, you should define it within an Object

scala> object T {
     |   trait Q {
     |     def implementMe: Unit
     |   }
     | }
defined module T

scala> val inT = new T.Q {
     |   def implementMe = println("implemented!")
     | }
inT: T.Q = $anon$1@20f2a08b

scala> inT.implementMe
implemented!

Why path-dependent types?

As for the design reasons, look here

You cannot do that. When types are nested you're creating what is called a path-dependent type, meaning the type of each instance of the inner entity is tied to the specific instance within which it's constructed.

In other words, you interface Q has no independent existence that would allow you to refer to it apart from an instance of T.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!