Claude
Skills
Sign in
Back

oop-polymorphism

Included with Lifetime
$97 forever

Use when implementing polymorphism and interfaces in object-oriented design. Use when creating flexible, extensible systems with interchangeable components.

Design

What this skill does


# OOP Polymorphism

Master polymorphism to create flexible, extensible object-oriented systems. This skill focuses on understanding and applying polymorphic behavior through interfaces, abstract classes, and runtime type substitution.

## Understanding Polymorphism

Polymorphism allows objects of different types to be treated uniformly through a common interface. It enables writing code that works with abstractions rather than concrete implementations.

### Interface-Based Polymorphism in Java

```java
// Common interface for all payment methods
public interface PaymentMethod {
    PaymentResult process(BigDecimal amount);
    boolean isValid();
    String getDisplayName();
}

// Concrete implementations
public class CreditCard implements PaymentMethod {
    private final String cardNumber;
    private final String cardholderName;
    private final String expiryDate;
    private final String cvv;

    public CreditCard(String cardNumber, String cardholderName, String expiryDate, String cvv) {
        this.cardNumber = cardNumber;
        this.cardholderName = cardholderName;
        this.expiryDate = expiryDate;
        this.cvv = cvv;
    }

    @Override
    public PaymentResult process(BigDecimal amount) {
        if (!isValid()) {
            return PaymentResult.failed("Invalid credit card");
        }

        // Credit card processing logic
        String transactionId = UUID.randomUUID().toString();
        System.out.println("Processing $" + amount + " via credit card ending in " +
            cardNumber.substring(cardNumber.length() - 4));

        return PaymentResult.success(transactionId, amount);
    }

    @Override
    public boolean isValid() {
        return cardNumber != null &&
               cardNumber.length() == 16 &&
               !isExpired(expiryDate);
    }

    @Override
    public String getDisplayName() {
        return "Credit Card ending in " + cardNumber.substring(cardNumber.length() - 4);
    }

    private boolean isExpired(String expiryDate) {
        // Expiry date validation logic
        return false;
    }
}

public class PayPal implements PaymentMethod {
    private final String email;
    private final String password;

    public PayPal(String email, String password) {
        this.email = email;
        this.password = password;
    }

    @Override
    public PaymentResult process(BigDecimal amount) {
        if (!isValid()) {
            return PaymentResult.failed("Invalid PayPal credentials");
        }

        String transactionId = UUID.randomUUID().toString();
        System.out.println("Processing $" + amount + " via PayPal account " + email);

        return PaymentResult.success(transactionId, amount);
    }

    @Override
    public boolean isValid() {
        return email != null && email.contains("@") && password != null;
    }

    @Override
    public String getDisplayName() {
        return "PayPal (" + email + ")";
    }
}

public class BankTransfer implements PaymentMethod {
    private final String accountNumber;
    private final String routingNumber;
    private final String accountHolderName;

    public BankTransfer(String accountNumber, String routingNumber, String accountHolderName) {
        this.accountNumber = accountNumber;
        this.routingNumber = routingNumber;
        this.accountHolderName = accountHolderName;
    }

    @Override
    public PaymentResult process(BigDecimal amount) {
        if (!isValid()) {
            return PaymentResult.failed("Invalid bank account");
        }

        String transactionId = UUID.randomUUID().toString();
        System.out.println("Processing $" + amount + " via bank transfer from " + accountHolderName);

        return PaymentResult.success(transactionId, amount);
    }

    @Override
    public boolean isValid() {
        return accountNumber != null &&
               routingNumber != null &&
               accountNumber.length() > 0;
    }

    @Override
    public String getDisplayName() {
        return "Bank Account (" + accountHolderName + ")";
    }
}

// Polymorphic usage
public class PaymentProcessor {
    private final List<PaymentMethod> paymentMethods;

    public PaymentProcessor() {
        this.paymentMethods = new ArrayList<>();
    }

    public void addPaymentMethod(PaymentMethod method) {
        paymentMethods.add(method);
    }

    public PaymentResult processPayment(BigDecimal amount) {
        // Try each payment method until one succeeds
        for (PaymentMethod method : paymentMethods) {
            if (method.isValid()) {
                System.out.println("Attempting payment with " + method.getDisplayName());
                PaymentResult result = method.process(amount);

                if (result.isSuccess()) {
                    return result;
                }
            }
        }

        return PaymentResult.failed("No valid payment method available");
    }

    public List<String> getAvailablePaymentMethods() {
        return paymentMethods.stream()
            .filter(PaymentMethod::isValid)
            .map(PaymentMethod::getDisplayName)
            .collect(Collectors.toList());
    }
}

// Usage - polymorphism in action
PaymentProcessor processor = new PaymentProcessor();
processor.addPaymentMethod(new CreditCard("1234567890123456", "John Doe", "12/25", "123"));
processor.addPaymentMethod(new PayPal("[email protected]", "secret"));
processor.addPaymentMethod(new BankTransfer("9876543210", "123456789", "John Doe"));

PaymentResult result = processor.processPayment(new BigDecimal("99.99"));
```

### Protocol-Based Polymorphism in Python

```python
from typing import Protocol, List, Optional
from abc import ABC, abstractmethod
from dataclasses import dataclass
import json

# Protocol defines the interface (structural typing)
class Serializable(Protocol):
    """Protocol for objects that can be serialized."""

    def to_dict(self) -> dict:
        """Convert to dictionary."""
        ...

    def to_json(self) -> str:
        """Convert to JSON string."""
        ...

# Another protocol
class Identifiable(Protocol):
    """Protocol for objects with an ID."""

    @property
    def id(self) -> str:
        """Get unique identifier."""
        ...

# Concrete implementations
@dataclass
class User:
    """User implementation with both protocols."""

    _id: str
    username: str
    email: str
    age: int

    @property
    def id(self) -> str:
        return self._id

    def to_dict(self) -> dict:
        return {
            'id': self._id,
            'username': self.username,
            'email': self.email,
            'age': self.age
        }

    def to_json(self) -> str:
        return json.dumps(self.to_dict())

@dataclass
class Product:
    """Product implementation with both protocols."""

    _id: str
    name: str
    price: float
    category: str

    @property
    def id(self) -> str:
        return self._id

    def to_dict(self) -> dict:
        return {
            'id': self._id,
            'name': self.name,
            'price': self.price,
            'category': self.category
        }

    def to_json(self) -> str:
        return json.dumps(self.to_dict())

@dataclass
class Order:
    """Order implementation."""

    _id: str
    user_id: str
    items: List[str]
    total: float

    @property
    def id(self) -> str:
        return self._id

    def to_dict(self) -> dict:
        return {
            'id': self._id,
            'user_id': self.user_id,
            'items': self.items,
            'total': self.total
        }

    def to_json(self) -> str:
        return json.dumps(self.to_dict())

# Polymorphic functions using protocols
def save_to_file(obj: Serializable, filename: str) -> None:
    """Save any serializable object to file."""
    with open(filename, 'w') as f:
        f.write(obj.to_json())

def get_id(obj: Identifiable) -> str:
    """Get ID from any identifiable object."""
    return obj.id

def serialize_batch(objects: List[Serializabl

Related in Design