以下是我尝试运行的代码:
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.printDetails
和student.printSomeOtherDetails
告诉我value printDetails is not a member of type parameter S
据我了解:
Q[A <: B]
表示类/方法Q
可以接受A
类的任何对象,其中A
类是B
类的子类型。这称为上限。 Q[A >: B]
表示类/方法Q
可以接受A
类的任何对象,其中A
类是B
类的父类(super class)型。这称为下界。 如果我的理解是错误的,请帮助我,并帮助我理解为什么出现上述问题。谢谢你们。
最佳答案
您的理解并没有错,但是您没有完全理解后果。
具体来说,如果未提供明确的上限,则所有参数实际上都具有Object
的上限。这是在您的类型printStudentDetails
中使用MyGenericClassforLowerBound
方法的情况下发生的。也就是说,可以将Object
类型的值合法地作为参数传递给此方法。但是Object
类型没有定义printDetails
和printSomeOtherDetails
方法-因此出错。
要编译该方法,您还需要提供合适的上限(类似于MyGenericClassforUpperBound
),例如:
def printStudentDetails[S >: ComputerScienceStudent <: Student](student: S) = { ...
但是,在这种情况下,应该注意的是,下限实际上变得多余,因为子类
Student
的任何参数都可以成功传入,因为它可以被视为Student
类型,并且满足上限-因此,即使InformationTechnologyStudent
和子类也可以ComputerScienceStudent
可以成功传递给它。当您可能会传入混合了来自两个不同层次结构的类型的值时,这种构造会更有用。