case class inheritance

Scala 禁止case class inheritance

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的要求。

转载于:https://www.cnblogs.com/devos/p/4451935.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值