Polymorphism
Overloading: same method नाम, अलग parameters — जैसे add(int,int) और add(double,double)। ये compile-time पर decide होता है।
Overriding: child class parent के method को अपने तरीक़े से दोबारा लिखती है — जैसे Dog अपना sound() ख़ुद define करता है। ये run-time पर decide होता है।
class Animal { void sound() { System.out.println("..."); } }
class Cat extends Animal { void sound() { System.out.println("Meow"); } }- एक नाम, कई रूप
- Overloading = same class, अलग parameters
- Overriding = child, parent का method redefine करता है
Overloading तब होती है जब same नाम के multiple methods हों, different parameters (number, type, या order) के साथ। Compiler compile-time पर ही decide कर लेता है कौनसा method call होगा, arguments का type देखकर — इसलिए "compile-time" (या "static") polymorphism कहते हैं।
Return type अकेला overloading का basis नहीं बन सकता — सिर्फ़ return type अलग होने से दो methods "same" माने जाते हैं (compile error)।
void print(int x) { System.out.println("int: " + x); }
void print(String x) { System.out.println("String: " + x); }
void print(int x, int y) { System.out.println("two ints"); }Overriding parent-child के बीच होती है — child parent के method को अपना version देता है (same signature के साथ)। कौनसा version चलेगा ये *runtime* पर decide होता है, actual object type देखकर (reference type से नहीं) — इसलिए "runtime" (या "dynamic") polymorphism।
सबसे powerful example: Parent type का reference, Child type के object को point कर सकता है (Animal a = new Dog();)। जब method call होती है, JVM देखता है *actual object* कौनसा है (Dog, reference type Animal नहीं), और उसका overridden version चलाता है।
इसी से polymorphic code लिखा जाता है — एक ही loop से सब Animal types handle करना, चाहे वो Dog हो या Cat हो या कोई भी Animal का future subclass — बिना loop का code change किए।
Animal a = new Dog(); // parent reference, child object
a.makeSound(); // Dog ka version chalega, Animal ka nahi!
for (Animal animal : zooList) { // List<Dog>, List<Cat> — sab Animal type
animal.makeSound(); // har ek ka apna sahi version chalega
}Polymorphism से तुम generic code लिख सकते हो जो future में नए types के साथ भी काम करेगा, बिना existing code change किए — इसे "Open/Closed Principle" कहते हैं (extension के लिए open, modification के लिए closed)।
जैसे List<Shape> में Circle, Square, Triangle सब रखकर सबकी area() call कर सकते हो — एक ही loop से, नया shape (Pentagon) add करने पर भी loop change नहीं करना पड़ेगा, बस Pentagon class बनाओ जो Shape extend करे।