A flexible payment system should be designed using abstraction and polymorphism so that new payment methods can be added without changing existing code. An interface defines the common payment contract, while an abstract class can provide shared functionality such as validation, logging, or transaction tracking. This approach follows the Open/Closed Principle and promotes maintainability.
Key Points: • Use an interface to define common payment operations such as pay() and refund(). • Use an abstract class to implement shared behavior and reduce code duplication. • Each payment method implements its own processing logic while maintaining a common contract.
Example: In an e-commerce application, customers may choose Credit Card, PayPal, or Cryptocurrency payments. The checkout service interacts only with the Payment interface and does not need to know the specific implementation details of each payment type.
Code Example:
interface PaymentMethod {
void pay(double amount);
void refund(double amount);
}abstract class AbstractPayment
implements PaymentMethod {
protected void logTransaction(
String message) {
System.out.println(message);
}
}
class CreditCardPayment
extends AbstractPayment {
@Override
public void pay(double amount) {
logTransaction(
"Credit Card Payment: "
+ amount);
}
@Override
public void refund(double amount) {
logTransaction(
"Credit Card Refund: "
+ amount);
}
}
class PayPalPayment
extends AbstractPayment {
@Override
public void pay(double amount) {
logTransaction(
"PayPal Payment: "
+ amount);
}
@Override
public void refund(double amount) {
logTransaction(
"PayPal Refund: "
+ amount);
}
}
class CryptoPayment
extends AbstractPayment {
@Override
public void pay(double amount) {
logTransaction(
"Crypto Payment: "
+ amount);
}
@Override
public void refund(double amount) {
logTransaction(
"Crypto Refund: "
+ amount);
}
}Benefits: • Supports polymorphic payment processing. • Easy to add new payment methods. • Reduces code duplication through abstraction. • Follows SOLID design principles. • Improves maintainability and scalability.
Interview Tip: A concise interview answer is: I would define a PaymentMethod interface containing common operations such as pay() and refund(), then use an abstract class for shared functionality. Specific payment types like CreditCardPayment, PayPalPayment, and CryptoPayment implement their own logic. This design leverages polymorphism, follows the Open/Closed Principle, and makes the system easy to extend with new payment methods.