Skip to content

Commit b63859a

Browse files
committed
feat(generics-upper-bounds): add example of upper-bounded wildcards with Animal hierarchy
WHAT: - Introduced `Animal` base class with subclasses `Dog` and `Cat`, each overriding `sound()`. - Implemented method `makeSound(List<? extends Animal>)` that accepts a list of any subclass of `Animal`. - Demonstrated runtime polymorphism by passing `List<Dog>` and `List<Cat>` to the method. WHY: - Showcases how upper-bounded wildcards (`? extends Animal`) allow methods to operate on collections of a type and its subtypes. - Useful for read-only scenarios where elements are consumed but not safely added (PECS principle: Producer Extends). - Demonstrates real-world applicability: handling heterogeneous animal types with one generic method. DETAILS: - `List<? extends Animal>` ensures flexibility to accept both `List<Dog>` and `List<Cat>`. - Iteration treats elements as `Animal` → enabling polymorphic method calls like `animal.sound()`. - Prevents unsafe additions (cannot add a `Dog` to `List<? extends Animal>` safely, except `null`). BENEFITS: - Promotes reusable and type-safe code when processing different subclasses in collections. - Demonstrates dynamic method dispatch via generics and wildcards. - Reinforces understanding of covariance in generics (`? extends T`). REFERENCE: - PECS Principle: - Producer → `? extends T` (safe for reading). - Consumer → `? super T` (safe for writing). Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent bb7ffe9 commit b63859a

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package UpperBoundedWildcards;
2+
3+
import java.util.List;
4+
5+
class Animal {
6+
public void sound() {
7+
System.out.println("Some sound");
8+
}
9+
}
10+
11+
class Dog extends Animal {
12+
@Override
13+
public void sound() {
14+
System.out.println("Bark");
15+
}
16+
}
17+
18+
class Cat extends Animal {
19+
@Override
20+
public void sound() {
21+
System.out.println("Meow");
22+
}
23+
}
24+
25+
public class AnimalDemo {
26+
public static void makeSound(List<? extends Animal> animals) {
27+
for (Animal animal : animals) {
28+
animal.sound();
29+
}
30+
}
31+
32+
public static void main(String[] args) {
33+
List<Dog> dogs = List.of(new Dog(), new Dog());
34+
List<Cat> cats = List.of(new Cat(), new Cat());
35+
36+
makeSound(dogs);
37+
makeSound(cats);
38+
}
39+
}
40+
41+
/*
42+
1. Classes:
43+
- `Animal` base class with method `sound()`.
44+
- `Dog` and `Cat` extend `Animal` and override `sound()` with specific behavior.
45+
46+
2. Upper-Bounded Wildcard:
47+
- Method signature: `makeSound(List<? extends Animal> animals)`
48+
- `? extends Animal` means:
49+
✔ You can pass a `List<Dog>` or `List<Cat>` or any subclass of `Animal`.
50+
✔ Read-only (safe to read as `Animal`), but you cannot safely add new elements to `animals`
51+
because compiler doesn’t know the exact subtype.
52+
53+
3. Logic:
54+
- For-each loop: `for (Animal animal : animals)` → safe because every element is guaranteed to be an `Animal`.
55+
- Calls `animal.sound()` which resolves to the overridden version (`Bark` for Dog, `Meow` for Cat).
56+
57+
4. Main Method:
58+
- `List.of(new Dog(), new Dog())` → immutable list of Dogs.
59+
- `List.of(new Cat(), new Cat())` → immutable list of Cats.
60+
- Both are passed to `makeSound()`, demonstrating polymorphism + upper-bounded wildcard flexibility.
61+
62+
✔ `? extends Animal` = accept a list of any subclass of Animal.
63+
✔ Safe to read elements as `Animal`, but you cannot add new elements.
64+
✔ Useful for covariant read-only operations.
65+
✔ Demonstrates polymorphism: Dogs bark, Cats meow, all via one generic method.
66+
*/

0 commit comments

Comments
 (0)