【问题标题】:Overload the constructor of a subclass重载子类的构造函数
【发布时间】:2016-01-14 12:51:55
【问题描述】:

我正在尝试创建一个构造函数,它采用Punto 类型的 2 个元素并将其分配给实例变量,在我的超类中我已经有一个构造函数,但我想要在我的子类中再添加一个,所以首先在我的子类中我调用超类构造函数,然后我尝试再添加一个,但出现以下错误:

类中的构造函数不能应用于给定类型。

超类:

public class Poligono  implements Figura  {

Punto[] vertici;

public Poligono(Punto[] vertici) throws IndexOutOfBoundsException {
    if(vertici == null || vertici.length<3) {
        throw new IndexOutOfBoundsException();
    } 
    this.vertici = vertici;
}

子类:

package figura;

import punto.Punto;


public class Rettangolo extends Poligono{

   Punto p1;
   Punto p2;

   public Rettangolo(Punto[] vertici) throws IndexOutOfBoundsException {
       super(vertici);
   }

   public Rettangolo(Punto p1, Punto p2) throws NullPointerException{

       if(p1==null || p2==null) throw new NullPointerException();

       this.p1 = p1;
       this.p2 = p2;
   }

在我的第二个构造函数中,我得到了错误:

constructor Poligono in class Poligono cannot be applied to given types;
required: Punto[]
found: no arguments
reason: actual and formal argument lists differ in length

【问题讨论】:

  • 请注意,您几乎肯定希望在构造函数中获取vertici 的副本:所谓的防御性副本 可以保护您的Poligono 类免受后续更改vertici 数组。

标签: java inheritance constructor


【解决方案1】:

您的public Rettangolo(Punto p1, Punto p2) 必须调用超类Poligono 的某个构造函数。编译器抱怨唯一可用的构造函数 - Poligono(Punto[] vertici) - 不适合第二个 Rettangolo 构造函数的参数。

您必须使用super(..) 调用显式调用Poligono 构造函数。

假设传递给该构造函数的两个点是矩形的两个对角,并且 Poligono 构造函数需要一个顶点数组,您需要这样的东西:

public Rettangolo(Punto p1, Punto p2) {

    super (new Punto[]{p1,
                       new Punto (p1.getX(),p2.getY()), 
                       p2, 
                       new Punto (p2.getX(),p1.getY())});

    this.p1 = p1;
    this.p2 = p2;
}

我可能弄错了点的顺序或方法名称。

【讨论】:

    【解决方案2】:

    Why does this() and super() have to be the first statement in a constructor?

    你可以做的(除了打电话super())是

    public Rettangolo(Punto p1, Punto p2) {
         super(new Punto[] {p1, p2});
    }
    

    我更喜欢这个解决方案,因为如果您使用Rettangolo(Punto[]),您将没有任何可使用的点。因此,要么您阅读第一个构造函数中的要点,例如,

    public Rettangolo(Punto[] vertici) throws IndexOutOfBoundsException {
       super(vertici);
       p1 = vertici[0];
       p2 = vertici[1];
    }
    

    或者您不使用单点,而只使用数组。

    【讨论】:

      【解决方案3】:

      如果您初始化“Rettangolo”对象,则不会调用超类构造函数。

      无论何时创建一个对象,父类状态都会在子类之前初始化。

      构造函数的第一行要么调用父构造函数,要么调用同一个类的另一个构造函数,它会调用父构造函数。

      现在你的情况:

      public Rettangolo(Punto p1, Punto p2) throws NullPointerException{
      
         if(p1==null || p2==null) throw new NullPointerException();
      
         this.p1 = p1;
         this.p2 = p2;
      

      }

      您的构造函数正在尝试调用默认构造函数,但由于没有定义这样的构造函数,因此发生错误。

      您要么为父类定义一个默认构造函数并初始化Punto p1,p2,但随后vertici[]数组将为空。

      或者你可以这样做

      public Rettangolo(Punto p1, Punto p2) throws NullPointerException{
         super(new Punto[] {p1,p2});
         if(p1==null || p2==null) throw new NullPointerException();
      
         this.p1 = p1;
         this.p2 = p2;
      }
      

      但这取决于您的要求。你只需要记住,父类的构造函数总是会被首先调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-30
        • 2021-01-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多