簡體   English   中英

不能直接調用超類型構造函數 - 為什么不呢?

[英]Can't call supertype constructor directly - why not?

我在Java中有以下示例類:

public class A { }

public class Super {
    protected Super() { }
    public Super(A a) { }
}

public class Sub extends Super { }

public class Consumer {
    public Consumer() {
        Sub sub = new Sub(new A()); //compiler error
    }
}

編譯器錯誤表明參數不能應用於Sub中的默認構造函數,這是完全可以理解的。

我很好奇的是這個決定背后的理由。 Java在Sub生成默認的空構造函數; 為什么不能在這種情況下在幕后調用呢? 這主要是理智的手持,還是有技術原因?

編輯

我知道這是一個語言的限制。 我很好奇為什么它是一種語言限制。

編輯2

看起來,通常情況下,我太過接近我實際工作的代碼,看看大局。 我在下面的答案中發布了一個反例,說明了為什么這是BadThing®。

public class Sub extends Super { }

沒有構造函數Sub(A a),它只有默認構造函數Sub()。

構造函數不是繼承的。

基類需要調用超級構造函數以確保正確實例化對象。 例如考慮:

class Super {
   final String field1;

   public Super(String field1) {
      this.field1 = field1;
   }
   ...
}


class Base extends Super {
   final String field2;

   public Base(String field2) {
      this.field2 = field2;
   }
   ...
}

Base的構造函數是否覆蓋了Super構造函數? 如果是這樣,則不再保證field1被初始化,使得繼承的方法出乎意料地行為。

在向子類添加非默認構造函數的那一刻,繼承的構造函數就會停止工作。 我認為這是一個令人困惑且很少有用的功能,它被添加到語言中,雖然從技術上講,我看不出有什么理由不可能。

我認為這是一個既可讀性也不假設意圖的問題。 你說

Java生成默認的空構造函數; 為什么不能在這種情況下在幕后調用呢?

然而對我而言,Java隱藏地調用Super(A)構造函數“幕后”比調用Super()構造函數,忽略A更有意義。

你有它。 關於在這種情況下應該(或可能 )發生什么,我們已經有兩個截然不同的假設。

Java語言的核心原則之一是透明度。 程序員應該盡可能地通過查看代碼將會發生什么,有時會犧牲方便性或語法級別的魔力

與此並行的原則並不是假設意圖:在程序員的意圖看似含糊不清的情況下,Java語言有時會支持編譯錯誤,而不是通過某些(任意或其他)選擇算法自動選擇默認值。

你已經覆蓋了默認的公共構造函數,因此沒有任何東西可以調用。

所以Sub類相當於

public class Sub extends Super
{
    protected Sub(){}
    public Sub(A a) { }
}

它會因為它

  • Sane行為 - 按程序員的指示行事,它也遵循OOP語言中的繼承概念
  • 遵循其C ++遺產

我把這個作為這種行為的技術原因; 我同意其他幾個答案,這可能在語義上令人困惑。

請考慮以下示例:

public class A { }

public abstract class Super {
    protected Super() {
        // perform time consuming, destructive, or
        // otherwise one-time operations
    }

    public Super(A a) {
        this();
        // perform A-related construction operations
    }
}

public class Sub extends Super { }

public class Consumer {
    public Consumer() {
        Sub sub = new Sub(new A());
    }
}

構造Sub ,在這種情況下,將調用Sub上的默認構造函數,它將鏈接到Super上的默認構造函數(因為這是語言定義的魔力)。 然后,對Super(A)調用將調用設計為在構造時運行一次的邏輯。 這顯然不是開發者的意圖。

即使沒有Super(A)構造函數中的this()調用,開發人員的意圖也無法確定; 由於某種原因,構造函數可能是互斥的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM