CodeBlanks Logo Icon CodeBlanks

Summary - Generics

Combine generic class, methods and collections to write a Stack<T>.

Summary - Generics

In this group you saw all the tools of generics: generic class, generic method, type constraint, generic collection and generics vs dynamic. Now we will merge them in a generic stack system.

In the first step we will write a generic stack named Stack<T> with push and pop methods. In the second step we will add the <T extends num> constraint and specialize the NumberBox class to numbers. These two examples show the power of generics in one flow: type safety and reuse together.

Practice Write a generic Stack<T> class

Define a generic class named Stack<T>. Give it a final List<T> _items = []; field. The void push(T v) method should do _items.add(v); the T pop() method should return _items.removeLast();. In main, create var s = Stack<int>();, call s.push(1), s.push(2), s.push(3) and print(s.pop()).

Starter code

main.dart
// Define the Stack<T> class
// Add push and pop methods

void main() {
  // Create a Stack<int>, push and pop
}

Sample solution

main.dart
// Define the Stack<T> class
class Stack<T> {
  final List<T> _items = [];
  void push(T v) {
    _items.add(v);
  }
  T pop() {
    return _items.removeLast();
  }
}

void main() {
  var s = Stack<int>();
  s.push(1);
  s.push(2);
  s.push(3);
  print(s.pop());
}

Expected output

3

Constrained generic: NumberBox<T extends num>

In the second step we will specialize a generic class to numbers using the <T extends num> constraint. NumberBox<T extends num> accepts only int and double; this makes operators like + safe at compile time.

Example: class NumberBox<T extends num> { final T value; NumberBox(this.value); num sum(T other) { return value + other; } }. Here value + other compiles because both carry num behavior. The call NumberBox<int>(5).sum(3) returns 8. This is a real example of adding a constraint to a generic class.

Practice Write a NumberBox<T extends num> class

Define a constrained generic class named NumberBox<T extends num>. Give it a final T value field and a NumberBox(this.value) constructor. The num sum(T other) method should return value + other;. In main, create var b = NumberBox<int>(5); and call print(b.sum(3)).

Starter code

main.dart
// Define the NumberBox<T extends num> class
// Add the sum method

void main() {
  // Create NumberBox<int>(5) and print sum(3)
}

Sample solution

main.dart
// Define the NumberBox<T extends num> class
class NumberBox<T extends num> {
  final T value;
  NumberBox(this.value);
  num sum(T other) {
    return value + other;
  }
}

void main() {
  var b = NumberBox<int>(5);
  print(b.sum(3));
}

Expected output

8

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which is true for a generic Stack<T>?

  • Stack<T> cannot hold a constructor
  • Stack<T> works only with int
  • Stack<T> works with any type; it provides type safety Correct answer
  • Stack<T> is the same as dynamic

Explanation: Stack<T> works with any type and gives compile-time type safety.

All lessons in Intermediate