Scala Lesson 28 – Generics | Dataplexa

Generics

In this lesson, you will learn about Generics in Scala. Generics allow you to write flexible, reusable, and type-safe code.

Instead of writing separate code for each data type, generics let you write a single implementation that works with many types.


Why Generics Are Needed

Without generics, you often need to duplicate code for different data types. This leads to repetitive and hard-to-maintain programs.

Generics solve this problem by allowing types to be specified later, when the code is used.


Generic Class Example

Below is a simple class that stores a value of any type.

class Box[T](value: T) {
  def getValue: T = value
}

Here:

  • T is a type parameter
  • The actual type is provided when creating an object

Using a Generic Class

You can use the same generic class with different data types.

val intBox = new Box
val strBox = new Box[String]("Scala")

intBox.getValue
strBox.getValue

The compiler ensures type safety at compile time.


Generic Methods

Generics can also be used with methods, not just classes.

def printItem[T](item: T): Unit = {
  println(item)
}

This method works with any data type.

printItem(10)
printItem("Scala")
printItem(true)

Multiple Type Parameters

A generic class or method can have more than one type parameter.

class Pair[A, B](first: A, second: B) {
  def getFirst: A = first
  def getSecond: B = second
}

This allows combining values of different types.


Type Inference with Generics

Scala can often infer generic types automatically. You do not always need to specify them explicitly.

val box = new Box("Hello")
box.getValue

Scala infers the type T as String.


Upper Type Bounds

You can restrict the types allowed in generics using type bounds.

An upper bound restricts a type to be a subclass of a specific class.

class Printer[T <: AnyVal](value: T) {
  def print(): Unit = println(value)
}

This allows only value types like Int, Double, etc.


Generic Collections in Scala

Scala collections heavily use generics.

val numbers: List[Int] = List(1, 2, 3)
val names: List[String] = List("Alice", "Bob")

Generics ensure that collections store only valid types.


Benefits of Generics

  • Type safety at compile time
  • Code reusability
  • Cleaner and more maintainable code
  • Better performance than casting

📝 Practice Exercises


Exercise 1

Create a generic class Container that stores a value and returns it.

Exercise 2

Create a generic method that swaps two values and prints them.

Exercise 3

Create a class with two generic type parameters.


✅ Practice Answers


Answer 1

class Container[T](value: T) {
  def get: T = value
}

Answer 2

def swap[T](a: T, b: T): Unit = {
  println(b)
  println(a)
}

Answer 3

class Data[A, B](x: A, y: B) {
  def first: A = x
  def second: B = y
}

What’s Next?

In the next lesson, you will learn about Type Inference in Scala and how the compiler automatically determines data types.