مشخصات مقاله
-
0
-
0.0
-
6036
-
0
-
0
آموزش Java-آموزش چند ریختی در جاوا
Polymorphism توانایی یک آبجکت برای گرفتن فرم های مختلف می باشد. متداول ترین استفاده از Polymorphism در OOP اتفاق می افتد، وقتی که مرجع گروه اصلی برای اشاره به یک آبجکت زیرمجموعه استفاده می شود.
هر آبجکت جاوا که می تواند بیشتر از یک تست IS-A را انتقال دهد، یک Polymorphism در نظر گرفته می شود. در جاوا همه ی آبجکتها polymorphic هستند، زیرا هر آبجکت تست IS-A را برای نوع خود و برای آبجکت گروه انتقال خواهد داد.
این مسئله مهم است که تنها راه ممکن برای دسترسی به یک آبجکت از طریق متغیر مرجع می باشد. یک متغیر مرجع می تواند تنها یک نوع باشد. همانطور که اعلام شد، نوع یک متغیر مرجع نمی تواند تغییر کند.
متغیر مرجع می تواند مجددا به آبجکت های دیگری که نهایی اعلام نشده اند، اختصاص داده شود. نوع متغیر مرجع متودهایی که می تواند روی آبجکت فرا بخواند را تعیین می کند.
یک متغیر مرجع می تواند به هر آبجکت از نوع اعلام شده و یا هر زیرگروه از نوع اعلام شده، اشاره کند. یک متغیر مرجع می تواند به عنوان یک گروه یا یک اینترفیس اعلام شود.
مثال:
اجازه بدهید مثالی را بررسی کنیم:
public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}
اکنون گروه Deer به عنوان گروه polymorphic در نظر گرفته می شود، زیرا دارای چند inheritance میباشد. موارد زیر در مورد مثال بالا درست می باشند:
· A Deer IS-A Animal
· A Deer IS-A Vegetarian
· A Deer IS-A Deer
· A Deer IS-A Object
وقتی که واقعیت های متغیر مرجع را برای یک آبجکت Deer در نظر می گیریم، اعلامات زیر قانونی می باشند:
Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;
تمام متغیرهای مرجع d، a ، v، o به همان آبجکت Deer در دسته اشاره دارند.
متودهای مجازی (virtual methods):
در این بخشبه شما نشان خواهم داد که چگونه رفتار متودهای overridden در جاوا به شما اجازه می دهد تا در هنگام طراحی گروه های خود از مزایای polymorphism استفاده کنید.
ما تقریبا در مورد متود overriding صحبت کرده ایم، که یک گروه زیر مجموعه می تواند یک متود را در گروه اصلی خود override کند. یک متود overridden لزوما در گروه اصلی مخفی می شود و درخواست نمی شود، مگر اینکه گروه زیر مجموعه از لغت کلیدی super در داخل متود overriding استفاده کند.
/* File name : Employee.java */
public class Employee
{
private String name;
private String address;
private int number;
public Employee(String name, String address, int number)
{
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
this.number = number;
}
public void mailCheck()
{
System.out.println("Mailing a check to " + this.name
+ " " + this.address);
}
public String toString()
{
return name + " " + address + " " + number;
}
public String getName()
{
return name;
}
public String getAddress()
{
return address;
}
public void setAddress(String newAddress)
{
address = newAddress;
}
public int getNumber()
{
return number;
}
}
اکنون فرض کنید گروه Employee را مانند زیر باز کرده ایم:
/* File name : Salary.java */
public class Salary extends Employee
{
private double salary; //Annual salary
public Salary(String name, String address, int number, double
salary)
{
super(name, address, number);
setSalary(salary);
}
public void mailCheck()
{
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to " + getName()
+ " with salary " + salary);
}
public double getSalary()
{
return salary;
}
public void setSalary(double newSalary)
{
if(newSalary >= 0.0)
{
salary = newSalary;
}
}
public double computePay()
{
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
اکنون برنامه ی زیر را با دقت مطالعه کرده و سعی کنید خروجی آن را تعیین کنید:
/* File name : VirtualDemo.java */
public class VirtualDemo
{
public static void main(String [] args)
{
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("Call mailCheck using Salary reference --");
s.mailCheck();
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
این کد نتیجه ی زیر را به دنبال خواهد داشت:
Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0
Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0
در اینجا دو آبجکت Salary را نمونه گذاری کرده ایم. یکی در حال استفاده از مرجع Salary، s و دیگری در حال استفاده از مرجع Employee، e می باشد.
هنگام فراخوانی s.mailCheck() ، کامپایلر mailCheck() را در گروه Salary در زمان کامپایل می بیند و JVM در زمان اجرا mailCheck() را در گروه Salary فرا می خواند.
فراخواندن mailCheck() در e کاملا متفاوت است، زیرا e یک مرجع Employee می باشد. وقتی کامپایلر یک e.mailCheck() مشاهده می کند، درواقع کامپایلر یک متود mailCheck() در گروه Employee می بیند.
در اینجا در زمان کامپایل، کامپایلر در Employee از mailCheck() برای ارزیابی این وضعیت استفاده می کند. به هرحال در زمان اجرا JVM در گروه Salary مورد mailCheck() را فرامی خواند.
این رفتار با عنوان درخواست متود مجازی (virtual) مورد اشاره قرار می گیرد. همه ی متودها در جاوا به این روش رفتار می کنند، در حالیکه یک متود overridden در زمان اجرا فراخوانده می شود و اصلا مهم نیست مرجع چه نوع داده ای می باشد و یا در هنگام کامپایل در source code چه نوع داده ای استفاده شد.