Java:为什么需要构造函数在父类中使用对象?

时间:2015-08-28 14:53:03

标签: java inheritance

编辑2:顺便说一句,伙计们,我班上的代码可以运行并通过所有测试人员。我只是想绕着构造者。日期d是一个对象; Date的构造函数的产品,对吗?因此,如果IncDate是一个日期(这是扩展的意思,我认为),它是否可以访问Date的构造函数,因此能够创建新的Date对象和/或使用它们?伙计们,非常感谢!

例如:我在Data Structures类中处理的类看起来像这样。这是子类的构造函数:

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对象的选项,因为extends基本上意味着“是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;

4 个答案:

答案 0 :(得分:3)

因为构造函数不像普通方法那样继承。因此,父类中的构造函数不能直接用于子类。

但您仍然可以从子类构造函数中调用父构造函数。

所以解决方法是在子类中创建一个构造函数,然后调用父类中的构造函数。

答案 1 :(得分:2)

因为没有默认构造函数。默认构造函数是没有参数的构造函数。

答案 2 :(得分:2)

来自官方Oracle Java教程:

  

您不必为您的班级提供任何构造函数,但在执行此操作时必须小心。编译器自动为没有构造函数的任何类提供无参数的默认构造函数。此默认构造函数将调用超类的无参数构造函数。在这种情况下,如果超类没有无参数构造函数,编译器会抱怨,因此您必须验证它是否存在。如果你的类没有显式的超类,那么它有一个隐式的超类Object,它有一个无参数的构造函数。

因此,在您的情况下,为了使您的代码工作,您需要为您的父Date类显式提供一个空构造函数(但要小心,您需要手动提供字段的值,作为空构造函数不会初始化字段&#34; newMonth&#34;,&#34; newDay&#34;和&#34; newYear&#34;)。

答案 3 :(得分:2)

JLS section 8.8.9明确了这一点。

  

如果隐式声明了默认构造函数,但是超类没有可访问的构造函数,该构造函数不带参数且没有throws子句,那么这是一个编译时错误。

让我们稍微回顾一下并描述两种不同类型的构造函数 - 默认和定义。

默认构造函数隐式声明;也就是说,如果你没有为类声明自己的构造函数,Java会为你声明它。它只包含对super()的调用(只要它不是Object):

  

如果声明的类是原始类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
    }
}

您的父类没有no-arg构造函数,因此对super的调用失败。