+4 امتیاز
قبل در برنامه نویسی توسط (29 امتیاز)
ویرایش شده قبل توسط

دایتل در آخرین کتاب خود بر خلاف قبل صحت پارامترهای سازنده را توسط فراخوانی متدهای setter در سازنده انجام نمی دهد بلکه شروط متد setter را مجددا در سازنده بازنویسی کرده آیا این کار تاثیری در performance دارد؟

مثال کتاب نسخه 9:

public HourlyEmployee( String first, String last, String ssn, double hourlyWage,
 double hoursWorked ) {
  super( first, last, ssn );
  setWage( hourlyWage );
  setHours( hoursWorked );

 public void setWage( double hourlyWage ) {
   if ( hourlyWage >= 0.0 )
     wage = hourlyWage;
   else
     throw new IllegalArgumentException("Hourly wage must be >= 0.0" );
 }

}

مثال بالا در نسخه 10 کتاب:

public HourlyEmployee(String firstName, String lastName,
  String socialSecurityNumber, double wage, double hours) {
    super(firstName, lastName, socialSecurityNumber);
    if (wage < 0.0)
       throw new IllegalArgumentException("Hourly wage must be >= 0.0");
    if ((hours < 0.0) || (hours > 168.0))
       throw new IllegalArgumentException("Hours worked must be >= 0.0 and <= 168.0");
    this.wage = wage;
    this.hours = hours;
  }

  public void setWage(double wage) {
    if (wage < 0.0)
      throw new IllegalArgumentException("Hourly wage must be >= 0.0");
    this.wage = wage;
  }

1 پاسخ

+4 امتیاز
قبل توسط (1.1هزار امتیاز)
انتخاب شده قبل توسط
 
بهترین پاسخ

دلیل این کار وجود یک violation در مباحث کنترل کیفیت کد است که باعث می شود نتایجی برخلاف آن چیزی که ما توقع داریم اتفاق بیوفتد. در زبان برنامه نویسی جاوا نباید درون Constructor متد هایی که قابل override شدن هستند را فراخوانی کرد (متد های private, static, یا final قابل override شدن نیستند). به این قانون به زبان انگلیسی Ensure that constructors do not call overridable methods می گویند.

در زبان برنامه نویسی جاوا اگر متد یک کلاس در کلاس فرزندش override شده باشد و در Constructor کلاس پدر متد override شده فراخوانی شود، متد override شده در کلاس فرزند استفاده خواهد شد. به کد زیر توجه کنید:

class SuperClass {
  public SuperClass () {
    doLogic();
  }
 
  public void doLogic() {
    System.out.println("This is superclass!");
  }
}
 
class SubClass extends SuperClass {
  private String color = null;
  public SubClass() {
    super();
    color = "Red";
  }
 
  public void doLogic() {
    System.out.println("This is subclass! The color is :" + color);
    // ...
  }
}
 
public class Overridable {
  public static void main(String[] args) {
    SuperClass bc = new SuperClass();
    // Prints "This is superclass!"
    SuperClass sc = new SubClass();
    // Prints "This is subclass! The color is :null"
  }
}

کد بالا بدون مشکل و خطا اجرا می شود ولی در زمانی که در Constructor کلاس SubClass با استفاده از super سازنده کلاس SuperClass فراخوانی می شود بجای فراخوانی متد doLogic در SuperClass متد doLogic در SubClass فراخوانی می شود.

راه حل:

یا باید متد doLogic را غیرقابل override کرد یا اینکه بدنه متد doLogic را در محل مشخص در Constructor کپی کرد و از متد doLogic صرف نظر کرد.

قبل توسط (29 امتیاز)
تشکر بخاطر جواب کاملتون

سوالات مشابه

+1 امتیاز
1 پاسخ 1.2هزار بازدید
0 امتیاز
1 پاسخ 717 بازدید
0 امتیاز
1 پاسخ 767 بازدید
+2 امتیاز
1 پاسخ 571 بازدید
سوال شده 4 سال قبل در برنامه نویسی توسط 1993 (242 امتیاز)
0 امتیاز
1 پاسخ 377 بازدید
سوال شده 6 سال قبل در برنامه نویسی توسط یوری (426 امتیاز)
+1 امتیاز
1 پاسخ 507 بازدید
0 امتیاز
0 پاسخ 463 بازدید
+1 امتیاز
1 پاسخ 531 بازدید
+2 امتیاز
1 پاسخ 969 بازدید
...