Scala UpperBound和LowerBound概念

Sud*_*Deb 8 generics scala variance subtyping

以下是我尝试运行的代码:

class Student {
  def printDetails = println("I am a student")
  def printSomeOtherDetails = println("I love Studying")
}

class ComputerScienceStudent extends Student {
  override def printDetails = println("I am a Computer Science Student")
  override def printSomeOtherDetails = println("I love Scala")
}

class InformationTechnologyStudent extends Student {
  override def printDetails = println("I am an Information Technology Student")
  override def printSomeOtherDetails = println("I love Java")
}

class MyGenericClassForUpperBound {
  def printStudentDetails[S <: Student](student: S) = {
    student.printDetails
    student.printSomeOtherDetails
  }
}

class MyGenericClassforLowerBound {
  def printStudentDetails[S >: ComputerScienceStudent](student: S) = {
    student.printDetails
    student.printSomeOtherDetails
  }
}
Run Code Online (Sandbox Code Playgroud)

方法printStudentDetails来自于MyGenericClassforLowerBound创建问题.声明student.printDetailsstudent.printSomeOtherDetails告诉我

value printDetails is not a member of type parameter S
Run Code Online (Sandbox Code Playgroud)

据我所知:

  • Q[A <: B]表示类/方法Q可以接受类的任何对象,A其中Class A是类的子类型B.这称为上界.
  • Q[A >: B]表示类/方法Q可以接受类的任何对象,A其中Class A是类的超类型B.这称为下界.

如果我的理解是错误的,请帮助我,并帮助我理解为什么上述问题即将到来.多谢你们.

Sha*_*nds 14

你的理解没有错,但你没有遵循后果.

具体地,Object如果没有提供明确的上限,则所有参数实际上具有上限.printStudentDetails对于您的类型中的方法,会发生这种情况MyGenericClassforLowerBound.也就是说,type的值Object可以合法地作为参数传递给此方法.但类型Object没有定义的方法printDetailsprintSomeOtherDetails-因此错误.

要使方法编译,您还需要提供合适的上限(类似于MyGenericClassforUpperBound),例如:

def printStudentDetails[S >: ComputerScienceStudent <: Student](student: S) = { ...
Run Code Online (Sandbox Code Playgroud)

但是应该注意,在这种情况下,下限实际上变得多余,因为子类的任何参数Student都可以成功传递,因为它可以被视为类型Student,满足上限 - 所以偶数InformationTechnologyStudent和子类ComputerScienceStudent可以传递成功地进入它.当您可以传递来自两个不同层次结构的类型的值时,这种构造更有用.