Download presentation
Presentation is loading. Please wait.
1
ارث بری 2 استفاده ی مجدد از کلاس توسط وراثت
مظفر بگ محمدی دانشگاه ایلام
2
آیا اجزاء سازنده به ارث برده می شوند؟
نمی توان از سازنده ی Employee برای ایجاد اشیاء HourlyEmployee استفاده کرد. ما باید برای HourlyEmployees یک سازنده ی مناسب ایجاد کنیم. اما سازنده ی HourlyEmployee چگونه می تواند متغییرهای خصوصی کلاس Employee را مقداردهی اولیه نماید در حالی که دسترسی مستقیم به آنها ندارد؟
3
سازنده ی super کلاس مشتق شده می تواند به شکل زیر از سازنده ی کلاس پایه برای مقداردهی متغییرهای خصوصی به ارث برده شده از کلاس پایه استفاده کند. public DerivedClass(int p1, int p2, double p3) { super(p1, p2); derivedClassInstanceVariable = p3; } در مثال فوق، دستور super(p1, p2); سازنده ی کلاس پایه را فراخوانی می کند. 3
4
سازنده ی super برای فراخوانی سازنده ی کلاس پایه نمی توانید از اسم کلاس پایه استفاده کنید و باید از کلمه ی کلیدی super استفاده کنید. فراخوانی super باید اولین کاری باشد که در سازنده انجام می شود. نمی توان متغییرهای کلاس را به عنوان پارامتر به super ارسال کرد. 4
5
سازنده ی super اگر یک کلاس مشتق شده متد super را فراخوانی نکند، سازنده ی بدون آرگومان کلاس پایه بصورت خودکار فراخوانی می گردد. اگر کلاس پایه سازنده ی بدون آرگومان نداشته باشد، منجر به تولید خطا می شود. چون متغییرهای به ارث برده شده باید مقداردهی اولیه شوند، و سازنده ی کلاس پایه برای این کار طراحی شده است، لذا باید همیشه super را صریحاً فراخوانی کرد. 5
6
سازنده ی HourlyEmployee
public class HourlyEmployee extends Employee { private double wageRate; private double hours; // for the month // the no-argument constructor invokes // the Employee (super) no-argument constructor // to initialize the Employee instance variables // then initializes the HourlyEmployee instance variables public HourlyEmployee( ) super( ); wageRate = 0; hours = 0; }
7
سازنده ی HourlyEmployee
// the alternative HourlyEmployee constructor invokes an // appropriate Employee (super) constructor to initialize // the Employee instance variables (name and date), and then // initializes the HourlyEmployee rate and hours public HourlyEmployee(String theName, Date theDate, double theWageRate, double theHours) { super(theName, theDate); if ((theWageRate >= 0) && (theHours >= 0)) wageRate = theWageRate; hours = theHours; } else System.exit(0);
8
دسترسی به متد کلاس پایه که بازنویسی شده است.
می توان با استفاده از super در هنگام تعریف متدها در کلاس مشتق شده، متدهای بازنویسی شده ی کلاس پایه را نیز فراخوانی کرد. // HourlyEmployee’s toString( ) might be public String toString( ) { return (super.toString() + "$" + getRate( )); } به هر حال، بجز در داخل تعریف کلاس، در جای دیگری نمی توان نسخه ی کلاس پایه ی یک متد بازنویسی شده را فراخوانی کرد. 8
9
نمی توان از super به صورت تودرتو استفاده کرد
به عنوان مثال، کد زیر غلط است. super.super.toString() // ILLEGAL! 9
10
هر شی از کلاس مشتق شده بیش از یک نوع دارد
هر شی که از نوع کلاس مشتق شده باشد، از نوع کلاس پایه ی مربوطه هم هست. بطور کلی، هر شی کلاس مشتق شده از نوع تمام اجداد خود نیز هست. بنابراین، این شی را می توان به هر متغییری از نوع اجداد نیز منتسب کرد. 10
11
هر شی از کلاس مشتق شده بیش از یک نوع دارد
یعنی می توان شی کلاس مشتق شده را بعنوان پارامتر به جای کلاسهای اجدادش به متدها ارسال کرد. در حقیقت، شی کلاس مشتق شده را می توان در هر جایی که یک شی از نوع اجدادش استفاده شده است، استفاده نمود. دقت کنید در این رابطه حالت برعکس صحیح نیست. یعنی نمی توان یک شی از نوع اجداد را به جای یک شی کلاس مشتق شده استفاده کرد. 11
12
خلاصه ی کلاس پایه/مشتق شده
فرض کنید که کلاس D از کلاس B مشتق شده است. هر شی از نوع D از نوع B نیز هست ولی عکس آن صحیح نیست. D نسخه ی خصوصی تر B است. هر جایی که از B استفاده شده است، از D نیز می توان استفاده کرد.
13
دسترسی Protected می توان هنگام تعریف یک متد یا متغییر از protected به جای public یا private استفاده کرد. در این صورت، می توان در جاهای زیر آنرا با اسم فراخوانی کرد: داخل تعریف کلاس خودش داخل هر کلاسی که از آن مشتق می شود. داخل هر کلاسی که بسته ی آن با کلاس ما یکسان است. حفاظت protected نسبت به private ضعیف است. می توان با تعریف کلاسهای مشتق شده متغییرهای protected را فراخوانی کرد. بنابراین، متغییرهای خصوصی را معمولاً با protected علامت نمی زنند. 13
14
راهنمایی: متغییرهای استاتیک به ارث برده می شوند.
متغییرهای استاتیک کلاس پایه توسط همه ی کلاسهای مشتق شده به ارث برده می شوند. معنای public, private و protected برای متغییرهای استاتیک شبیه متغییرهای معمولی است. 14
15
کلاس Object در جاوا کلاس Object جد تمام کلاسها است.
کلاس Object در بسته ی java.lang قرار دارد که همیشه بصورت اتوماتیک فراخوانی می شود. لذا می توان متدهای نوشت که آرگومان آنها از نوع Object باشد. این پارامتر را بعداً می توان با هر شی از هر کلاسی جایگزین کرد. 15
16
کلاس Object کلاس Object متدهایی دارد که توسط تمام کلاسهای دیگر به ارث برده می شود. مثل متدهای equals و toString هر شی این متدها را از اجداد خود به ارث می برد. می توان این متدها را در کلاسهای مشتق شده بازنویسی کرد. بعضی کتابخانه های جاوا فرض می کنند که این متدها حتماً بازنویسی می گردند. 16
17
روش درست تعریف متد equals
چون متد equals همیشه از Object به ارث برده می شود، متدهایی شبیه این متد آنرا بارگذاری می کنند. public boolean equals(Employee otherEmployee) { } اما این متد به جای بارگذاری، باید بازنویسی شود public boolean equals(Object otherObject) 17
18
روش درست تعریف کلاس equals
پارامتر otherObject از نوع Objectرا باید با تبدیل نوع تغییر دهد. به هر حال، متد جدید این کار را فقط در صورتی باید انجام دهد که otherObject یک شی از همین کلاس باشد و مقدار آن null نباشد. باید تمام متغییرهای هر دو شی را با هم مقایسه نماید. 18
19
یک متد equals بهتر برای کلاس Employee
public boolean equals(Object otherObject) { if(otherObject == null) return false; else if(getClass( ) != otherObject.getClass( )) else Employee otherEmployee = (Employee)otherObject; return (name.equals(otherEmployee.name) && hireDate.equals(otherEmployee.hireDate)); } 19
20
متد getClass() هر شی متد getClass()را از کلاس Object به ارث می برد.
این متد بصورت finalتعریف شده است، یعنی قابل بازنویسی نیست. فراخوانی getClass() باعث می شود که کلاس مورد استفاده در هنگام ایجاد شی (توسط دستور new) برگردد. خروجی این متد را می توان با عملگرهای == و != مقایسه نمود تا ببینیم که کلاس دو شی برابر هستند یا نه؟ (Object1.getClass() == Object2.getClass()) 20
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.