23. OOP పిల్లర్స్ — ఇన్హెరిటెన్స్, ఎన్క్యాప్సులేషన్ & పాలిమార్ఫిజమ్
super() మరియు Method Resolution Order (MRO) డైమండ్ ప్రాబ్లమ్ను C3 Linearization ద్వారా ఎలా పరిష్కరిస్తాయి, ప్రైవేట్ వేరియబుల్స్ తెరవెనుక నేమ్ మ్యాంగ్లింగ్ (Name Mangling) ఎలా జరుగుతుంది, @property డెకరేటర్లతో క్లీన్ పైథానిక్ గెట్టర్స్/సెట్టర్స్ ఎలా రాయాలి, మరియు abc మాడ్యూల్ ద్వారా బలమైన కాంట్రాక్ట్ ఇంటర్ఫేస్లను ఎలా రూపొందించాలో ప్రొడక్షన్ ప్రమాణాలతో నేర్చుకుందాం.
1 ఆబ్జెక్ట్ ఓరియెంటెడ్ ప్రోగ్రామింగ్ 4 ప్రధాన స్తంభాలు (The 4 Pillars of OOP)
ప్రపంచ స్థాయి సాఫ్ట్వేర్ ఆర్కిటెక్చర్లు అన్నీ నాలుగు మౌలిక సిద్ధాంతాలపై ఆధారపడి నిర్మించబడతాయి:
| OOP పిల్లర్ | నిర్వచనం & ప్రధాన లక్ష్యం | రియల్-వరల్డ్ అనాలజీ |
|---|---|---|
| 1. Encapsulation (నిక్షిప్తీకరణ) | డేటా (Fields) మరియు దానిపై పనిచేసే మెథడ్స్ను ఒకే యూనిట్గా బంధించి, బయటి అనధికార మార్పుల నుండి రక్షించడం. | మెడిసిన్ క్యాప్సూల్ (లోపలి ఔషధాలు బయటి వాతావరణం నుండి సురక్షితంగా ఉంటాయి). |
| 2. Abstraction (సారాంశీకరణ) | క్లిష్టమైన అంతర్గత పనితీరును దాచిపెట్టి, కేవలం అవసరమైన సులభతరమైన ఇంటర్ఫేస్ను మాత్రమే బయటకు ప్రదర్శించడం. | కార్ డ్రైవింగ్ పెడల్ (ఆక్సిలరేటర్ నొక్కితే చాలు, ఇంజిన్ ఇంజెక్షన్ అంతర్గత సంక్లిష్టత డ్రైవర్కు అవసరం లేదు). |
| 3. Inheritance (వారసత్వం) | ఇప్పటికే ఉన్న బేస్ క్లాస్ లక్షణాలను మరియు ప్రవర్తనలను కొత్త క్లాస్లోకి విస్తరింపజేయడం ("is-a" సంబంధం). | తల్లిదండ్రుల నుండి పిల్లలకు జన్యుపరమైన లక్షణాలు సంక్రమించడం. |
| 4. Polymorphism (బహురూపత) | ఒకే ఇంటర్ఫేస్ లేదా మెథడ్ పేరు ద్వారా విభిన్న రకాల ఆబ్జెక్టులు వాటికి తగినట్లుగా ప్రత్యేకంగా స్పందించే సామర్థ్యం. | ఒకే సౌండ్ కంట్రోలర్ ద్వారా స్పీకర్, హెడ్ఫోన్, బ్లూటూత్ డివైజ్లు వేర్వేరుగా స్పందించడం. |
2 ఇన్హెరిటెన్స్ (Inheritance) — "is-a" రిలేషన్షిప్ ఆర్కిటెక్చర్
ఒక సాధారణ క్లాస్ (Base Class లేదా Parent Class) లోని ఫీచర్లను మరొక ప్రత్యేక క్లాస్ (Derived Class లేదా Child Class) పొందడాన్ని ఇన్హెరిటెన్స్ అంటారు. పేరెంట్ క్లాస్లో రాసిన కోడ్ను చైల్డ్ క్లాస్ ఉచితంగా పొందుతుంది:
- కోడ్ పునర్వినియోగం (DRY Principle): పది వేర్వేరు వాహనాలకు (కారు, బైక్, ట్రక్) సంబంధించిన కామన్ ఫీచర్లను (ఇంజిన్ స్టార్ట్, బ్రేక్ వేయడం) ఒక్కసారి బేస్ క్లాస్లో రాస్తే, అన్ని చైల్డ్ క్లాసులు వాటిని మళ్లీ రాయకుండా వాడుకోగలవు.
- "is-a" సంబంధం: ఇన్హెరిటెన్స్ వర్తింపజేసే ముందు ఎల్లప్పుడూ ప్రశ్నించుకోవాలి — "కారు అనేది ఒక వాహనమా?" (Car is a Vehicle? -> అవును). అప్పుడే ఇన్హెరిటెన్స్ ఉపయోగించాలి. ఒకవేళ "కారుకు ఒక ఇంజిన్ ఉందా?" (Car has an Engine? -> Composition) అయితే ఇన్హెరిటెన్స్ వాడకూడదు!
3 మెథడ్ ఓవర్రైడింగ్ (Method Overriding)
పేరెంట్ క్లాస్ అందించిన డిఫాల్ట్ ప్రవర్తన చైల్డ్ క్లాస్కు సరిపోకపోతే, చైల్డ్ క్లాస్ అదే పేరుతో కొత్త మెథడ్ను డిఫైన్ చేసి పేరెంట్ మెథడ్ను రీప్లేస్ చేయవచ్చు. దీనిని Method Overriding అంటారు:
మెథడ్ ఓవర్రైడింగ్ యొక్క ముఖ్య నియమాలు:
- చైల్డ్ క్లాస్ మెథడ్ పేరు మరియు పేరెంట్ క్లాస్ మెథడ్ పేరు ఖచ్చితంగా ఒకేలా ఉండాలి.
- రన్టైమ్లో పైథాన్ డైనమిక్ బైండింగ్ ద్వారా ఆబ్జెక్ట్ రకాన్ని బట్టి అత్యంత నిర్దిష్టమైన (Most Specific) చైల్డ్ క్లాస్ మెథడ్ను ముందుగా పిలుస్తుంది.
- పేరెంట్ మెథడ్ పూర్తిగా వద్దనుకుంటే ఓవర్రైడ్ చేయవచ్చు, లేదా పేరెంట్ పనికి అదనపు ఫీచర్ జోడించాలంటే
super()ను పిలిచి కొనసాగించవచ్చు.
4 super() ఫంక్షన్ మెకానిక్స్
చైల్డ్ క్లాస్ స్వంత __init__ ను కలిగి ఉన్నప్పుడు, అది పేరెంట్ క్లాస్ యొక్క __init__ ను ఓవర్రైడ్ చేస్తుంది. దీనివల్ల పేరెంట్ క్లాస్ వేరియబుల్స్ ఇనిషియలైజ్ కావు. పేరెంట్ క్లాస్ కన్స్ట్రక్టర్ లేదా మెథడ్ను చైల్డ్ క్లాస్ నుండి సేఫ్గా పిలవడానికి super() ఫంక్షన్ను ఉపయోగిస్తాము:
సాంప్రదాయకంగా
ParentClass.__init__(self, name) అని క్లాస్ పేరును హార్డ్కోడ్ చేసి పిలిచేవారు. కానీ భవిష్యత్తులో క్లాస్ పేరు మారినా లేదా మల్టిపుల్ ఇన్హెరిటెన్స్ వచ్చినప్పుడు అది విఫలమవుతుంది. super().__init__(name) అని రాస్తే పైథాన్ స్వయంగా MRO ప్రకారం సరైన పేరెంట్ క్లాస్ను డైనమిక్గా పిలుస్తుంది (మరియు self ను కూడా మనం అందించాల్సిన అవసరం లేదు!).
5 మల్టిపుల్ ఇన్హెరిటెన్స్, డైమండ్ ప్రాబ్లమ్ & MRO (C3 Linearization)
జావా వంటి భాషలు మల్టిపుల్ ఇన్హెరిటెన్స్ను (ఒక క్లాస్ బహుళ క్లాసులను నేరుగా ఇన్హెరిట్ చేసుకోవడం) అనుమతించవు, కానీ పైథాన్ పూర్తి మల్టిపుల్ ఇన్హెరిటెన్స్ను సమర్థిస్తుంది. అయితే దీనివల్ల ప్రసిద్ధ Diamond Problem ఏర్పడే అవకాశం ఉంది (ఉదాహరణకు A అనే క్లాస్ నుండి B మరియు C పుట్టి, ఆ రెండింటి నుండి D పుట్టినప్పుడు — B మరియు C రెండింటిలోనూ ఒకే పేరుతో ఉన్న మెథడ్ను D పిలిస్తే ఏది రన్ కావాలి?).
C3 Linearization అల్గారిథమ్ & MRO ప్రాధాన్యత సూత్రాలు:
పైథాన్ ఈ గందరగోళాన్ని నివారించడానికి C3 Linearization Algorithm ను ఉపయోగిస్తుంది. దీని ఆధారంగా Method Resolution Order (MRO) నిర్ధారించబడుతుంది (ClassName.mro() ద్వారా చూడవచ్చు). ఇది 3 ప్రధాన నియమాలను పాటిస్తుంది:
- చైల్డ్ క్లాస్ ఎల్లప్పుడూ పేరెంట్ క్లాస్ కంటే ముందే పరిశీలించబడుతుంది.
- మల్టిపుల్ పేరెంట్స్ ఉన్నప్పుడు, క్లాస్ డిక్లరేషన్లో ఇచ్చిన ఎడమ నుండి కుడి క్రమం (Left-to-Right order:
class D(B, C)లో B ముందూ, C తర్వాత) గౌరవించబడుతుంది. - Monotonicity: ఒక క్లాస్ యొక్క MRO దాని చైల్డ్ క్లాస్ యొక్క MRO క్రమానికి విరుద్ధంగా ఉండకూడదు. ఒకవేళ విరుద్ధమైన ఆర్డర్ ఏర్పడితే పైథాన్ కంపైలేషన్ సమయంలోనే
TypeError: Cannot create a consistent method resolution order (MRO)అని నిరోధిస్తుంది.
6 ఎన్క్యాప్సులేషన్: ప్రైవేట్ వేరియబుల్స్ & నేమ్ మ్యాంగ్లింగ్ (Name Mangling)
పైథాన్లో C++ లేదా Java లాంటి కఠినమైన private కీవర్డ్స్ లేవు. అయితే పైథాన్ కమ్యూనిటీ స్పష్టమైన కన్వెన్షన్లు మరియు రన్టైమ్ ట్రాన్స్ఫార్మేషన్లను కలిగి ఉంది:
| యాక్సెస్ లెవల్ | సింటాక్స్ | ఉద్దేశం మరియు ప్రవర్తన |
|---|---|---|
| Public | self.balance |
ఎక్కడి నుంచైనా స్వేచ్ఛగా చదవవచ్చు మరియు మార్చవచ్చు. |
| Protected | self._balance |
ఒక సింగిల్ అండర్స్కోర్. ఇది కేవలం కన్వెన్షన్ మాత్రమే (హెచ్చరిక: "ఈ వేరియబుల్ను బయట నేరుగా ముట్టుకోవద్దు"). పైథాన్ దీనికి ఎలాంటి యాక్సెస్ రెస్ట్రిక్షన్ విధించదు. |
| Private (Mangled) | self.__balance |
రెండు లీడింగ్ అండర్స్కోర్లు. పైథాన్ రన్టైమ్ దీని పేరును అంతర్గతంగా _ClassName__balance గా మారుస్తుంది (Name Mangling). దీనివల్ల సబ్క్లాస్లలో యాక్సిడెంటల్ ఓవర్రైడింగ్ జరగదు. |
7 పైథానిక్ గెట్టర్స్ & సెట్టర్స్: @property & @cached_property
Java లో లాగా get_balance() మరియు set_balance(amt) అని అగ్లీ మెథడ్స్ రాయడం పైథానిక్ శైలి కాదు. పైథాన్లో @property డెకరేటర్ను ఉపయోగించి మెథడ్ను సాధారణ అట్రిబ్యూట్ లాగా (obj.balance) యాక్సెస్ చేయవచ్చు, అదే సమయంలో వాలిడేషన్ లాజిక్ను అమలు చేయవచ్చు:
- Getter (
@property): మెథడ్ను బ్రాకెట్లు లేకుండా వేరియబుల్ లాగా చదవడానికి వీలు కల్పిస్తుంది. - Setter (
@attr.setter): వినియోగదారుడు విలువను మార్చాలని ప్రయత్నించినప్పుడు వాలిడేషన్ చేసి (ఉదా: బ్యాలెన్స్ నెగెటివ్ ఉండకూడదు) మాత్రమే అనుమతిస్తుంది. - Deleter (
@attr.deleter):del obj.attrచేసినప్పుడు క్లీనప్ లేదా రీసెట్ చేయడానికి వాడుతారు. @functools.cached_property(Modern Python 3.8+): భారీ డేటా గణనలు లేదా రిమోట్ డేటాబేస్ నుండి లోడ్ చేసే ప్రాపర్టీలకు గేమ్ ఛేంజర్. ఇది మొదటిసారి మాత్రమే మెథడ్ను రన్ చేసి ఫలితాన్ని ఆబ్జెక్ట్ యొక్క__dict__లో క్యాష్ చేస్తుంది; ఆ తర్వాత ఎన్నిసార్లు పిలిచినా ఎటువంటి అదనపు సమయం తీసుకోకుండా తక్షణమే విలువను అందిస్తుంది!
8 పాలిమార్ఫిజమ్ (Polymorphism), డక్ టైపింగ్ & Static Protocols
పైథాన్లో పాలిమార్ఫిజమ్ చాలా సహజంగా మరియు అద్భుతంగా పనిచేస్తుంది. ప్రసిద్ధ పైథానిక్ సూత్రం:
అంటే ఒక ఫంక్షన్కు వచ్చే ఆబ్జెక్ట్ ఏ క్లాస్కు చెందినదో పరిశీలించకుండా, దానికి మనం కోరుకున్న మెథడ్ (ఉదా: process_payment()) ఉందా లేదా అనేది మాత్రమే చూస్తాము.
ఆధునిక పైథాన్ 3.8+: Structural Subtyping vs Nominal Subtyping (PEP 544):
సాంప్రదాయ స్టాటిక్ లాంగ్వేజెస్ (Java, C++) లో Nominal Subtyping ఉంటుంది — అంటే రెండు క్లాసులు ఒకే రకమైన మెథడ్లను కలిగి ఉన్నప్పటికీ, అవి స్పష్టంగా ఒక కామన్ ఇంటర్ఫేస్ను implements చేస్తే తప్ప కంపైలర్ వాటిని ఒకే రకంగా అంగీకరించదు. కానీ మోడ్రన్ పైథాన్ Structural Subtyping (Protocols) ను సమర్థిస్తుంది:
typing.Protocolద్వారా మీరు ఒక రూల్ లేదా కాంట్రాక్ట్ను డిక్లేర్ చేయవచ్చు.- ఏదైనా యూజర్ క్లాస్ ఆ ప్రొటోకాల్లోని మెథడ్స్ను అమలు చేస్తే చాలు — అది ఆ ప్రొటోకాల్ను ఇన్హెరిట్ చేసుకోకపోయినా, Mypy / Pyright ఆటోమేటిక్గా దానిని సరైన టైప్గా గుర్తిస్తాయి!
@runtime_checkableడెకరేటర్ను ఉపయోగించడం ద్వారాisinstance(obj, MyProtocol)ను రన్టైమ్లో కూడా సురక్షితంగా తనిఖీ చేయవచ్చు.
9 అబ్స్ట్రాక్ట్ బేస్ క్లాసెస్ (Abstract Base Classes - ABC)
పెద్ద ఎంటర్ప్రైజ్ సిస్టమ్స్లో టీమ్లోని డెవలపర్లు నిర్దిష్టమైన రూల్స్ను తప్పనిసరిగా అమలు చేసేలా బలవంతం చేయడానికి (Enforce Interface Contracts) పైథాన్ యొక్క abc మాడ్యూల్ను ఉపయోగిస్తాము:
అబ్స్ట్రాక్ట్ క్లాసెస్ యొక్క ప్రాముఖ్యత మరియు నియమాలు:
from abc import ABC, abstractmethod: బేస్ క్లాస్ABCనుండి డిరైవ్ కావాలి.@abstractmethodరక్షణ: ఏ మెథడ్ ముందైతే@abstractmethodఉంటుందో, చైల్డ్ క్లాస్ ఆ మెథడ్ను తప్పనిసరిగా ఇంప్లిమెంట్ చేయాలి! ఒక్క మెథడ్ మర్చిపోయినా కూడా పైథాన్ ఆ చైల్డ్ క్లాస్ ఆబ్జెక్ట్ను క్రియేట్ చేయనివ్వదు (TypeError: Can't instantiate abstract class with abstract method).- ఇంటర్ఫేస్ మరియు బేస్ ఇంప్లిమెంటేషన్ కలయిక: అబ్స్ట్రాక్ట్ క్లాస్ కేవలం ఎంప్టీ మెథడ్స్ మాత్రమే కాకుండా, కామన్ లాజిక్ ఉన్న కాంక్రీట్ మెథడ్స్ను కూడా కలిగి ఉండవచ్చు.
- ఎంటర్ప్రైజ్ ఆర్కిటెక్చర్ బెనిఫిట్: కోర్ సిస్టమ్ బేస్ క్లాస్ ఇంటర్ఫేస్పై మాత్రమే ఆధారపడుతుంది; భవిష్యత్తులో కొత్త ప్లగిన్లు లేదా గేట్వేలు (ఉదా: ApplePay, Crypto) వచ్చినప్పుడు కోర్ కోడ్లో ఒక్క లైన్ కూడా మార్చకుండా సులభంగా ప్లగ్ చేయవచ్చు (Open/Closed Principle).
10 కోడ్ డెమో 1: పేమెంట్ గేట్వే ఆర్కిటెక్చర్ (ABC & Polymorphism)
UPI, క్రెడిట్ కార్డ్ మరియు క్రిప్టో పేమెంట్లను ఏకరీతిగా ప్రాసెస్ చేసే అబ్స్ట్రాక్ట్ పేమెంట్ సిస్టమ్ను నిర్మిద్దాం:
from abc import ABC, abstractmethod
# అబ్స్ట్రాక్ట్ ఇంటర్ఫేస్ కాంట్రాక్ట్
class PaymentGateway(ABC):
def __init__(self, merchant_name: str):
self.merchant_name = merchant_name
@abstractmethod
def authorize(self, amount: float) -> bool:
"""చెల్లింపును ఆథరైజ్ చేసే విధానం."""
pass
@abstractmethod
def execute_payment(self, amount: float) -> bool:
"""నగదు బదిలీ జరిపే విధానం."""
pass
# 1. UPI గేట్వే
class UPIPayment(PaymentGateway):
def __init__(self, merchant_name: str, upi_vpa: str):
super().__init__(merchant_name)
self.upi_vpa = upi_vpa
def authorize(self, amount: float) -> bool:
print(f"📱 UPI VPA [{self.upi_vpa}] కి ₹{amount} పిన్ రిక్వెస్ట్ పంపబడింది.")
return True
def execute_payment(self, amount: float) -> bool:
print(f"✅ UPI ద్వారా ₹{amount:,.2f} చెల్లింపు విజయవంతమైంది! మర్చంట్: {self.merchant_name}")
return True
# 2. Credit Card గేట్వే
class CreditCardPayment(PaymentGateway):
def __init__(self, merchant_name: str, card_last4: str):
super().__init__(merchant_name)
self.card_last4 = card_last4
def authorize(self, amount: float) -> bool:
print(f"💳 కార్డ్ *{self.card_last4} కి 3D-Secure OTP ధృవీకరణ పూర్తయింది.")
return True
def execute_payment(self, amount: float) -> bool:
print(f"✅ క్రెడిట్ కార్డుతో ₹{amount:,.2f} వసూలు చేయబడింది! మర్చంట్: {self.merchant_name}")
return True
# పాలిమార్ఫిక్ క్లయింట్ ఫంక్షన్
def process_order_checkout(gateway: PaymentGateway, total_amount: float):
print("
--- ఆర్డర్ చెక్అవుట్ ప్రాసెస్ మొదలైంది ---")
if gateway.authorize(total_amount):
gateway.execute_payment(total_amount)
# పరీక్షించడం
upi = UPIPayment("భారత్ మార్ట్", "balaji@okaxis")
card = CreditCardPayment("భారత్ మార్ట్", "8821")
process_order_checkout(upi, 1499.0)
process_order_checkout(card, 8950.0)
11 కోడ్ డెమో 2: కార్పొరేట్ ఎంప్లాయ్ హైరార్కీ with @property Validation
ఇన్హెరిటెన్స్, super(), మరియు @property వాలిడేషన్ కలగలసిన కార్పొరేట్ ఉద్యోగుల ఆర్కిటెక్చర్ను చూద్దాం:
# బేస్ క్లాస్
class BaseEmployee:
def __init__(self, emp_id: str, name: str, base_salary: float):
self.emp_id = emp_id
self.name = name
self._salary = base_salary
@property
def salary(self):
return self._salary
@salary.setter
def salary(self, value):
if value < 20000.0:
raise ValueError("కనీస వేతనం ₹20,000 కన్నా తక్కువ ఉండకూడదు!")
self._salary = value
def calculate_annual_ctc(self) -> float:
return self._salary * 12
# సాఫ్ట్వేర్ ఇంజనీర్ సబ్క్లాస్
class SoftwareEngineer(BaseEmployee):
def __init__(self, emp_id: str, name: str, base_salary: float, tech_stack: list):
super().__init__(emp_id, name, base_salary)
self.tech_stack = tech_stack
def calculate_annual_ctc(self) -> float:
base_annual = super().calculate_annual_ctc()
tech_allowance = 50000.0 # టెక్నాలజీ అలవెన్స్
return base_annual + tech_allowance
# మేనేజర్ సబ్క్లాస్
class EngineeringManager(BaseEmployee):
def __init__(self, emp_id: str, name: str, base_salary: float, team_size: int):
super().__init__(emp_id, name, base_salary)
self.team_size = team_size
def calculate_annual_ctc(self) -> float:
base_annual = super().calculate_annual_ctc()
mgmt_bonus = self.team_size * 25000.0 # ప్రతి టీమ్ మెంబర్కు బోనస్
return base_annual + mgmt_bonus
# టెస్టింగ్
dev = SoftwareEngineer("DEV101", "రాహుల్ వర్మ", 75000.0, ["Python", "Docker", "AWS"])
mgr = EngineeringManager("MGR001", "సుస్మిత", 120000.0, team_size=8)
print(f"👨💻 {dev.name} వార్షిక CTC: ₹{dev.calculate_annual_ctc():,.2f}")
print(f"👩💼 {mgr.name} వార్షిక CTC: ₹{mgr.calculate_annual_ctc():,.2f}")
12 కామన్ బిగినర్స్ మిస్టేక్స్ & ప్రొడక్షన్ బెస్ట్ ప్రాక్టీసెస్
- Composition Over Inheritance: బిగినర్స్ ప్రతి చిన్న లాజిక్ కోసం క్లాసులను ఇన్హెరిట్ చేస్తుంటారు. కానీ ప్రముఖ డిజైన్ ప్రిన్సిపల్: "Favor object composition over class inheritance". సంబంధం "is-a" (కారు అనేది ఒక వాహనం) అయినప్పుడు మాత్రమే ఇన్హెరిటెన్స్ వాడండి; సంబంధం "has-a" (కారుకు ఒక ఇంజిన్ ఉంది) అయినప్పుడు ఆబ్జెక్ట్ను క్లాస్ లోపల ఒక వేరియబుల్గా ఉంచండి (Composition).
- Fragile Base Class Problem: లోతైన ఇన్హెరిటెన్స్ చెట్లలో (Deep Inheritance Trees - 4-5 స్థాయిలు), పేరెంట్ క్లాస్లో చేసిన ఒక చిన్న మార్పు దూరంగా ఉన్న చైల్డ్ క్లాసులను బ్రేక్ చేస్తుంది. ఎల్లప్పుడూ హైరార్కీని గరిష్టంగా 2-3 స్థాయిలకే పరిమితం చేయండి.
- Name Mangling ను సెక్యూరిటీ అనుకోవడం:
__privateవేరియబుల్స్ పూర్తిగా సురక్షితమైనవి కావు; ఎవరైనాobj._ClassName__variableద్వారా వాటిని మార్చవచ్చు. ఇది కేవలం వేరియబుల్ కొల్లిజన్ నివారణకే.
13 రియల్-వరల్డ్ ప్రాజెక్ట్: "Multi-Tier Enterprise Logistics & Shipping Pipeline"
ఈ అధ్యాయంలో నేర్చుకున్న అన్ని కాన్సెప్టులను (ABC ఇంటర్ఫేస్, సింగిల్ & మల్టిపుల్ ఇన్హెరిటెన్స్, super(), @property వాలిడేషన్, డక్ టైపింగ్ పాలిమార్ఫిజమ్) సమగ్రంగా ఏకీకృతం చేస్తూ — వివిధ రకాల కార్గో రవాణాలను (Road, Air, Maritime Express) సురక్షితంగా లెక్కించే పూర్తి స్థాయి Enterprise Multi-Tier Logistics Shipping Pipeline ను నిర్మిద్దాం!
# =====================================================================
# చాప్టర్ 23 ప్రాజెక్ట్: Enterprise Multi-Tier Logistics Shipping Pipeline
# కాన్సెప్ట్స్: ABC Contracts, super(), Property Validation, Polymorphism
# =====================================================================
from abc import ABC, abstractmethod
import datetime
# 1. అబ్స్ట్రాక్ట్ కార్గో షిప్పింగ్ బేస్ క్లాస్
class BaseShipment(ABC):
def __init__(self, tracking_id: str, origin: str, dest: str, weight_kg: float):
self.tracking_id = tracking_id
self.origin = origin
self.dest = dest
self._weight_kg = weight_kg
self.created_at = datetime.datetime.now()
@property
def weight_kg(self):
return self._weight_kg
@weight_kg.setter
def weight_kg(self, value):
if value <= 0:
raise ValueError("కార్గో బరువు సున్నా కన్నా ఎక్కువ ఉండాలి!")
self._weight_kg = value
@abstractmethod
def calculate_cost(self) -> float:
"""ప్రతి రవాణా విధానం స్వంత ధర లెక్కించే లాజిక్."""
pass
@abstractmethod
def estimated_delivery_days(self) -> int:
"""డెలివరీకి పట్టే రోజుల అంచనా."""
pass
# 2. రోడ్ లాజిస్టిక్స్ (సర్ఫేస్ డెలివరీ)
class RoadSurfaceShipment(BaseShipment):
def __init__(self, tracking_id: str, origin: str, dest: str, weight_kg: float, distance_km: float):
super().__init__(tracking_id, origin, dest, weight_kg)
self.distance_km = distance_km
def calculate_cost(self) -> float:
base_rate = 50.0 # ప్రారంభ ఛార్జ్
cost = base_rate + (self.weight_kg * 12.0) + (self.distance_km * 3.5)
return cost
def estimated_delivery_days(self) -> int:
return max(2, int(self.distance_km / 400) + 1)
# 3. ఎయిర్ కార్గో (ఎక్స్ప్రెస్ డెలివరీ)
class AirExpressShipment(BaseShipment):
def __init__(self, tracking_id: str, origin: str, dest: str, weight_kg: float, is_hazardous: bool = False):
super().__init__(tracking_id, origin, dest, weight_kg)
self.is_hazardous = is_hazardous
def calculate_cost(self) -> float:
flat_air_surcharge = 500.0
haz_fee = 1200.0 if self.is_hazardous else 0.0
return flat_air_surcharge + haz_fee + (self.weight_kg * 65.0)
def estimated_delivery_days(self) -> int:
return 1 # నెక్స్ట్ డే ఎక్స్ప్రెస్
# 4. సెంట్రల్ లాజిస్టిక్స్ డిస్పాచర్ ఇంజిన్ (పాలిమార్ఫిక్ ప్రాసెసర్)
class LogisticsDispatcher:
def __init__(self, hub_name: str):
self.hub_name = hub_name
self.manifest = []
def dispatch_cargo(self, shipment: BaseShipment):
# పాలిమార్ఫిజమ్: shipment రకం ఏదైనా సంబంధం లేకుండా calculate_cost() పనిచేస్తుంది
cost = shipment.calculate_cost()
days = shipment.estimated_delivery_days()
self.manifest.append(shipment)
print(f"📦 [ట్రాకింగ్: {shipment.tracking_id}] డిస్పాచ్ అయింది!")
print(f" • రకం: {shipment.__class__.__name__}")
print(f" • మార్గం: {shipment.origin} -> {shipment.dest} (బరువు: {shipment.weight_kg} KG)")
print(f" • షిప్పింగ్ ఛార్జ్: ₹{cost:,.2f} | అంచనా డెలివరీ: {days} రోజు(లు)")
print("-" * 65)
def print_manifest_summary(self):
print(f"
==================== {self.hub_name} మానిఫెస్ట్ సారాంశం ====================")
total_freight_cost = sum(s.calculate_cost() for s in self.manifest)
total_weight = sum(s.weight_kg for s in self.manifest)
print(f"మొత్తం పార్సిల్స్: {len(self.manifest)}")
print(f"మొత్తం కార్గో బరువు: {total_weight:,.2f} KG")
print(f"మొత్తం షిప్పింగ్ రాబడి (Revenue): ₹{total_freight_cost:,.2f}")
print("========================================================================
")
# =====================================================================
# పైప్లైన్ సిమ్యులేషన్
# =====================================================================
dispatcher = LogisticsDispatcher("హైదరాబాద్ సెంట్రల్ లాజిస్టిక్స్ హబ్")
# వివిధ రకాల రవాణా ఆర్డర్లు
shipment1 = RoadSurfaceShipment("TRK-HYD-001", "హైదరాబాద్", "విజయవాడ", weight_kg=25.0, distance_km=275.0)
shipment2 = AirExpressShipment("TRK-AIR-909", "హైదరాబాద్", "ముంబై", weight_kg=8.5, is_hazardous=False)
shipment3 = AirExpressShipment("TRK-AIR-910", "హైదరాబాద్", "న్యూఢిల్లీ", weight_kg=15.0, is_hazardous=True)
# డిస్పాచ్ ప్రాసెసింగ్
dispatcher.dispatch_cargo(shipment1)
dispatcher.dispatch_cargo(shipment2)
dispatcher.dispatch_cargo(shipment3)
# మొత్తం హబ్ సారాంశం
dispatcher.print_manifest_summary()
? మీ అవగాహనను పరీక్షించుకోండి (5 Interactive Quizzes)
1. super() ఫంక్షన్ యొక్క ప్రధాన ప్రయోజనం ఏమిటి?
super() చైల్డ్ క్లాస్ నుండి పేరెంట్ క్లాస్ యొక్క మెథడ్స్ మరియు కన్స్ట్రక్టర్ను నేరుగా హార్డ్కోడ్ చేయకుండా, పైథాన్ యొక్క Method Resolution Order (MRO) ప్రకారం సురక్షితంగా మరియు డైనమిక్గా పిలవడానికి అనుమతిస్తుంది.
2. డైమండ్ ప్రాబ్లమ్ను పైథాన్ ఏ అల్గారిథమ్ ద్వారా పరిష్కరిస్తుంది?
3. Name Mangling అంటే ఏమిటి? ఇది ఎప్పుడు సంభవిస్తుంది?
__salary) పేరును పైథాన్ అంతర్గతంగా _ClassName__salary గా మారుస్తుంది. దీనివల్ల చైల్డ్ క్లాసుల్లో పొరపాటున ఆ వేరియబుల్ ఓవర్రైట్ కాకుండా నిరోధించబడుతుంది.
4. పైథాన్లో డక్ టైపింగ్ (Duck Typing) అంటే ఏమిటి?
5. @abstractmethod ఉన్న క్లాస్ను నేరుగా ఆబ్జెక్ట్గా సృష్టించవచ్చా?
TypeError ను రైజ్ చేస్తుంది. చైల్డ్ క్లాస్ ఆ మెథడ్స్ను పూర్తిగా ఇంప్లిమెంట్ చేసిన తర్వాతే ఆబ్జెక్ట్ సృష్టించబడుతుంది.
ఈ Enterprise Logistics Shipping Engine ని లైవ్గా మన కంపైలర్లో రన్ చేయండి!
ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్లోనే Modern Python 3 కంపైలర్లో ఈ OOP ఇన్హెరిటెన్స్ మరియు పాలిమార్ఫిజమ్ కోడ్ను ఎగ్జిక్యూట్ చేసి అవుట్పుట్ తనిఖీ చేయండి.