I have this class in scala
trait PageComponent {
protected var page:Page = _
protected var pageData:PageData = _
def initialise(page0:Page, pageData0:PageData) {
page = page0
pageData = pageData0
}
}
Each subclass of PageComponent has it's own subclass of Page and PageData as well. When a subclass calls page or pageData, I want it to return it's own type for this.
I've tried stuff like
trait PageComponent {
type P <: Page
protected var page:P = _
protected var pageData:PageData = _
def initialise(page0:P, pageData0:PageData) {
page = page0
pageData = pageData0
}
}
and this sort of works such that the subclass can call page and gets the page type defined by implementing the type P.
However, I'm trying to call the initialise method and I'm passing through an object of type Page and it is showing this error
error: type mismatch;
found : pageInfoToGoTo.page.type (with underlying type com.xxx.gui.Page)
required: pageComponentToGoTo.P
pageComponentToGoTo.initialise(pageInfoToGoTo.page, pageData)
I'm obviously wrong here but I thought because P "is a" Page this should work for me.
Any ideas?
-----edit for more info------
I do have something like
class AhoyPage extends Page
object MyPageComponent extends PageComponent {
type P = AhoyPage
}
after reading jwinandy's answer I changed the code so that the initialise method is called this way
pageComponentToGoTo.initialise(pageInfoToGoTo.page.asInstanceOf[pageComponentToGoTo.P], pageData)
and it now works. So I guess my question is answered. Thanks. That cast isn't very nice though. I have a list of PageInfo that looks like this
PageInfo(page:Page, ...)
when a PageInfo is selected I use the page to look up the page component in a map. There must be a better way of doing it but if not, I'm happy with this.
You have to define P when you subclass.
In you case, you have to had :
type P = com.xxx.gui.Page
Example, this works :
trait Page
trait PageData
trait PageComponent {
type P <: Page
protected var page:P = _
protected var pageData:PageData = _
def initialise(page0:P, pageData0:PageData) {
page = page0
pageData = pageData0
}
}
class AhoyPage extends Page
object MyPageComponent extends PageComponent {
type P = AhoyPage
}
object MyApp extends App {
MyPageComponent.initialise(new AhoyPage, new PageData {})
// OR
MyPageComponent.initialise(new MyPageComponent.P, new PageData {})
}
Please post more of your code if you want to refactor a bit to achieve a better level of composability.
-- edit --
Like https://gist.github.com/3608684
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With