构造函数是否可能超越?

时间:2011-02-24 03:05:07

标签: java constructor override

我所知道的是,编译器在字节码中编写了一个默认的无参数构造函数。但是如果我们自己编写它,那么构造函数会自动调用。这种现象是构造函数的重写吗?

15 个答案:

答案 0 :(得分:22)

构造函数不是常规方法,它们不能被“覆盖”。假设可以重写构造函数意味着超类构造函数是可见的,可以调用它来创建子类的实例。这不是真的......默认情况下,子类没有任何构造函数(除了构造函数,如果它扩展的类有一个)。它必须显式声明任何其他构造函数,并且那些构造函数属于它而不属于它的超类,即使它们采用与超类构造函数相同的参数。

你提到的关于默认没有arg构造函数的东西只是构造函数工作方式的一个方面,与覆盖无关。

答案 1 :(得分:21)

你所描述的并不是最重要的。如果您没有指定默认构造函数,那么 编译器将创建一个默认构造函数。如果它是一个子类,它将调用 默认的父构造函数(super()),它还会将所有实例变量初始化为 由类型的默认值确定的默认值(数字类型为0,布尔值为false或null 对象)。

当子类具有相同的名称,参数的数量/类型和时,会发生覆盖 与超类的实例方法相同的返回类型。在这种情况下,子类 将覆盖超类的方法。 Information on overriding here

答案 2 :(得分:13)

永远不可能。构造函数覆盖在Java中是不可能的。

这是因为,

  

构造函数看起来像一个方法但是   name应该是类名而不是   返回值。

     

覆盖意味着我们声明的内容   在超级课程中,我们确实拥有   在Sub类中声明它被调用   重写。超级名称和子   班级名称不同。

     

如果你想写超级课程   Sub类中的构造函数,然后是Sub   class会将其视为一种方法   构造函数,因为名称应该   与Sub类名称不匹配。它   会给出编译错误   方法没有返回值。所以   我们应该宣布为无效,然后才宣布   它会编译。


查看以下代码:

Class One
        {
         ....
         One() { // Super Class constructor
          .... 
        }

        One(int a) { // Super Class Constructor Overloading
          .... 
        }
 }

Class Two extends One
                   {
                    One() {    // this is a method not constructor 
                    .....      // because name should not match with Class name
                   }

                    Two() { // sub class constructor
                   ....  
                   }

                   Two(int b) { // sub class constructor overloading
                   ....
                  }
 }  

答案 3 :(得分:3)

只要它们具有不同的参数,您就可以拥有许多构造函数。但是将默认构造函数放入的编译器不称为“构造函数重写”。

答案 4 :(得分:3)

无法覆盖构造函数。构造函数可以视为静态,子类不能覆盖其超级构造函数。

当然,您可以在超类构造函数中调用protected-method,然后在子类中覆盖它以更改超类构造函数。但是,许多人建议不要使用这个技巧,以保护超类构造函数的行为。例如,FindBugs会警告你构造函数调用非final方法。

答案 5 :(得分:2)

不可以覆盖构造函数。如果我们尝试这样做,那么编译器错误就会出现。在Java中永远不可能实现。让我们看看这个例子。请问请写一个返回类型o方法。意味着它会将覆盖构造函数视为一种方法,而不是构造函数。

package com.sample.test;

class Animal{

    public static void showMessage()
    {
        System.out.println("we are in Animal class");
    }
}

class Dog extends Animal{

    public void DogShow() 
    {
        System.out.println("we are in Dog show class");
    } 

    public static void showMessage()
    {
        System.out.println("we are in overriddn method of dog class");
    }
}

public class AnimalTest { 

    public static void main(String [] args)
    {
        Animal animal = new Animal();
        animal.showMessage();

        Dog dog = new Dog();
        dog.DogShow();

        Animal animal2 = new Dog();
        animal2.showMessage();
    }

}

答案 6 :(得分:1)

  

但如果我们自己写,那   构造函数被自动调用。

这不正确。如果你调用它,那么no-args构造函数被称为 ,无论你是否自己编写它。如果您不在派生类中编写显式超级(...)调用,也会自动调用它。

这些都不构成构造函数重写。 Java中没有这样的东西。 构造函数重载,即提供不同的参数集。

答案 7 :(得分:1)

因为构造函数不能在Java中继承而且Method Overriding需要继承。因此,它不适用。

答案 8 :(得分:0)

您的示例不是覆盖。从技术上讲,覆盖在子类中,但在此示例中,构造方法在原始类中被替换。

答案 9 :(得分:0)

还应该注意,您不能使用超类名称的构造函数覆盖子类中的构造函数。 OOPS的规则告诉构造函数应该具有名称作为其类名。如果我们尝试覆盖超类构造函数,它将被视为没有返回类型的未知方法。

答案 10 :(得分:0)

构造函数看起来像一个方法,但名称应该是类名,没有返回值。

Overriding意味着我们在Super类中声明的内容,我们必须在Sub类中声明它被称为Overriding。超类名和子类名不同。

如果您尝试在Sub类中编写超类构造函数,则Sub类会将其视为方法而非构造函数,因为name不应与Sub类名匹配。它会给出一个编译错误,即方法没有返回值。所以我们应该声明为void,然后才会编译。

答案 11 :(得分:0)

java中的方法覆盖用于改进先前编写的代码性能。

一些代码表明我们在这里创建基类的引用并创建派生类的phyisical实例。 在构造函数重载是可能的。

InputStream fis=new FileInputStream("a.txt");
int size=fis.available();

size将返回a.txt中可能的总字节数 所以

答案 12 :(得分:0)

由于以下原因,无法构造函数覆盖。

构造函数名称必须与类名相同。在继承实践中,您需要创建两个具有不同名称的类,因此两个构造函数必须具有不同的名称。所以构造函数覆盖是不可能的,这种想法甚至没有意义。

答案 13 :(得分:0)

我发现这是这个问题的一个很好的例子:

    class Publication {

    private String title;

    public Publication(String title) {
        this.title = title;
    }

    public String getDetails() {
        return "title=\"" + title + "\"";
    }

}

class Newspaper extends Publication {

    private String source;

    public Newspaper(String title, String source) {
        super(title);
        this.source = source;
    }

    @Override
    public String getDetails() {
        return super.getDetails() + ", source=\"" + source + "\"";
    }
}

class Article extends Publication {

    private String author;

    public Article(String title, String author) {
        super(title);
        this.author = author;
    }

    @Override
    public String getDetails() {
        return super.getDetails() + ", author=\"" + author + "\"";
    }

}

class Announcement extends Publication {

    private int daysToExpire;

    public Announcement(String title, int daysToExpire) {
        super(title);
        this.daysToExpire = daysToExpire;
    }

    @Override
    public String getDetails() {
        return super.getDetails() + ", daysToExpire=" + daysToExpire;
    }

}

答案 14 :(得分:0)

虽然其他人指出不可能在语法上覆盖构造函数,但我还想指出,这样做在概念上是不好的。假设超类是一个狗对象,子类是一个赫斯基对象。 dog 对象具有诸如“4 条腿”、“尖鼻”等属性,如果“覆盖”意味着删除狗并用 Husky 替换它,那么 Husky 将缺少这些属性并成为一个损坏的对象。哈士奇从来没有这些特性,只是从狗身上继承了它们。 另一方面,如果你打算给哈士奇狗所拥有的一切,那么从概念上讲,你可以用哈士奇“覆盖”狗,但是创建一个与狗相同的类是没有意义的,它实际上不是一个继承类但完全替代。