Scala UpperBound and LowerBound concept

北城余情 提交于 2019-12-20 14:40:18

问题


Below is the code I am trying to run:

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

the method printStudentDetails from MyGenericClassforLowerBound is creating the problem. The statements student.printDetails and student.printSomeOtherDetails are telling me

value printDetails is not a member of type parameter S

As far as I understood:

  • Q[A <: B] means the class/method Q can take any objects of class A where Class A is the sub type of class B. This is called Upper Bound.
  • Q[A >: B] means the class/method Q can take any objects of class A where Class A is the super type of class B. This is called Lower Bound.

Please help me if my understanding is wrong and help me to understand why the above stated problem is coming. Thanks guys.


回答1:


Your understanding is not wrong, but you haven't followed through the consequences.

Specifically, all parameters have, in effect, an upper bound of Object if no explicit upperr bound is provided. This is happening in the case of the method printStudentDetails in your type MyGenericClassforLowerBound. That is, a value of type Object could be legally passed as the parameter to this method. But type Object does not define the methods printDetails and printSomeOtherDetails - hence the error.

To make the method compile, you would need to also provide a suitable upper bound (similar to MyGenericClassforUpperBound), eg:

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

It should be noted in this case, however, that the lower bound effectively becomes redundant, because any parameter that subclasses Student can be passed in successfully because it can be treated as of type Student, satisfying teh upper bound - so even InformationTechnologyStudent and subclasses of ComputerScienceStudent can be passed into it successfully. This sort of construct is more useful when you might be passed in values mixing in types from two different hierarchies.



来源:https://stackoverflow.com/questions/19821824/scala-upperbound-and-lowerbound-concept

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!