2015-10-07 3 views
1

иметь класс SCALAизменить тип возвращаемого суперкласса метода

class JobsHistory extends mutable.HashSet[JobInstance] { 

     /** 
     * Filter only Map Reduce Jobs 
     * @return 
     */ 
     implicit def onlyMapReduce = this.filter((job) => job.mapTasksCount > 0 && job.reduceTasksCount > 0) 

     /** 
     * Filter only jobs with successful status 
     * @return 
     */ 
     implicit def onlySucceeded = this.filter((job) => job.status == "SUCCEEDED") 
    } 

Я хотел бы быть в состоянии сделать тип вызова

instances.onlyMapReduce.onlySucceeded 

где instances является JobsHistory типа. Проблема в том, что я вызываю фильтр, который поступает из суперкласса, и возвращает HashSet, а не JobsHistory, как я могу обеспечить правильный тип возврата.

ответ

3

Я бы предложил просто добавить эти методы к Set, используя шаблон Pimp My Library.

case class JobInstance(status: String, mapTasksCount: Int, reduceTasksCount: Int) 

implicit class JobHistory(val jobs: Set[JobInstance]) extends AnyVal { 
    def onlyMapReduce = jobs.filter((job) => job.mapTasksCount > 0 && job.reduceTasksCount > 0) 

    def onlySucceeded = jobs.filter(_.status == "SUCCEEDED") 
} 

val set = Set(JobInstance("SUCCEEDED", 3, 3), JobInstance("SUCCEEDED", 0, 3), JobInstance("Failed", 3, 3)) 

set.onlyMapReduce.onlySucceeded 
res3: scala.collection.immutable.Set[JobInstance] = Set(JobInstance(SUCCEEDED,3,3)) 

Она будет работать так же с изменяемым зделали filter возвращает новый набор независимо от того, если это изменяемые или нет.

2

Я думаю, что это хороший случай, чтобы предпочесть композицию над наследованием.

case class JobHistory(jobs: Set[JobInstance]) { 
    def onlyMapReduce = copy(jobs = jobs filter (job => 
    job.mapTasksCount > 0 && job.reduceTasksCount > 0 
)) 

    def onlySucceeded = copy(jobs = jobs filter (job => job.status == "SUCCEEDED")) 
} 

Обратите внимание, что я заменил mutable.HashSet на immutable.Set.

Смежные вопросы