Learning Inheritance and Basic OOP from Real Banking Projects (Back in 2010)
Around 2010, I spent most of my days working as a Java and C developer in the electronic payment industry. At that time, things were very different compared to today.
There were no fancy AI coding assistants.
No Stack Overflow answers for every problem.
And debugging production issues sometimes meant sitting next to a physical EDC terminal at 2 AM.
Most of my work involved:
- Java backend systems
- ISO8583 transaction processing
- EDC/POS terminal development in C
- Payment switching integrations
- Host-to-host communication
- Bank certification testing
One of the most interesting experiences was integrating payment networks such as China UnionPay.
At first, the project looked simple:
Just send transaction messages and receive responses
But after a few weeks, I realized payment integration is actually a perfect example of why Object-Oriented Programming (OOP) matters.
Especially:
- Encapsulation
- Inheritance
- Polymorphism
- Abstraction
Without proper design, the code quickly becomes impossible to maintain.
The Problem We Faced
In payment systems, every network has slightly different rules.
For example:
| Network | Special Rules |
|---|---|
| Visa | Specific settlement fields |
| MasterCard | Different reversal handling |
| China UnionPay | Custom field mapping and MAC validation |
| Local Switch | Proprietary message structure |
At the beginning, many developers create separate code for every integration.
Something like this:
if(network.equals("VISA")) {
// visa logic
}
else if(network.equals("MASTERCARD")) {
// mastercard logic
}
else if(network.equals("CUP")) {
// unionpay logic
}
Looks easy.
But after several years?
Disaster.
The code becomes:
- hard to maintain
- difficult to test
- risky to modify
- painful during certification
That was when inheritance became extremely useful.
Basic OOP Design
Instead of duplicating code, we created a base transaction class.
public abstract class BaseTransaction {
protected String terminalId;
protected String merchantId;
protected double amount;
public BaseTransaction(String terminalId,
String merchantId,
double amount) {
this.terminalId = terminalId;
this.merchantId = merchantId;
this.amount = amount;
}
public void connect() {
System.out.println("Connecting to payment host...");
}
public abstract void buildMessage();
public abstract void send();
}
This class contains common behavior shared by all payment networks.
Every network:
- needs connection
- needs transaction amount
- needs terminal ID
- needs message building
But the implementation details are different.
That is where inheritance comes in.
China UnionPay Integration Example
Now let’s create a specialized class for China UnionPay.
public class UnionPayTransaction extends BaseTransaction {
public UnionPayTransaction(String terminalId,
String merchantId,
double amount) {
super(terminalId, merchantId, amount);
}
@Override
public void buildMessage() {
System.out.println("Building CUP ISO8583 message...");
System.out.println("Adding Field 60 and MAC validation...");
}
@Override
public void send() {
System.out.println("Sending transaction to China UnionPay host...");
}
}Now the design becomes much cleaner.
Instead of creating giant if-else blocks everywhere, every payment network simply extends the base class.
Using the Class
public class Main {
public static void main(String[] args) {
BaseTransaction trx = new UnionPayTransaction(
"TERM001",
"MERCHANT001",
100000
);
trx.connect();
trx.buildMessage();
trx.send();
}
}
Output:
Connecting to payment host...
Building CUP ISO8583 message...
Adding Field 60 and MAC validation...
Sending transaction to China UnionPay host...This is a simple example, but the concept is very powerful.
Why This Matters in Real Projects
Back in 2010, our payment systems handled:
- purchase transactions
- reversals
- settlement
- batch upload
- key exchange
- EMV processing
- network management messages
Without proper OOP design, adding a new network could break existing integrations.
Inheritance helped us:
- reuse common logic
- reduce duplicated code
- isolate network-specific behavior
- speed up certification testing
- make debugging easier
And trust me, debugging payment systems at midnight during production deployment is already stressful enough.
Good architecture saves lives.
Well… maybe not lives.
But definitely weekends.
My Experience as a Java and C Developer
One interesting thing about working in both Java and C is that you start appreciating architecture differently.
In C development for EDC terminals:
- memory management mattered
- buffer handling mattered
- communication protocols mattered
- performance mattered
A small mistake could crash the terminal.
Meanwhile in Java backend systems:
- scalability mattered
- thread handling mattered
- transaction consistency mattered
- integration design mattered
Java gave flexibility.
C gave discipline.
Combining both experiences taught me something important:
Clean design is more valuable than clever code.
A junior developer often focuses on making code work.
A senior developer focuses on making code maintainable for the next 5 years.
That mindset changed how I built systems afterward.
Final Thoughts
When learning OOP, many tutorials use examples like:
- Animal
- Dog
- Cat
- Vehicle
- Car
Those are fine for beginners.
But real-world software engineering becomes much more interesting when you apply OOP to actual business problems.
Payment integration taught me that inheritance is not just theory.
It is a practical tool that helps teams:
- move faster
- reduce bugs
- simplify integrations
- survive long-term maintenance
And honestly?
Some of the code written back in 2010 is probably still running somewhere in production today.
That is both impressive…
and slightly terrifying.
If you’d like to explore more of my notes, feel free to check out my other sections on code, databases, and even management – all still connected to the broader world of technology.
That’s all for now, folks! Keep learning, keep building, and most importantly enjoy the journey! 🥰😍