8

下面是我试图运行的代码:

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
  }
}

printStudentDetails来自的方法MyGenericClassforLowerBound正在制造问题。陈述student.printDetailsstudent.printSomeOtherDetails告诉我

value printDetails is not a member of type parameter S

据我了解:

  • Q[A <: B]表示类/方法Q可以采用类的任何对象,A其中 ClassA是 class 的子类型B。这称为上限。
  • Q[A >: B]表示类/方法Q可以采用类的任何对象,A其中 ClassA是 class 的超类型B。这称为下限。

如果我的理解有误,请帮助我,并帮助我理解为什么会出现上述问题。多谢你们。

4

1 回答 1

14

你的理解没有错,只是你没有承担后果。

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

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

def printStudentDetails[S >: ComputerScienceStudent <: Student](student: S) = { ...

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

于 2013-11-06T20:20:08.303 回答