简体   繁体   中英

scala: upper and lower bounds in functions between classes

Assuming that

class SpecificAPI extends APIConnection{
   def annotate(...) = //definition of annotate function
}

I have a class father:

class Father{
   protected def processMessage[A<:APIConnection](recordToAnalyze: RecordToAnalyze, api:Option[A] = None): Option[IndexEnrichment]
}

class Child extends Father{
   override def processMessage[SpecificAPI](recordToAnalyze: RecordToAnalyze, api: Option[SpecificAPI]): Option[IndexEnrichment] = {

    api.get.annotate(...) //I cannot access to this function
}

Why I cannot access to methods of the SpecificAPI in the Child class?

Basically I want to define a generic method to instantiate che connection to different APIs and I want to change only the function processMessage in the Children classes. Am I missing something?

Because SpecificAPI in class Child is the type parameter. So it is the same as actually typing processMessage[A] ...

What you probably want is to lift type parameter to class definition, so you can pass the SpecificApi to the Child :

class Father[A<:APIConnection]{
   protected def processMessage(recordToAnalyze: RecordToAnalyze, api:Option[A] = None): Option[IndexEnrichment]
}

class Child extends Father[SpecificAPI]{
   override def processMessage(recordToAnalyze: RecordToAnalyze, api: Option[SpecificAPI]): Option[IndexEnrichment] = {

    api.get.annotate(...) //I cannot access to this function
}

As a side note, do not use get directly on Option , unless you did it just to make this example.

The type parameter SpecificAPI in the processMessage of the Child class is an unconstrained type parameter with an extremely confusing name. If you want to understand better what your code does, rename it to X :

class Child extends Father{
  override def processMessage[X](
    recordToAnalyze: RecordToAnalyze, 
    api: Option[X]
  ): Option[IndexEnrichment] = {
    api.get.annotate(...) //I cannot access to this function
    // Well, why should an arbitrary `X` have method `annotate`?
  }
}

Now it should be obvious that this cannot compile.

I have a vague feeling that you might have meant something like this:

trait APIConnection
class IndexEnrichment
class RecordToAnalyze

class SpecificAPI extends APIConnection {
  def annotate(): Unit = ???
}

trait Father [A <: APIConnection] {
  protected def processMessage(
    recordToAnalyze: RecordToAnalyze, 
    api:Option[A] = None
  ): Option[IndexEnrichment]
}

class Child extends Father[SpecificAPI] {
  override def processMessage(
    recordToAnalyze: RecordToAnalyze, 
    api: Option[SpecificAPI]
  ): Option[IndexEnrichment] = {
    api.get.annotate()
    ???
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM