17. జావా వారసత్వం (Inheritance), 'super' & Object Cosmic Superclass (Inheritance Mastery)

☕ Java (Java 21+ LTS) 🟢 Lesson 17 of 25 📂 Part 04: Core OOP & Exceptions (Page 2 of 5) ⏱️ 26 min read
📌 Covered in this lesson: IS-A రిలేషన్షిప్ & extends కీవర్డ్ · Single & Multilevel Inheritance · super() కన్‌స్ట్రక్టర్ కాల్స్ · java.lang.Object (Cosmic Superclass: toString, equals, hashCode)

ఆబ్జెక్ట్-ఓరియెంటెడ్ ప్రోగ్రామింగ్ (OOP) లో కోడ్ పునర్వినియోగానికి (Code Reusability) మరియు వాస్తవ ప్రపంచ సంబంధాల రూపకల్పనకు మూలస్తంభం వారసత్వం (Inheritance). ఇప్పటికే ఉన్న ఒక క్లాస్ లోని ఫీచర్లు మరియు ప్రవర్తనలను మరొక కొత్త క్లాస్ extends కీవర్డ్ ద్వారా స్వీకరించే పద్ధతినే వారసత్వం అంటారు. దీనిని టెక్నికల్ భాషలో "IS-A రిలేషన్షిప్" గా పిలుస్తారు (ఉదా: Car IS-A Vehicle). అయితే C++ లో ఉన్న బహుళ వారసత్వం (Multiple Inheritance) వల్ల ఉత్పన్నమయ్యే వినాశకరమైన 'డైమండ్ సమస్య' (Diamond Problem) ను జావా ఎలా పరిష్కరించింది? పేరెంట్ క్లాస్ కన్‌స్ట్రక్టర్లను మరియు ఓవర్‌రైడ్ చేయబడిన మెథడ్లను పిలవడానికి super కీవర్డ్ ఎలా ఉపయోగపడుతుంది? మరియు జావాలోని సమస్త క్లాసులకు ఆదిమ మూలపురుషుడైన java.lang.Object (Cosmic Superclass) యొక్క అంతర్గత ఆర్కిటెక్చర్ ఏమిటి? అనే కీలకమైన అంశాలను ఈ పాఠంలో ప్రాక్టికల్ విశ్లేషణలతో నేర్చుకుందాం.

వంశపారంపర్య DNA & స్మార్ట్‌ఫోన్ సిరీస్ అనాలజీ (The Family DNA Ancestry & Smartphone Generation Analogy):

  1. 1. Inheritance (వంశపారంపర్య జన్యువులు - Family Genetic Inheritance): తల్లిదండ్రుల నుండి పిల్లలకు కంటి రంగు, ఎత్తు, నడక వంటి శారీరక లక్షణాలు సహజంగానే సంక్రమిస్తాయి. పిల్లవాడు ఆ లక్షణాలను వారసత్వంగా తీసుకుంటూనే, అదనంగా తన సొంత నైపుణ్యాలను (New Skills) పెంపొందించుకుంటాడు. జావాలో ఒక సబ్‌క్లాస్ (Child) తన సూపర్ క్లాస్ (Parent) లోని ఫీల్డ్స్ మరియు మెథడ్లను నేరుగా పొంది, కొత్త ఫీచర్లను జోడించుకుంటుంది.
  2. 2. The Diamond Problem & Forbidden Multiple Inheritance (ఇద్దరు తల్లుల ఒకే ఆదేశ గందరగోళం): ఒక బిడ్డకు ఇద్దరు తల్లులు ఉండి, ఇద్దరూ ఒకే సమయంలో పరస్పర విరుద్ధమైన ఆదేశాలు జారీ చేస్తే బిడ్డ అయోమయంలో పడతాడు. C++ లో ఒక క్లాస్ ఒకేసారి రెండు వేర్వేరు పేరెంట్ క్లాసుల నుండి ఒకే పేరున్న మెథడ్‌ను ఇన్హెరిట్ చేసుకుంటే ఏది రన్ అవ్వాలో తెలియక అంబిగ్యుటీ వచ్చేది. జావా ఈ సంక్షోభాన్ని శాశ్వతంగా నివారించడానికి క్లాసుల స్థాయిలో 'మల్టిపుల్ ఇన్హెరిటెన్స్' ను కఠినంగా నిషేధించింది!
  3. 3. 'super' & java.lang.Object (కుటుంబ పెద్ద & విశ్వ మూలపురుషుడు - Family Elder & Cosmic Ancestor):
    • super: ఇంట్లో పిల్లవాడు తన తండ్రిని లేదా తల్లిని సంబోధించడానికి పిలిచే గౌరవప్రదమైన పిలుపు (పేరెంట్ కన్‌స్ట్రక్టర్ super(...) లేదా పేరెంట్ మెథడ్ super.process()).
    • java.lang.Object: భూమిపై ఉన్న ప్రతి మానవుడికీ ఒకే ఒక్క ఉమ్మడి ఆదిమ పూర్వీకుడు ఉన్నట్లుగా, జావాలోని ప్రతి ఒక్క క్లాస్ (మీరు స్వయంగా రాసినా లేదా జావా అంతర్నిర్మితమైనా) చివరికి java.lang.Object అనే విశ్వజనీన పేరెంట్ క్లాస్ నుండే ఉద్భవిస్తుంది!

ఈ పాఠం ముగిసేసరికి మీరు క్లాస్ హైరార్కీలను శాస్త్రీయంగా నిర్మించడం, పేరెంట్-చైల్డ్ కన్‌స్ట్రక్టర్ ఎగ్జిక్యూషన్ ఫ్లోను అర్థం చేసుకోవడం, మరియు ప్రొడక్షన్-గ్రేడ్ ఫిన్‌టెక్ పేమెంట్ గేట్‌వే ప్రాసెసింగ్ సిస్టమ్‌ను నిర్మించడంలో పరిపూర్ణ ప్రావీణ్యం సాధిస్తారు!

📑 ఈ పాఠంలో మీరు నేర్చుకునే అంశాలు (Table of Contents)
విభాగం A: వారసత్వ మూలాలు & ఆర్కిటెక్చర్
విభాగం B: 'super' & Object క్లాస్
విభాగం C: డెమోలు, ప్రాజెక్ట్ & పరీక్ష

1. వారసత్వం అంటే ఏమిటి? IS-A రిలేషన్షిప్ (Inheritance & IS-A Relationship)

జావాలో వారసత్వం (Inheritance) అనేది ఇప్పటికే ఉన్న ఒక క్లాస్ (Super Class / Parent Class) యొక్క ఫీల్డ్స్ మరియు మెథడ్లను మరొక కొత్త క్లాస్ (Sub Class / Child Class) వారసత్వంగా పొందే పద్ధతి. దీనికోసం మనం extends కీవర్డ్‌ను ఉపయోగిస్తాం.

// సూపర్ క్లాస్ (Parent)
public class Vehicle {
    String brand;
    void startEngine() { System.out.println("ఇంజిన్ ప్రారంభమైంది..."); }
}

// సబ్‌క్లాస్ (Child) - extends కీవర్డ్ ద్వారా Vehicle ఫీచర్లు పొందుతుంది
public class ElectricCar extends Vehicle {
    int batteryCapacityKWh;
    void chargeBattery() { System.out.println("ఛార్జింగ్ అవుతోంది..."); }
}

IS-A రిలేషన్షిప్ నియమం: ఒక క్లాస్‌ను మరొక క్లాస్‌కు వారసుడిగా చేసేముందు కచ్చితంగా "ఇది అది అవుతుందా?" (IS-A Test) అని ప్రశ్నించుకోవాలి:
• ElectricCar IS-A Vehicle ✅ (సరైన వారసత్వం)
• SavingAccount IS-A BankAccount ✅ (సరైన వారసత్వం)
• Car IS-A Engine ❌ (తప్పు! Car కు Engine ఉంటుంది - దీనిని HAS-A / Composition అంటారు).

2. సింగిల్, మల్టీలెవల్ & హైరార్కికల్ రకాలు (Types of Inheritance in Java)

క్లాసుల స్థాయిలో జావా 3 రకాల వారసత్వ నిర్మాణాలను సంపూర్ణంగా సమర్థిస్తుంది:

  • 1. సింగిల్ ఇన్హెరిటెన్స్ (Single Inheritance): ఒకే చైల్డ్ క్లాస్ ఒకే పేరెంట్ క్లాస్‌ను ఎక్స్‌టెండ్ చేసుకుంటుంది (ఉదా: B extends A).
  • 2. మల్టీలెవల్ ఇన్హెరిటెన్స్ (Multilevel Inheritance): గొలుసుకట్టు వారసత్వం. తాత ➔ తండ్రి ➔ కొడుకు క్రమంలో లక్షణాలు సంక్రమిస్తాయి (ఉదా: Device ➔ Phone ➔ SmartPhone).
  • 3. హైరార్కికల్ ఇన్హెరిటెన్స్ (Hierarchical Inheritance): ఒకే పేరెంట్ క్లాస్‌ను బహుళ చైల్డ్ క్లాసులు ఎక్స్‌టెండ్ చేసుకుంటాయి (ఉదా: Account ➔ SavingsAccount మరియు Account ➔ CurrentAccount).

3. Multiple Inheritance నిషేధం: Diamond Problem (Why Java Forbids Multiple Extends)

జావాలో ఒక క్లాస్ ఒకే సమయంలో రెండు లేదా అంతకంటే ఎక్కువ క్లాసులను ఎక్స్‌టెండ్ చేయలేదు (class C extends A, B రాయడం అసాధ్యం). దీనికి కారణం ప్రసిద్ధ డైమండ్ సమస్య (The Deadly Diamond of Death):

❌ డైమండ్ సమస్య విశ్లేషణ:

క్లాస్ A లో execute() అనే మెథడ్ ఉందనుకుందాం. క్లాస్ B మరియు క్లాస్ C రెండూ A ని ఎక్స్‌టెండ్ చేసి execute() ని తమదైన శైలిలో ఓవర్‌రైడ్ చేశాయి. ఇప్పుడు క్లాస్ D అనేది B మరియు C రెండింటినీ ఒకేసారి ఎక్స్‌టెండ్ చేస్తే, D ఆబ్జెక్ట్ d.execute() అని పిలిచినప్పుడు JVM కి B లోని మెథడ్ రన్ చేయాలో లేదా C లోని మెథడ్ రన్ చేయాలో అర్థం కాదు!

💡 జావా సృష్టికర్త జేమ్స్ గోస్లింగ్ భాషను సింపుల్‌గా, స్పష్టంగా మరియు బగ్-ఫ్రీగా ఉంచడానికి క్లాసుల స్థాయిలో ఈ డైమండ్ సమస్యను పూర్తిగా నిషేధించారు (ఇంటర్‌ఫేస్‌ల ద్వారా మాత్రమే సేఫ్‌గా మల్టిపుల్ ఇన్హెరిటెన్స్ సాధ్యమవుతుంది).

4. Memory Layout: చైల్డ్ ఆబ్జెక్ట్ లోపల పేరెంట్ స్టేట్ (Heap Architecture)

చాలామంది బిగినర్లు అనుకుంటారు: "సబ్‌క్లాస్ ఆబ్జెక్ట్ క్రియేట్ చేసినప్పుడు రెండు విడివిడి ఆబ్జెక్టులు హీప్‌లో పుడతాయి" అని. ఇది ముమ్మాటికీ అవాస్తవం!

హీప్ మెమరీలో సృష్టించబడేది ఒకే ఒక్క ఆబ్జెక్ట్. ఆ ఒక్క సబ్‌క్లాస్ ఆబ్జెక్ట్ యొక్క మెమరీ బ్లాక్ లోపలే సూపర్ క్లాస్ యొక్క అన్ని ప్రైవేట్ మరియు పబ్లిక్ ఫీల్డ్‌లు కూడా కేటాయించబడతాయి! ప్రైవేట్ ఫీల్డ్‌లను చైల్డ్ క్లాస్ నేరుగా పేరుతో పిలవలేకపోయినప్పటికీ, అవి చైల్డ్ ఆబ్జెక్ట్ మెమరీలోనే నివసిస్తూ పేరెంట్ పబ్లిక్ మెథడ్స్ ద్వారా పనిచేస్తాయి.

5. 'super' కీవర్డ్ 3 ప్రధాన విధులు (The 3 Faces of super)

సబ్‌క్లాస్ లోపల నుండి తన పేరెంట్ సూపర్ క్లాస్‌ను సంబోధించడానికి జావా అందించిన కీలకమైన రిఫరెన్స్ వేరియబుల్ super. ఇది 3 ప్రధాన పనులను చేస్తుంది:

  • 1. పేరెంట్ కన్‌స్ట్రక్టర్‌ను పిలవడం: సబ్‌క్లాస్ కన్‌స్ట్రక్టర్ మొదటి లైన్‌లో super(args...) రాయడం ద్వారా పేరెంట్ ఫీల్డ్స్‌ను ఇనిషియలైజ్ చేస్తాం.
  • 2. పేరెంట్ క్లాస్ వేరియబుల్‌ను సూచించడం: చైల్డ్ క్లాస్‌లో మరియు పేరెంట్ క్లాస్‌లో ఒకే పేరున్న వేరియబుల్ ఉన్నప్పుడు, పేరెంట్ వేరియబుల్‌ను స్పష్టంగా సూచించడానికి super.variableName వాడతాం.
  • 3. పేరెంట్ క్లాస్ మెథడ్‌ను ఇన్వోక్ చేయడం: చైల్డ్ క్లాస్‌లో మెథడ్‌ను ఓవర్‌రైడ్ చేసినప్పటికీ, ఒరిజినల్ పేరెంట్ మెథడ్ పనితనాన్ని కూడా అమలు చేయాలనుకుంటే super.methodName() వాడతాం.

6. Constructor Execution Order: Top-Down Flow (The Constructor Hierarchy)

ఒక చైల్డ్ ఆబ్జెక్ట్ సృష్టించబడినప్పుడు కన్‌స్ట్రక్టర్లు ఎలా ఎగ్జిక్యూట్ అవుతాయి?

గోల్డెన్ ఎగ్జిక్యూషన్ రూల్ (Top-Down Flow):
కన్‌స్ట్రక్టర్లు ఎల్లప్పుడూ అత్యున్నత పేరెంట్ (Grandparent / Object class) నుండి అత్యంత క్రింది చైల్డ్ క్లాస్ వరకు క్రమంగా అమలవుతాయి. చైల్డ్ క్లాస్ కన్‌స్ట్రక్టర్ బాడీ ఎగ్జిక్యూట్ అవ్వడానికి ముందే పేరెంట్ కన్‌స్ట్రక్టర్ తన పనిని సంపూర్ణంగా ముగించాలి!

మీరు సబ్‌క్లాస్ కన్‌స్ట్రక్టర్‌లో super() అని స్పష్టంగా రాయకపోయినా, జావా కంపైలర్ స్వయంగా మొదటి లైన్‌లో super(); ను అదృశ్యంగా చేర్చుతుంది!

7. java.lang.Object — విశ్వజనీన సూపర్ క్లాస్ (The Cosmic Superclass)

జావా ప్లాట్‌ఫారమ్‌లో java.lang.Object అనేది క్లాస్ హైరార్కీ యొక్క పరమ శిఖరం (Root of the Class Hierarchy). మీరు ఒక క్లాస్ రాసి ఏ క్లాస్‌నూ extends చేయకపోతే, జావా కంపైలర్ ఆటోమేటిక్‌గా extends Object అని జతచేస్తుంది.

ఈ విశ్వజనీన పేరెంట్ ఉండటం వల్లనే జావాలో ఏదైనా ఆబ్జెక్ట్‌ను Object obj = anyInstance; రూపంలో జెనరిక్‌గా నిల్వ చేసుకునే అద్భుతమైన సదుపాయం లభించింది.

8. Object క్లాస్ 11 మెథడ్స్ & equals/hashCode కాంట్రాక్ట్ (The Core Contract)

java.lang.Object క్లాస్‌లో ప్రతి జావా ఆబ్జెక్ట్‌కూ సంక్రమించే 11 ప్రాథమిక మెథడ్స్ ఉన్నాయి:

1. toString()            // ఆబ్జెక్ట్ యొక్క టెక్స్ట్ రిప్రజెంటేషన్
2. equals(Object obj)    // ఆబ్జెక్టుల సమానత్వ తనిఖీ
3. hashCode()            // హ్యాష్ టేబుల్స్ (HashMap/HashSet) కోసం 32-bit హాష్ నంబర్
4. getClass()            // రన్‌టైమ్ క్లాస్ మెటాడేటా
5. clone()               // ఆబ్జెక్ట్ క్లోనింగ్
6-10. wait(), notify(), notifyAll()  // త్రెడ్ సింక్రనైజేషన్ లాకింగ్
11. finalize()           // డిప్రికేట్ చేయబడిన పాత క్లీనప్
⚖️ The equals & hashCode Contract:
రెండు ఆబ్జెక్టులు equals() ప్రకారం సమానమైతే (a.equals(b) == true), వాటి యొక్క hashCode() లు తప్పనిసరిగా సమానంగా ఉండాలి! ఒకటి ఓవర్‌రైడ్ చేసి మరొకటి మర్చిపోతే HashMap మరియు HashSet లలో డేటా అదృశ్యమైపోయి తీవ్రమైన బగ్స్ వస్తాయి.

9. డెమో 1: Constructor Execution Hierarchy ట్రేస్ (Top-Down Execution Proof)

తాత ➔ తండ్రి ➔ కొడుకు క్రమంలో కన్‌స్ట్రక్టర్లు ఎలా అమలు చేయబడతాయో స్టెప్-బై-స్టెప్ టెలిమెట్రీతో పరిశీలిద్దాం:

InheritanceConstructorExecutionDemo.java
public class InheritanceConstructorExecutionDemo {

    // Level 1: Grandparent
    public static class HardwareDevice {
        String serialNumber;

        public HardwareDevice(String serial) {
            System.out.println("  1️⃣ [Executing HardwareDevice Constructor] Serial: " + serial);
            this.serialNumber = serial;
        }
    }

    // Level 2: Parent (extends HardwareDevice)
    public static class ComputingDevice extends HardwareDevice {
        int ramGigabytes;

        public ComputingDevice(String serial, int ram) {
            super(serial); // Explicit call to Grandparent constructor
            System.out.println("  2️⃣ [Executing ComputingDevice Constructor] RAM: " + ram + " GB");
            this.ramGigabytes = ram;
        }
    }

    // Level 3: Child (extends ComputingDevice)
    public static class CloudServerNode extends ComputingDevice {
        String regionZone;

        public CloudServerNode(String serial, int ram, String zone) {
            super(serial, ram); // Explicit call to Parent constructor
            System.out.println("  3️⃣ [Executing CloudServerNode Constructor] Zone: " + zone);
            this.regionZone = zone;
        }

        public void printSpecs() {
            System.out.printf("🖥️ Node Specs: Serial=%s | RAM=%d GB | Zone=%s%n",
                    serialNumber, ramGigabytes, regionZone);
        }
    }

    public static void main(String[] args) {
        System.out.println("=================================================");
        System.out.println("🏗️ INHERITANCE CONSTRUCTOR TOP-DOWN EXECUTION");
        System.out.println("=================================================
");

        System.out.println("Instantiating: new CloudServerNode('SRV-HYD-01', 64, 'ap-south-1a'):");
        CloudServerNode server = new CloudServerNode("SRV-HYD-01", 64, "ap-south-1a");

        System.out.println("
Final Initialized Object Specs:");
        server.printSpecs();

        System.out.println("
=================================================");
        System.out.println("✅ Top-Down Constructor Execution Flow Verified!");
        System.out.println("=================================================");
    }
}
Terminal Output:
=================================================
🏗️ INHERITANCE CONSTRUCTOR TOP-DOWN EXECUTION
=================================================

Instantiating: new CloudServerNode('SRV-HYD-01', 64, 'ap-south-1a'):
  1️⃣ [Executing HardwareDevice Constructor] Serial: SRV-HYD-01
  2️⃣ [Executing ComputingDevice Constructor] RAM: 64 GB
  3️⃣ [Executing CloudServerNode Constructor] Zone: ap-south-1a

Final Initialized Object Specs:
🖥️ Node Specs: Serial=SRV-HYD-01 | RAM=64 GB | Zone=ap-south-1a

=================================================
✅ Top-Down Constructor Execution Flow Verified!
=================================================

10. డెమో 2: java.lang.Object మెథడ్స్ కాంట్రాక్ట్ (toString, equals & hashCode)

java.lang.Object లోని డిఫాల్ట్ మెథడ్స్ vs ఓవర్‌రైడ్ చేయబడిన బిజినెస్ లాజిక్ మధ్య వ్యత్యాసాన్ని ధృవీకరించే ప్రాక్టికల్ డెమో:

ObjectClassContractDemo.java
import java.util.Objects;

public class ObjectClassContractDemo {

    // Overriding Object's core contracts properly
    public static class BankCustomer {
        private final String customerId;
        private final String panCard;
        private final String fullName;

        public BankCustomer(String id, String pan, String name) {
            this.customerId = id;
            this.panCard = pan;
            this.fullName = name;
        }

        @Override
        public String toString() {
            return "BankCustomer[ID=" + customerId + ", PAN=" + panCard + ", Name=" + fullName + "]";
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true; // Reference check
            if (obj == null || getClass() != obj.getClass()) return false; // Type check

            BankCustomer other = (BankCustomer) obj;
            // Equality based on unique business key: customerId & panCard
            return Objects.equals(this.customerId, other.customerId) &&
                   Objects.equals(this.panCard, other.panCard);
        }

        @Override
        public int hashCode() {
            return Objects.hash(customerId, panCard);
        }
    }

    public static void main(String[] args) {
        System.out.println("=================================================");
        System.out.println("📜 JAVA.LANG.OBJECT CORE CONTRACTS AUDIT");
        System.out.println("=================================================
");

        BankCustomer c1 = new BankCustomer("CUST-101", "ABCDE1234F", "Balaji Nemani");
        BankCustomer c2 = new BankCustomer("CUST-101", "ABCDE1234F", "Balaji Nemani");
        BankCustomer c3 = new BankCustomer("CUST-102", "XYZPQ9876K", "Karthik Verma");

        // 1. toString() verification
        System.out.println("1. Clean toString() Output:");
        System.out.println("   c1: " + c1);

        // 2. equals() verification
        System.out.println("
2. equals() Logic:");
        System.out.println("   c1 == c2 (Reference Check):         " + (c1 == c2) + " (Distinct Heap Objects)");
        System.out.println("   c1.equals(c2) (Content Equivalence): " + c1.equals(c2) + " (Same Customer ID & PAN)");
        System.out.println("   c1.equals(c3):                       " + c1.equals(c3));

        // 3. hashCode() contract verification
        System.out.println("
3. hashCode() Contract:");
        System.out.println("   c1.hashCode(): " + c1.hashCode());
        System.out.println("   c2.hashCode(): " + c2.hashCode());
        System.out.println("   Contract Satisfied (c1.equals(c2) => same hash): " + (c1.hashCode() == c2.hashCode()));

        System.out.println("=================================================");
    }
}
Terminal Output:
=================================================
📜 JAVA.LANG.OBJECT CORE CONTRACTS AUDIT
=================================================

1. Clean toString() Output:
   c1: BankCustomer[ID=CUST-101, PAN=ABCDE1234F, Name=Balaji Nemani]

2. equals() Logic:
   c1 == c2 (Reference Check):         false (Distinct Heap Objects)
   c1.equals(c2) (Content Equivalence): true (Same Customer ID & PAN)
   c1.equals(c3):                       false

3. hashCode() Contract:
   c1.hashCode(): 2049182390
   c2.hashCode(): 2049182390
   Contract Satisfied (c1.equals(c2) => same hash): true
=================================================

11. Capstone ప్రాజెక్ట్: ఎంటర్‌ప్రైజ్ ఫిన్‌టెక్ పేమెంట్ గేట్‌వే

ఈ అధ్యాయంలో నేర్చుకున్న అన్ని కాన్సెప్టులను (వారసత్వ ఆర్కిటెక్చర్, IS-A రిలేషన్షిప్, super() కన్‌స్ట్రక్టర్లు, మెథడ్ రీ-యూస్ మరియు java.lang.Object కాంట్రాక్ట్) సమగ్రంగా మిళితం చేస్తూ ఒక ఎంటర్‌ప్రైజ్ స్థాయి Fintech Multi-Rail Payment Gateway Engine ను నిర్మిద్దాం:

FintechPaymentGatewayEngine.java
import java.util.Objects;
import java.util.UUID;

public class FintechPaymentGatewayEngine {

    // Base Transaction Class (Superclass)
    public static class PaymentTransaction {
        private final String transactionId;
        private final double amount;
        private final String currency;
        private String status;

        public PaymentTransaction(double amount, String currency) {
            this.transactionId = "TXN-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
            this.amount = amount;
            this.currency = currency;
            this.status = "INITIATED";
        }

        public void processPayment() {
            this.status = "SUCCESSFUL";
            System.out.printf("  💳 Base Payment [%s] Settled: %s %,.2f%n", transactionId, currency, amount);
        }

        public String getTransactionId() { return transactionId; }
        public double getAmount() { return amount; }
        public String getStatus() { return status; }

        @Override
        public String toString() {
            return String.format("[%s | %s %.2f | %s]", transactionId, currency, amount, status);
        }
    }

    // Subclass 1: Credit Card Payment Rail
    public static class CreditCardTransaction extends PaymentTransaction {
        private final String maskedCardNumber;
        private final String cardNetwork;

        public CreditCardTransaction(double amount, String currency, String cardNum, String network) {
            super(amount, currency); // Pass core fields to parent
            this.maskedCardNumber = "XXXX-XXXX-XXXX-" + cardNum.substring(cardNum.length() - 4);
            this.cardNetwork = network;
        }

        @Override
        public void processPayment() {
            System.out.println("🔒 Authorizing 3D Secure OTP with Card Network: " + cardNetwork);
            super.processPayment(); // Leverage parent settlement
            System.out.println("   └─► Card debited: " + maskedCardNumber);
        }
    }

    // Subclass 2: UPI Instant Payment Rail
    public static class UpiTransaction extends PaymentTransaction {
        private final String vpaAddress;
        private final String upiRefNumber;

        public UpiTransaction(double amount, String currency, String vpa) {
            super(amount, currency);
            this.vpaAddress = vpa;
            this.upiRefNumber = "UPI" + System.currentTimeMillis();
        }

        @Override
        public void processPayment() {
            System.out.println("⚡ NPCI Instant Switch Routing to VPA: " + vpaAddress);
            super.processPayment();
            System.out.println("   └─► Bank RRN Ref: " + upiRefNumber);
        }
    }

    public static void main(String[] args) {
        System.out.println("=================================================");
        System.out.println("💰 ENTERPRISE FINTECH PAYMENT GATEWAY PIPELINE");
        System.out.println("=================================================
");

        // Rail 1: Credit Card
        System.out.println("1. Processing Card Rail Transaction:");
        PaymentTransaction cardTxn = new CreditCardTransaction(45000.0, "INR", "4111222233339842", "VISA");
        cardTxn.processPayment();
        System.out.println("   Transaction Dossier: " + cardTxn + "
");

        // Rail 2: UPI Instant
        System.out.println("2. Processing UPI Rail Transaction:");
        PaymentTransaction upiTxn = new UpiTransaction(2500.0, "INR", "balaji@okaxis");
        upiTxn.processPayment();
        System.out.println("   Transaction Dossier: " + upiTxn);

        System.out.println("
=================================================");
        System.out.println("✅ All multi-rail transactions settled securely via Inheritance!");
        System.out.println("=================================================");
    }
}
Terminal Output:
=================================================
💰 ENTERPRISE FINTECH PAYMENT GATEWAY PIPELINE
=================================================

1. Processing Card Rail Transaction:
🔒 Authorizing 3D Secure OTP with Card Network: VISA
  💳 Base Payment [TXN-8F12A09B] Settled: INR 45,000.00
   └─► Card debited: XXXX-XXXX-XXXX-9842
   Transaction Dossier: [TXN-8F12A09B | INR 45000.00 | SUCCESSFUL]

2. Processing UPI Rail Transaction:
⚡ NPCI Instant Switch Routing to VPA: balaji@okaxis
  💳 Base Payment [TXN-C401ED2A] Settled: INR 2,500.00
   └─► Bank RRN Ref: UPI1730548192001
   Transaction Dossier: [TXN-C401ED2A | INR 2500.00 | SUCCESSFUL]

=================================================
✅ All multi-rail transactions settled securely via Inheritance!
=================================================

12. ప్రొడక్షన్ పిట్‌ఫాల్స్, బెస్ట్ ప్రాక్టీసెస్ & 5 క్విజ్‌లు (Best Practices & Quizzes)

🚫 ప్రొడక్షన్‌లో నివారించాల్సిన 4 ఘోరమైన తప్పులు (Production Pitfalls):

  1. HAS-A రిలేషన్‌కు పొరపాటున ఇన్హెరిటెన్స్ వాడటం: కారుకు ఇంజిన్ ఉంటుందే తప్ప కారు ఇంజిన్ కాదు. Car extends Engine అని రాస్తే బలహీనమైన టైట్-కప్లింగ్ ఆర్కిటెక్చర్ ఏర్పడుతుంది. కంపోజిషన్ (Composition) వాడాలి.
  2. పేరెంట్ కన్‌స్ట్రక్టర్ లేకుండా సబ్‌క్లాస్ రాయడం: పేరెంట్ క్లాస్‌లో కేవలం పారామీటరైజ్డ్ కన్‌స్ట్రక్టర్ మాత్రమే ఉన్నప్పుడు, చైల్డ్ క్లాస్‌లో స్పష్టంగా super(args) రాయకపోతే కంపైలేషన్ ఎర్రర్ వస్తుంది.
  3. equals() ని ఓవర్‌రైడ్ చేసి hashCode() ని మర్చిపోవడం: ఇది జావాలోని అత్యంత భయంకరమైన కలెక్షన్ బగ్స్ లో ఒకటి. HashSet లో ఒకే వాల్యూ ఉన్న ఆబ్జెక్టులు రెండుసార్లు ఇన్సర్ట్ అవుతాయి!
  4. అనవసరమైన లోతైన వారసత్వ గొలుసులు (Deep Inheritance Trees): 4 లేదా 5 కంటే ఎక్కువ స్థాయిల వారసత్వం రాస్తే కోడ్‌ను మెయింటెయిన్ చేయడం అసాధ్యంగా మారుతుంది ("Favor composition over inheritance").

✨ ప్రొడక్షన్ గోల్డెన్ రూల్స్ (Golden Rules):

1. IS-A ఖరారు: కేవలం నిజమైన IS-A రిలేషన్షిప్ ఉన్నప్పుడు మాత్రమే extends వాడండి.
2. కన్‌స్ట్రక్టర్ గౌరవం: చైల్డ్ కన్‌స్ట్రక్టర్ మొదటి లైన్‌లోనే super(...) ఉపయోగించి పేరెంట్‌ను ఇనిషియలైజ్ చేయండి.
3. equals & hashCode: ఈ రెండింటినీ ఎల్లప్పుడూ ఒకే ఫీల్డ్‌ల ఆధారంగా జంటగా ఓవర్‌రైడ్ చేయండి.
4. ఫైనల్ రక్షణ: ఒక క్లాస్‌ను ఎవరూ ఎక్స్‌టెండ్ చేయకూడదనుకుంటే దాన్ని final class గా ప్రకటించండి.

🧠 మీ అవగాహనను పరీక్షించుకోండి (5 Interactive Quizzes):

ప్రశ్న 1: జావాలో క్లాసుల స్థాయిలో Multiple Inheritance ఎందుకు అనుమతించబడదు?

సమాధానం: డైమండ్ సమస్య (Diamond Problem) వల్ల వచ్చే కంపైలర్ అంబిగ్యుటీని నివారించడానికి.

ప్రశ్న 2: చైల్డ్ క్లాస్ ఆబ్జెక్ట్ సృష్టించినప్పుడు కన్‌స్ట్రక్టర్లు ఏ క్రమంలో ఎగ్జిక్యూట్ అవుతాయి?

సమాధానం: Top-Down ఆర్డర్ లో: అత్యున్నత పేరెంట్ క్లాస్ కన్‌స్ట్రక్టర్ మొదటగా ఎగ్జిక్యూట్ అయి, చివరగా చైల్డ్ క్లాస్ కన్‌స్ట్రక్టర్ పూర్తవుతుంది.

ప్రశ్న 3: 'super()' కాల్ సబ్‌క్లాస్ కన్‌స్ట్రక్టర్ లో ఎక్కడ ఉండాలి?

సమాధానం: తప్పనిసరిగా మొట్టమొదటి స్టేట్‌మెంట్ (First Line) గా మాత్రమే ఉండాలి.

ప్రశ్న 4: జావాలోని సమస్త క్లాసులకు అల్టిమేట్ పేరెంట్ క్లాస్ (Cosmic Superclass) ఏది?

సమాధానం: java.lang.Object క్లాస్.

ప్రశ్న 5: రెండు ఆబ్జెక్టులు 'a.equals(b) == true' అయితే వాటి hashCode ల పరిస్థితి ఏమిటి?

సమాధానం: జావా కాంట్రాక్ట్ ప్రకారం వాటి యొక్క hashCode లు తప్పనిసరిగా సమానం (Must be Equal) కావాలి.

← మునుపటి పాఠం: 16. Encapsulation & Records తర్వాతి పాఠం: 18. Polymorphism & Overriding →