组合子类型(Scala)
我正在寻找一个干净的面向对象的方式来模拟以下内容(在Scala中):
一个人可以是: >某公司的经理 这表明我们介绍一个Person的超类和子类: >类经理 Manager类具有以下方法:getSalary(),workLongHours(),findNewJob()等.TennisPlayer类具有以下方法:getWorldRanking(),playGame(),strainAnkle()等等.另外还有类Person中的方法,如getsSick().一个有病的经理失去了工作,网球运动员在赛季停止了运动. 此外,课程是不可变的.也就是说,例如,strainAnkle()返回一个新的TennisPlayer,它具有紧张的脚踝,但是所有其他属性保持不变. 现在的问题是:我们如何模拟一个人既可以是管理者又可以是TennisPlayer, 重要的是,该解决方案既保持了不变性,又保证了安全性. 我们可以实现类: >经理和数学家 但这导致班级的组合爆炸. 我们还可以使用traits(with state),但是我们如何实现诸如findNewJob()之类的方法,这些方法需要返回一个具有相同特征的新人,而且具有新的Manager特征状态.同样,我们如何实现诸如getsSick()的方法? 问题:您将如何在Scala的干净OO时尚中实现?记住:不可变性和类型安全是必须的. 解决方法
这不像我继承的理想情况.也许你试图强制将事情变成继承模式,因为处理具有不变值的组合似乎很尴尬.这是几种方法之一.
object Example { abstract class Person(val name: String) { def occupation: Occupation implicit val self = this abstract class Occupation(implicit val practitioner: Person) { def title: String def advanceCareer: Person } class Programmer extends Occupation { def title = "Code Monkey" def advanceCareer = practitioner } class Student extends Occupation { def title = "Undecided" def advanceCareer = new Person(practitioner.name) { def occupation = new Programmer } } } def main(args: Array[String]) { val p = new Person("John Doe") { def occupation = new Student } val q = p.occupation.advanceCareer val r = q.occupation.advanceCareer println(p.name + " is a " + p.occupation.title) println(q.name + " is a " + q.occupation.title) println(r.name + " is a " + r.occupation.title) println("I am myself: " + (r eq r.occupation.practitioner)) } } 让我们试试吧 scala> Example.main(Array()) John Doe is a Undecided John Doe is a Code Monkey John Doe is a Code Monkey I am myself: true 所以这样做有点有用. 这里的诀窍是,每当一个职业(这是一个内在类)决定改变事情时,你创建你的人的匿名子类.它的工作是创造一个新角色,新角色完整无缺;这是通过隐含的val self = this和对职业的隐式构造函数来帮助的,这有助于自动加载人的正确实例. 您可能需要一个职业列表,因此可能会需要帮助方法来重新生成专业列表.就像是 object Example { abstract class Person(val name: String) { def occupations: List[Occupation] implicit val self = this def withOccupations(others: List[Person#Occupation]) = new Person(self.name) { def occupations = others.collect { case p: Person#Programmer => new Programmer case s: Person#Pirate => new Pirate } } abstract class Occupation(implicit val practitioner: Person) { def title: String def addCareer: Person override def toString = title } class Programmer extends Occupation { def title = "Code Monkey" def addCareer: Person = withOccupations( this :: self.occupations ) } class Pirate extends Occupation { def title = "Sea Monkey" def addCareer: Person = withOccupations( this :: self.occupations ) } } def main(args: Array[String]) { val p = new Person("John Doe") { def occupations = Nil } val q = (new p.Programmer).addCareer val r = (new q.Pirate).addCareer println(p.name + " has jobs " + p.occupations) println(q.name + " has jobs " + q.occupations) println(r.name + " has jobs " + r.occupations) println("I am myself: " + (r eq r.occupations.head.practitioner)) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |