سلام! در درس های قبل به طور خلاصه با مفهوم وراثت آشنا شدیم. امروز، دوباره به این موضوع خواهیم پرداخت، اما باز هم نه خیلی عمیق. ما هنوز در آینده درس مفصل تری در این مورد خواهیم داشت. امروز فقط نگاهی گذرا به چند مثال کاربردی می اندازیم و با یک اپراتور جالب در جاوا آشنا می شویم.
وراثت یک مکانیسم برنامه نویسی است (از جمله در جاوا) که به شما امکان می دهد یک کلاس جدید را بر اساس کلاس موجود اعلام کنید. سپس کلاس مشتق شده به فیلدها و متدهای کلاس والد دسترسی پیدا می کند. چرا ما به این نیاز داریم؟ خوب، تصور کنید که باید چندین کلاس خودرو را در یک برنامه ایجاد کنید: کامیون، ریس کار، سدان، پیکاپ و غیره. حتی قبل از نوشتن هر کدی، مطمئناً می دانید که همه این کلاس ها اشتراکات زیادی دارند: همه ماشین ها یک مدل دارند. نام، سال ساخت، حجم موتور، حداکثر سرعت و غیره (غیر از این که همه آنها دارای چرخ و سایر قطعات مشترک هستند). در این شرایط می توانید:
وراثت
بنابراین، ارث چیست؟
- این فیلدها را در هر کلاس ایجاد کنید (همزمان با ایجاد هر کلاس خودروی جدید آنها را اضافه کنید)
- فیلدهای مشترک برای همه خودروها را در یک
Car
کلاس والد بیاورید و سپس از کلمه کلیدی extensions برای استخراج همه کلاسها برای انواع خاصی از خودروها ازCar
کلاس استفاده کنید.
public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
حداقل، از تکرار غیرضروری کد جلوگیری می کنیم (و همیشه باید در هنگام نوشتن برنامه برای آن تلاش کنیم). بعلاوه، ما یک ساختار کلاسی ساده و قابل فهم داریم که تمام زمینه های مشترک برای همه خودروها در یک کلاس ادغام شده است. اگر کامیون ها دارای فیلدهای خاصی باشند که سایر خودروها ندارند، می توان آنها را در Truck
کلاس اعلام کرد. در مورد روش ها هم همینطور. Car
همه ماشینها رفتار مشترک خاصی دارند که میتوان آن را با روشهایی توصیف کرد، به عنوان مثال، ماشین را استارت، شتاب/ترمز کردن، و غیره. .
public class Car {
public void gas() {
// Accelerate
}
public void brake() {
// Brake
}
}
public class F1Car extends Car {
public void pitStop() {
// Only race cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
ما متدهای رایج برای همه خودروها را به Car
کلاس اضافه کردیم. اما، به F1Car
کلاسی که نمایانگر خودروهای مسابقه ای "فرمول 1" است نگاه کنید. پیت استاپ (توقف برای تعمیر و نگهداری فوری خودرو) فقط در مسابقات انجام می شود، بنابراین ما این قابلیت خاص را به کلاس مشتق شده مربوطه اضافه کردیم. 
نمونه اپراتور
در جاوا، یک عملگر ویژه به نام instanceof وجود دارد که بررسی می کند آیا یک شی بر اساس یک کلاس خاص ایجاد شده است یا خیر. بسته به نتیجه بررسی، true یا false را برمی گرداند . بیایید ببینیم با استفاده از کلاسهای مثال ماشین ما چگونه کار میکند:public class Truck extends Car {
public static void main(String[] args) {
Truck truck = new Truck();
System.out.println(truck instanceof Car);
}
}
خروجی: true اپراتور trueinstanceof
را برمی گرداند ، زیرا ما یک شی داریم و همه کامیون ها اتومبیل هستند. کلاس از کلاس گرفته شده است . همه کامیون ها بر اساس والد مشترک، کلاس ایجاد می شوند. به نحوه استفاده از اپراتور دقت کنید . شما آن را بدون نقطه می نویسید، زیرا یک عملگر است، نه یک متد ("نمونه شیء کلاس"). بیایید راه دیگری را امتحان کنیم: Truck
Truck
Car
Car
instanceof
public static void main(String[] args) {
Car car = new Car();
System.out.println(car instanceof Truck);
}
خروجی: false کلاس Car
(و اشیاء ماشین) از کلاس مشتق نمی شود Truck
. همه کامیون ها ماشین هستند، اما همه ماشین ها کامیون نیستند. Car
اشیاء بر اساس کلاس نیستند Truck
. یک مثال دیگر:
public static void main(String[] args) {
Car car = new Car();
Truck truck = new Truck();
System.out.println(car instanceof Object && truck instanceof Object);
}
خروجی: True در اینجا منطق نیز ساده است: همه کلاسهای جاوا، از جمله کلاسهایی که ایجاد میکنید، از کلاس فرود میآیند Object
(حتی اگر شما «extends Object» را نمینویسید - قبلاً به طور ضمنی گفته شده است). این چگونه و چه زمانی مفید خواهد بود؟ اپراتور instanceof
معمولاً هنگام نادیده گرفتن equals()
روش استفاده می شود. به عنوان مثال، در اینجا نحوه equals
پیاده سازی متد در String
کلاس آمده است:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
قبل از مقایسه a String
با شیء ارسال شده، روش آزمایش می کند که آیا شیء زوج یک رشته است یا خیر؟ تنها پس از آن شروع به مقایسه خصوصیات دو شیء می کند. اگر این تست وجود نداشت، هر شی با فیلدهای مقدار و طول میتوانست به متد ارسال شود و با یک رشته مقایسه شود، که البته اشتباه است.
GO TO FULL VERSION