سلام :)
کلمه پلی مورفیسم(Polymorphism) به معنای داشتن اشکال متعدد است. چندریختی(Polymorphism) در جاوا مفهومی است که به وسیله آن می توانیم یک عمل واحد را به روش های مختلف انجام دهیم.
دو نوع چندریختی در جاوا وجود دارد: چندریختی زمان کامپایل یا استاتیک و چندریختی زمان اجرا یا داینامیک. ما می توانیم پلی مورفیسم را در جاوا با روش overloading و روش overriding انجام دهیم.
خب Runtime polymorphism یا Dynamic Method Dispatch فرآیندی است که در آن فراخوانی یک متد override شده در زمان اجرا به جای زمان کامپایل مشخص می شود.
این نوع پلی مورفیسم با روش Overriding به دست می آید. از طرف دیگر، overriding زمانی اتفاق می افتد که یک کلاس مشتق شده(کلاس فرزند) برای یکی از توابع عضو، کلاس پایه(کلاس پدر) تعریف داشته باشد. گفته می شود که تابع پایه نادیده گرفته شده است.
اگر بخواهیم به زبا ساده تر بگوییم دو تابع با امضا یکسان در دو کلاس متفاوت که بین آن ها یک رابطه ارث بری وجود دارد یعنی اگر کلاس فرزند متدی را پیاده سازی کند که در کلاس پدر وجود داشته است، overriding در جاوا انجام داده ایم و در زمان فراخوانی تابع بجای تابع موجود در کلاس پدر، تابع override شده در کلاس فرزند صدا زده می شود و این عمل تا زمان اجرا قابل تشخیص نمی باشد. شروط overriding به ترتیب زیر است:
دو کلاس به نام Human و Boy داریم. کلاس Boy از کلاس Human ارث بری میکند. حال برای اینکه overriding را در جاوا انجام دهیم برای دو کلاس متدی به نام eat مینویسیم.کد آن به صورت زیر است:
public class Human { public void eat() { System.out.println("Human is Eating...."); } } public class Boy extends Human { @Override public void eat() { System.out.println("Boy is eating"); } } public class Girl extends Human { @Override public void eat() { System.out.println("Girl is eating"); } } public static void main(String[] args) { Human h; h = new Boy(); h.eat(); h = new Girl(); h.eat(); } output: Boy is eating Girl is eating
در مثال بالا کلاس boy و girl از کلاس human ارث بری می کند و تابع eat موجود در کلاس human را بازنویسی کرده است زمانی که در تابع main برای اولین بار متد eat را فراخوانی می کنیم بجای تابع eat موجود در کلاس boy اجرا می شود و برای بار دوم متد eat باز نویسی شده در کلاس girl اما اگر بازنویسی انجام نمی شد کلاس موجود در کلاس پدر فراخوانی می شد و برای اینکه مشخص شود کدام یک از توابع باید اجرا شود باید تا زمان اجرای پروژه صبر کرد.
این نوع پلی مورفیسم که Compile-Time Polymorphism یا Static Polymorphism گفته میشود با overloading تابع یا overloading عملگر به دست می آید، و در زمان کامپایل مشخص می شود.
* هرچند overloading عملگر درجاوا پشتیبانی نمی شود به جز عملگر "+" که میتوان برای جمع کردن دو عدد یا الحاق دو رشته به یکدیگر استفاده شود.
در توابع overloading به این معناست که توابع هم نام در یک کلاس اما با تعداد یا نوع پارامتر های ورودی متفاوت به عنوان مثال:
class Helper { // Method with 2 integer parameters static int Multiply(int a, int b) { // Returns product of integer numbers return a * b; } // Method 2 // With same name but with 2 double parameters static double Multiply(double a, double b) { // Returns product of double numbers return a * b; } }
همانطور که مشاهده میکنید در کلاس Helper ما دو تابع هم نام(Multiply) داریم که نوع پارامترهای ورودی آن ها متفاوت هستند در عمل ما تابع Multiply را overload کردیم، در زمان استفاده بر اساس نوع ورودی یکی از دو تابع فراخوانی می شود.
class Main{ public static void main(String[] args) { System.out.println(Helper.Multiply(2, 4)); //-- Output 8 System.out.println(Helper.Multiply(5.5, 6.3)); //-- Output 34.65 } }
یا در مثال دیگر:
class Helper { // Method 1 // Multiplication of 2 numbers static int Multiply(int a, int b) { // Return product return a * b; } // Method 2 // // Multiplication of 3 numbers static int Multiply(int a, int b, int c) { // Return product return a * b * c; } }
مانند مثال قبل در کلاس Helper ما دو تابع هم نام(Multiply) داریم با این تفاوت که تعداد پارامترهای ورودی آن ها متفاوت است یکی از توابع 2 ورودی و دیگری 3 ورودی دارد و در زمان فراخوانی براساس تعداد ورودی ها یکی از توابع فراخوانی می شود
* نوع خروجی در overloading موردنظر نیست و فقط نوع یا تعداد پارامترهای ورودی