2015-08-28 67 views
4

編輯2:順便說一下,我的代碼在工作,並通過了所有的測試人員。我只是試圖圍繞構造函數進行包裝。日期d是一個對象; Date的構造函數的一個產品,是否正確?因此,如果IncDate是一個Date(這就是我認爲的延伸手段),是不是有權訪問Date的構造函數,因此能夠創建新的Date對象和/或使用它們?再次,夥計們,非常感謝!Java:爲什麼你需要構造函數來在父類中使用對象?

例如:我在我的數據結構類中工作的類看起來像這樣。這是子類的構造函數:

public class IncDate extends Date 
public IncDate(int newMonth, int newDay, int newYear) 
{ 
    super(newMonth, newDay, newYear); 
} 

public void increment() 
{ 
    Date d = inverseLilian(lilian() + 1); 
    month = d.month; 
    day = d.day; 
    year = d.year; 
} 

這是父類的構造函數:

public Date(int newMonth, int newDay, int newYear) 
{ 
    month = newMonth; 
    day = newDay; 
    year = newYear; 
} 

因此,這裏是我的問題。如果函數「extends」基本上允許子類訪問其方法和對象,那麼在世界中我是否需要在子類中創建一個新的構造函數,以便我可以使用在父類中創建的Date對象?它使我困惑不已。如果有的話,所有的IncDate構造函數都會繼承父類的構造函數的值,但它不會繼承使用Date對象的選項,因爲擴展基本上意味着「是a」,所以IncDate是Date類,因此因此它應該可以選擇創建和使用Date對象,而無需使用它自己的構造函數。我很困惑。

TL; DR:如果我刪除IncDate構造函數,則Increment方法中的Date對象不起作用。爲什麼?

謝謝你們。你在這附近有很大的幫助!

編輯:因爲有人問,這裏是Date類中的inverseLilian和lilian方法。

public Date inverseLilian(int lilian) 
{ 
    int temp = ((lilian + 139444) * 100)/3652425; 
    int days = temp + lilian + 139444 - (temp/4); 
    temp = days * 100/36525; 
    if((days * 100) % 36525 == 0) 
     temp -= 1; 
    days = days - (temp * 36525/100); 
    int years = temp + 1201; 

    // account for leap year 
    int leapDay = 0; 
    if (years % 4 == 0) leapDay ++; 
    if (years % 100 == 0) leapDay --; 
    if (years % 400 == 0) leapDay ++; 

    if (days > leapDay + 59) days += (2 - leapDay); 
    int months = (((days + 91) * 100)/3055); 
    days = (days + 91) - ((months * 3055)/100); 
    months -= 2; 

    return new Date(months,days,years); 
} 


    public int lilian() 
{ 
    // Returns the Lilian Day Number of this date. 
    // Precondition: This Date is a valid date after 10/14/1582. 
    // 
    // Computes the number of days between 1/1/0 and this date as if no calendar 
    // reforms took place, then subtracts 578,100 so that October 15, 1582 is day 1. 

    final int subDays = 578100; // number of calculated days from 1/1/0 to 10/14/1582 

    int numDays = 0; 

    // Add days in years. 
    numDays = year * 365; 

    // Add days in the months. 
    if (month <= 2) 
     numDays = numDays + (month - 1) * 31; 
    else 
     numDays = numDays + ((month - 1) * 31) - ((4 * (month-1) + 27)/10); 

    // Add days in the days. 
    numDays = numDays + day; 

    // Take care of leap years. 
    numDays = numDays + (year/4) - (year/100) + (year/400); 

    // Handle special case of leap year but not yet leap day. 
    if (month < 3) 
    { 
     if ((year % 4) == 0) numDays = numDays - 1; 
     if ((year % 100) == 0) numDays = numDays + 1; 
     if ((year % 400) == 0) numDays = numDays - 1; 
    } 

    // Subtract extra days up to 10/14/1582. 
    numDays = numDays - subDays; 
    return numDays; 

回答

2

這是因爲沒有默認的構造函數。默認的構造函數是沒有參數的構造函數。

2

從Oracle官方的Java教程:

你不必爲你的類提供任何構造函數,但這樣做的時候,你一定要小心。編譯器自動爲任何沒有構造函數的類提供一個無參數的默認構造函數。這個默認構造函數將調用超類的無參構造函數。在這種情況下,如果超類沒有無參數構造函數,編譯器會發出抱怨,因此您必須驗證它是否存在。如果你的類沒有顯式超類,那麼它有一個隱式超類Object,它有一個無參構造函數。

所以,在你的情況下,爲了使你的代碼正常工作,你需要明確地爲你父母的Date類提供一個空的構造函數(但要小心你需要手動爲這些字段提供值,構造函數不會初始化字段「newMonth」,「newDay」和「newYear」)。

3

因爲構造函數不像普通方法那樣繼承。因此,父類中的構造函數不能直接提供給子類。

但你仍然可以從你的子類構造函數調用父構造函數。

所以解決的辦法是在你的子類中創建一個構造函數,然後調用父類中的構造函數。

+0

由於Date d是一個對象,因此我需要父類的構造函數來創建一個新的Date對象,因爲對象是由構造函數生成的!我希望這是正確的。謝啦。 – user5277222

2

該JLS section 8.8.9使這個明確。

這是一個編譯時錯誤,如果默認的構造函數是隱式聲明,但超類沒有可訪問的構造函數沒有參數,也沒有throws子句。

讓我們回過頭來,描述兩種不同類型的構造函數 - 默認和定義。

默認構造函數被隱式聲明爲;也就是說,如果你沒有爲類聲明你自己的構造函數,Java會爲你聲明它。它僅包含super()呼叫(只要它不是Object):

如果所聲明的類是原始類的對象,那麼默認的構造函數有一個空的機構。否則,默認構造函數只是簡單地調用沒有參數的超類構造函數。

定義的構造方法是你明確聲明。即使它與隱式構造函數相匹配,構造函數的存在意味着不再需要使用Java的「默認」構造函數。

所以,這意味着對於兩個類ParentChild,它們的聲明看起來就像Java一樣。請注意,這些是隱含聲明。現在

public class Parent { 
    public Parent() { 
     super(); // call out to Object's constructor 
    } 
} 

public class Child extends Parent { 
    public Child() { 
     super(); // call out to Parent's constructor 
    } 
} 

,這就是爲什麼你的代碼將無法正常工作:你的父類沒有默認的構造函數,不扔東西,這是隱式調用所期待的。

public class Date { 
    // Declared, not a default constructor 
    public Date(int newMonth, int newDay, int newYear) { 
     month = newMonth; 
     day = newDay; 
     year = newYear; 
    } 
} 

public class IncDate extends Date 
    public IncDate() { 
     super(); // implicit default constructor 
    } 
} 

你的父類沒有一個無參數的構造函數,所以調用super失敗。

相關問題