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.printDetails并student.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没有定义的方法printDetails和printSomeOtherDetails-因此错误.
要使方法编译,您还需要提供合适的上限(类似于MyGenericClassforUpperBound),例如:
def printStudentDetails[S >: ComputerScienceStudent <: Student](student: S) = { ...
Run Code Online (Sandbox Code Playgroud)
但是应该注意,在这种情况下,下限实际上变得多余,因为子类的任何参数Student都可以成功传递,因为它可以被视为类型Student,满足上限 - 所以偶数InformationTechnologyStudent和子类ComputerScienceStudent可以传递成功地进入它.当您可以传递来自两个不同层次结构的类型的值时,这种构造更有用.