Practical Polymorphism
Real-World Polymorphism Applications
Polymorphism is not just a theoretical concept but a practical tool for solving complex software design challenges. This section explores real-world applications and advanced techniques.
Generic Programming with Polymorphism
Generic programming allows creating flexible, reusable code that works with different types.
public class GenericRepository<T> {
private List<T> items = new ArrayList<>();
public void add(T item) {
items.add(item);
}
public T get(int index) {
return items.get(index);
}
public void processAll(Consumer<T> processor) {
items.forEach(processor);
}
}
// Usage example
public class User {
private String name;
// Constructor, getters, setters
}
public class Main {
public static void main(String[] args) {
GenericRepository<User> userRepository = new GenericRepository<>();
userRepository.add(new User("Alice"));
userRepository.processAll(user -> System.out.println(user.getName()));
}
}
Polymorphic Collections
Collections in Java heavily rely on polymorphic principles:
classDiagram
Collection <|-- List
Collection <|-- Set
List <|.. ArrayList
List <|.. LinkedList
Set <|.. HashSet
Set <|.. TreeSet
class Collection {
+add(E element)
+remove(Object o)
}
Advanced Polymorphism Techniques
Functional Interfaces and Lambda Expressions
Java 8+ introduced functional interfaces that enable polymorphic behavior through lambda expressions:
@FunctionalInterface
interface MathOperation {
int operate(int a, int b);
}
public class Calculator {
public static int calculate(int a, int b, MathOperation operation) {
return operation.operate(a, b);
}
public static void main(String[] args) {
// Different implementations through lambdas
MathOperation addition = (a, b) -> a + b;
MathOperation multiplication = (a, b) -> a * b;
System.out.println("Addition: " + calculate(5, 3, addition));
System.out.println("Multiplication: " + calculate(5, 3, multiplication));
}
}
Technique |
Performance Impact |
Use Case |
Method Overriding |
Slight runtime overhead |
Flexible behavior |
Interface Implementation |
Minimal performance cost |
Loose coupling |
Generic Types |
Compile-time type safety |
Type-flexible algorithms |
Lambda Expressions |
Efficient for functional programming |
Functional-style operations |
Error Handling with Polymorphic Exceptions
public abstract class BaseException extends Exception {
public abstract void handleError();
}
public class NetworkException extends BaseException {
@Override
public void handleError() {
System.out.println("Handling network-specific error");
}
}
public class DatabaseException extends BaseException {
@Override
public void handleError() {
System.out.println("Handling database-specific error");
}
}
public class ErrorHandler {
public static void processError(BaseException exception) {
exception.handleError();
}
}
Best Practices for Practical Polymorphism
- Use interfaces for defining contracts
- Prefer composition over inheritance
- Keep classes and methods focused
- Leverage functional interfaces
- Consider performance implications
Real-World Design Example
public interface DataSource {
void connect();
void disconnect();
List<String> fetchData();
}
public class DatabaseDataSource implements DataSource {
public void connect() { /* Database connection logic */ }
public void disconnect() { /* Database disconnection logic */ }
public List<String> fetchData() { /* Fetch from database */ }
}
public class APIDataSource implements DataSource {
public void connect() { /* API connection logic */ }
public void disconnect() { /* API disconnection logic */ }
public List<String> fetchData() { /* Fetch from API */ }
}
public class DataProcessor {
private DataSource dataSource;
public DataProcessor(DataSource dataSource) {
this.dataSource = dataSource;
}
public void processData() {
dataSource.connect();
List<String> data = dataSource.fetchData();
// Process data
dataSource.disconnect();
}
}
Conclusion
Practical polymorphism enables developers to create flexible, maintainable, and extensible software architectures. By understanding and applying these techniques, you can write more robust and adaptable code.
Explore advanced polymorphism techniques with LabEx's interactive Java programming environments to enhance your software design skills.