Scala Generics with trait implementation -

142 Views Asked by At

I want to build a messaging Queue Consumer, which for now will have only one implementation for Kafka but later on, it can have other implementations as well.

trait MessagingQueueConsumer {

  def consume[B <: NotificationConsumerRecords](topic: String, userNames: List[String]): TrieMap[String, B]

}

Here NotificationConsumerRecords is an abstract class for the records I consume from the messaging queue.

sealed abstract class NotificationConsumerRecords

and a case class extending it.

case class KafkaConsumerRecords[K,V](records: List[ConsumerRecord[K,V]]) extends NotificationConsumerRecords

And consume method should be able to accept all subtypes of NotificationConsumerRecords, that's why there is consume[B <: NotificationConsumerRecords]

Now, When I extend this trait for Kafka and try to implement consume

class KafkaMessagingQueueConsumer extends MessagingQueueConsumer {

  override def consume[KafkaConsumerRecords](topic: String, userNames: List[String]): TrieMap[String, KafkaConsumerRecords[String, String]] = {}
}

Or

class KafkaMessagingQueueConsumer extends MessagingQueueConsumer {

  override def consume[KafkaConsumerRecords[String, String]](topic: String, userNames: List[String]): TrieMap[String, KafkaConsumerRecords[String, String]] = {}
}

I get compile time error in both cases. and I guess I understand that the problem here is that compiler is taking them as some generic type instead of a particular type.

But I do not know what should I do to let the compiler know that this KafkaMessagingQueueConsumer should accept only KafkaConsumerRecords.

1

There are 1 best solutions below

0
jkinkead On

You've added the type parameter to the method, but you want the parameter on the trait.

Try this instead:

// Consumer for "B".
trait MessagingQueueConsumer[B <: NotificationConsumerRecords] {
  def consume(topic: String, userNames: List[String]): TrieMap[String, B]
}

And when implementing:

class KafkaMessagingQueueConsumer
    extends MessagingQueueConsumer[KafkaConsumerRecords] {
  override def consume(
      topic: String,
      userNames: List[String]
  ): TrieMap[String, KafkaConsumerRecords[String, String]] = {}
}