case class inheritance
2015-04-23 22:04
260 查看
Scala 禁止case class inheritance
在编译时会报出以下错误:
Error:(5, 12) case class FootballPlayer has case ancestor Person, but case-to-case inheritance is prohibited. To overcome this limitation, use extractors to pattern match on non-leaf nodes.
case class FootballPlayer(name: String, age: Int, number: Int) extends Person(name, age)
^
原因有挺多,下边的两篇文章讲了下理由,但我还是没明白其中的必要性。
http://tech.schmitztech.com/scala/caseclassinheritence.html http://stackoverflow.com/questions/11158929/what-is-so-wrong-with-case-class-inheritance
我们可以使得两个case class继承同一个trait来实际于case class继承的行为,但是这样就得自己写extractor了。比如
会编译出错, 因为Person是个trait,它并不支持extractor的语法。
需要给Person加个Companion object,像这样
这时就能用extractor了
编译器会为case class生成equals方法,但普通类就不会了。
这时,当两个FootballPlayer的构造参数相同,它们就相等。但是对于Doctor类来说不是这样了。
当给FootballPlayer这个case class的父类Person定义了equals方法之后,就不是这样了。
貌似这时候case class就不会生成equals方法了, 转而使用父类Person的equals方法。并且要记得同时在Person中覆盖hashCode方法,不然就破坏了equals对hashCode的要求。
case class Person(name: String, age: Int) case class FootballPlayer(name: String, age: Int, number: Int) extends Person(name, age)
在编译时会报出以下错误:
Error:(5, 12) case class FootballPlayer has case ancestor Person, but case-to-case inheritance is prohibited. To overcome this limitation, use extractors to pattern match on non-leaf nodes.
case class FootballPlayer(name: String, age: Int, number: Int) extends Person(name, age)
^
原因有挺多,下边的两篇文章讲了下理由,但我还是没明白其中的必要性。
http://tech.schmitztech.com/scala/caseclassinheritence.html http://stackoverflow.com/questions/11158929/what-is-so-wrong-with-case-class-inheritance
我们可以使得两个case class继承同一个trait来实际于case class继承的行为,但是这样就得自己写extractor了。比如
sealed trait Person{ def age: Int def name: String } case class FootballPlayer(name: String, age: Int, number: Int) extends Person val torres = FootballPlayer("Fernando Torres", 31, 19) val Person(name, age) = torres // can't resolve symbal Person
会编译出错, 因为Person是个trait,它并不支持extractor的语法。
需要给Person加个Companion object,像这样
object Person{ def unapply(p: Person) = Some((p.name, p.age)) }
这时就能用extractor了
val torres = FootballPlayer("Fernando Torres", 31, 19) val Person(name, age) = torres
编译器会为case class生成equals方法,但普通类就不会了。
sealed trait Person{ def age: Int def name: String } case class FootballPlayer(name: String, age: Int, number: Int) extends Person class Doctor(val name: String, val age: Int) extends Person val torresA = FootballPlayer("Fernando Torres", 31, 19) val torresB = FootballPlayer("Fernando Torres", 31, 19) println(torresA == torresB)//true val docA = new Doctor("C", 30) val docB = new Doctor("C", 30) println(docA == docB)//false
这时,当两个FootballPlayer的构造参数相同,它们就相等。但是对于Doctor类来说不是这样了。
当给FootballPlayer这个case class的父类Person定义了equals方法之后,就不是这样了。
sealed trait Person{self => def age: Int def name: String override def equals(that: Any):Boolean = { that match{ case p: Person => p.age == self.age && p.name == self.name case _ => false } } override def hashCode: Int = { var hash = 1 hash = hash * 31 + age hash = hash * 31 + {if(name !=null) name.hashCode else 0} hash } } case class FootballPlayer(name: String, age: Int, number: Int) extends Person class Doctor(val name: String, val age: Int) extends Person val torresA = FootballPlayer("Fernando Torres", 31, 19) val torresB = FootballPlayer("Fernando Torres", 31, 19) torresA.equals(torresB) println(torresA == torresB)//true val docA = new Doctor("C", 30) val docB = new Doctor("C", 30) println(docA == docB) //true val footballPlayerC = FootballPlayer("C", 30, 30) println(footballPlayerC == docA) //true println(footballPlayerC.hashCode())//1958 println(docA.hashCode())//1958
貌似这时候case class就不会生成equals方法了, 转而使用父类Person的equals方法。并且要记得同时在Person中覆盖hashCode方法,不然就破坏了equals对hashCode的要求。
相关文章推荐
- This error is raised because the column 'type' is reserved for storing the class in case of inheritance
- A class extends ArrayList, but the instance of the calss do not work in a complex case.
- (11)映射继承关系二之每个类对应一张表(@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
- Scala并发编程原生线程Actor、Case Class下的消息传递和偏函数实战解析
- Class Inheritance in C++
- scala高级内容(一) Case Class
- 第十四节 Case Class与模式匹配(一)
- scala 奇淫巧技 - 1.case class 长度问题
- Scala深入浅出实战经典:29,Case class和Case object代码实战解析
- spark系列case class学习
- 一步步学spark之一scala函数式编程中case class3.4
- 普通class和case class的区别
- scala - case class and pattens, Part II
- 第十五节 Case Class与模式匹配(二)
- scala case class
- Scala入门到精通——第十四节 Case Class与模式匹配(一),scala入门到精通
- scala case class与class区别
- 第29讲:Case class和Case object代码实战解析
- Class MockTestCase
- 云星数据---Scala实战系列(精品版)】:Scala入门教程040-Scala实战源码-Scala Case Class 02