آموزش جاوا- قسمت 8 (ارث‌بری)

آموزش جاوا- قسمت 8 (ارث‌بری)

قطعا تا به حال اصطلاح ارث‌بری در جاوا را به کرات شنیده‌اید. در این قسمت از آموزش جاوا قصد داریم تا شما را با مفهوم  و نحوه استفاده از آن آشنا کنیم.
در جاوا اصطلاح ارث‌بری یا inheritance به برگرفتن تمام توابع و ویژگی‌های غیرخصوصی (non-private) یک کلاس (سوپر کلاس) توسط کلاسی دیگر (کلاس زیرشاخه) گفته می‌شود. در اصطلاح تخصصی به کلاس زیرشاخه، subclass یا derived class نیز گفته می‌شود. ارث‌بری روشی برای ایجاد یک نسخه کپی از یک کلاس موجود به عنوان نقطه شروع برای کلاسی دیگر است.
حال که با اصطلاح inheritance آشنا شدید، بهتر است تا در همان ابتدا شما را اندکی با اصطلاح interface در جاوا آشنا کنیم، چرا که گاهی به اشتباه، به جای یکدیگر به کار برده می‌شوند. interface تنها ساختار اعضای کلاس را تعریف می‌کند، درحالی که کلاس‌های ارث‌برده شده (inherited) شامل کد واقعی سوپرکلاس هستند. همچنین در inheritance برای تعریف کلاس زیرشاخه از کلمه کلیدی extends استفاده می‌شود. در قسمت‌های بعدی آموزش جاوا به تفصیل درمورد interfaceها صحبت خواهد شد.
برای درک بهتر مفهوم ارث‌بری، اگر یک کلاس زیرشاخه از  یک سوپرکلاس ساخته شود و کلاس زیرمجموعه بدون تغییر باقی بماند، در اینصورت دو کلاس باهم برابر خواهند بود. اما معمولا کلاس‌های زیرمجموعه بدون تغییر باقی نمی‌مانند. چون کلاس زیرمجموعه خود یک کلاس محسوب می‌شود، می‌تواند تغییر کرده و توابع و ویژگی‌های جدیدی داشته باشد. همچنین کلاس زیرمجموعه نهایی، می‌تواند خود یک سوپرکلاس برای کلاس‌های زیرمجموعه دیگری شود. و این یعنی هیچ محدودیتی برای تعداد سطوح ارث بری وجود ندارد.
توابع و ویژگی‌های یک کلاس زیرشاخه، می‌تواند همانند همان توابع و ویژگی‌های سوپرکلاس متناظرش استفاده شود یا اینکه override شود. در حالت دوم، کد جدید برای هدفی دیگر جایگزین کد اصلی می‌شود. برای اجرای کد ارث‌بری شده از داخل کلاس زیرشاخه، قبل از نام تابع باید از .super استفاده شود. همچنین می‌توان یک constructor داخل کلاس زیرشاخه نوشت که constructor سوپرکلاس را فراخوانی کند (چه به طور مستقیم، چه با کلمه کلیدی super).
تا اینجا سعی کردیم تا به طور کامل شما را با مفهوم ارث‌بری آشنا کنیم. اما سوالی که ممکن است برای شما پیش آید این است که چرا باید از ارث‌بری استفاده کرد؟ همانطور که احتمالا خودتان نیز حدس زده‌اید، ارث‌بری کمک بسیاری به استفاده مجدد از کد‌های از پیش نوشته شده و مفهوم generic-to-specific می‌کند. در حالت ایده‌ال یک سوپرکلاس در عمومی‌ترین سطح ممکن نوشته می‌شود. اما کلاس‌های زیرشاخه با هدفی خاص‌تر و به صورت جزئی‌تر، از سوپرکلاس ساخته می‌شوند.

 

مثال برای مفهوم ارث‌بری

برای درک بهتر این مفهوم یک “در” را تصور کنید. هیچ اهمیتی ندارد که چه نوع دری باشد. تمام درها ویژگی باز و بسته شدن را دارند. اما در نحوه باز و بسته شدن “در”ها تفاوت‌هایی وجود دارد. به عنوان مثال برخی به صورت کشویی باز می‌شوند برخی رو به بالا می‌شوند و غیره. بنابراین اگر بخواهیم مفهوم ارث بری را روی “در” توضیح دهیم میتوانیم بگوییم “در” یک سوپر کلاس است که شامل یک تابع ساده به نام open است که از یک دستورالعمل push ساخته شده است:

public class Door {
    public void open ()
    {
        push();     // Since this is just a generic "Door" we will assume the simplest opening method.
                    // The actual open method must be overridden by a subclass, as we see below.
                    // Later, a way to force a subclass to override a method will be demonstrated -- 
                    // but for this simple example will do for now.
    }
}

استفاده از این کلاس در درب غرفه بانکی احتمالا ایده خوبی نباشد. استراتژی بهتر این است که با استفاده از مفهوم ارث‌بری، یک کلاس زیرشاخه از کلاس Door  ساخته شود و تابع open با هدفی خاص‌تر و جایگزینی pull به جای push دوباره نویسی شود:

class BankVaultDoor extends Door {    // The "extends" keyword used to tell java that BankVaultDoor inherits the functionality of Door.

    public void open () {
        enterCombination();
        pull;
    }

}

مزیت استفاده از ارث‌بری، نوشتن یک کد و اعمال آن به تعداد زیادی کلاس است که از آن کلاس ارث‌ می‌برند. در مثال زیر تابعی را مشاهده می‌کنید که انواع مختلفی از درها را باز می‌کند:

public class Main {

    public static void main(String[] args) {
        Door d1 = new BankVaultDoor();
        Door d2 = new HouseFrontDoor();
        Door d3 = new CarDoor();
    }

    if (arg[0] == "car") {
        d3.open();
    } else if (arg[0] == "bank") {
        d1.open();
    } else {
        d2.open();
    }
}

توجه کنید که تابع ()open هیچ اطلاعی از انواع درها ندارد. هر کلاسی که یک کلاس زیرشاخه از Door باشد، از تابع ()open برای باز کردن آن استفاده خواهد کرد.

 

 

اولین قسمت از مباحث پیشرفته آموزش جاوا به پایان رسید. مبحث ارث‌بری یکی از کاربردی ترین مباحث جاوا است. و قطعا در پروژه‌های خود به کدهایی برخواهید خورد که از این مفهوم در آن‌ها استفاده شده است. امیدواریم  پس از این قسمت از آموزش جاوا به اندازه یک قدم بلند به توسعه کنترل‌‌‌کننده‌های مبتنی بر زبان جاوا نزدیک‌تر شده باشید. در قسمت بعدی آموزش پیشرفته تر جاوا، درمورد مفهوم بسیار کاربردی  try and catch توضیح خواهیم داد.

 

تاریخچه آموزش جاوا به ترتیب:

قسمت اول آموزش جاوا (مقدمه)

قسمت دوم آموزش جاوا (Types and Variables)

قسمت سوم آموزش جاوا (دستورات شرطی)

قسمت چهارم آموزش جاوا (آرایه‌ها)

قسمت پنجم آموزش جاوا (حلقه‌ها)

قسمت ششم آموزش جاوا (توابع)

قسمت هفتم آموزش جاوا (اشیا)

قسمت هشتم آموزش جاوا (ارث‌بری)

قسمت نهم آموزش جاوا (try and catch)

قسمت دهم آموزش جاوا (کلاس‌های abstract)

ادامه دارد…

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *