2011-02-24 92 views
24

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

回答

17

你所描述的并不是压倒一切。如果您不指定默认构造函数,则 编译器将创建一个默认构造函数。如果它是一个子类,它会调用 默认的父类的构造(super()),它也将初始化所有实例变量 由类型的默认值(0的数字类型确定的默认值,假的布尔值,或目标的零 )。

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

3

只要它们采用不同的参数,就可以有许多构造函数。但是编译器放入一个默认的构造函数不会被称为“构造函数重载”。

+0

我不能否认你的答案,但OOP的基本规则,一般每个方法都必须重写,提供了其不被声明为final。 – Gopal 2011-02-24 03:27:45

0

你的例子不是一个覆盖。覆盖技术上发生在一个子类中,但在本例中,构造函数方法在原始类中被替换。

+0

但是,正如您可以观察到的那样,重写适用于具有相同数字签名但定义不同的方法。所以我们真的重写构造函数? – Gopal 2011-02-24 03:33:14

+2

不可以。最重要的概念只适用于继承。你是否在找人告诉你,你的'教师'是错的? – Corey 2011-02-24 04:35:27

3

无法重写构造函数。构造函数可以视为静态的,子类不能重写它的超级构造函数。

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

21

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

你提到的有关默认没有参数构造函数的东西只是构造函数如何工作的一个方面,与重写无关。

1

但是,如果我们自己编写它,那么 构造函数会自动调用。

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

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

11

这是永远不可能的。构造器重写在Java中是不可能的。

这是因为,

构造看起来像一个方法,但 名字应该是作为类名,并没有 返回值。

重写意味着我们已经宣布在超级类 ,恰好我们有 在子类中声明它被称为 重写。超类名与Sub 类名不同。

如果你想写超级类 构造函数,子类,则子 类将可以把它看成不 构造,因为名字应该 不匹配子类名称的方法。 会给出编译错误, 方法没有返回值。所以 我们应该声明为void,那么只有 它会编译。


看一看下面的代码:

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 
        .... 
        } 
} 
0

还应当指出的是,你不能覆盖的构造与超类的名字的构造函数的子类。 OOPS的规则告诉构造函数应该有名字作为它的类名。如果我们试图重载超类的构造函数,它将被视为一个没有返回类型的未知方法。

0

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

覆盖意味着我们已经在超类中声明了什么,我们不得不在Sub类中声明它被称为覆盖。超类名和子类名是不同的。

如果您尝试在Sub类中编写超级类构造函数,那么Sub类会将其视为不构造函数的方法,因为名称不应与Sub类名称匹配。它会给出一个编译错误,方法没有返回值。所以我们应该声明为无效,那么只有它才会被编译。

0

在java中重写的方法用于改进以前编写的最新代码性能。

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

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

大小将返回可能的字节总数A.TXT 所以

1

因为构造函数不能在Java中被继承和方法覆盖要求继承。因此,它不适用。

0

由于以下原因,构造函数重写是不可能的。

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

2

不,它不可能重写构造函数。如果我们试图做到这一点,那么编译器会出错。在Java中这是不可能的。让我们看看这个例子。它会问请写一个返回类型的方法。意味着它会将该重写的构造函数视为一种方法而不是构造函数。

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(); 
    } 

} 
+0

结果:我们在动物类 我们在狗展示类 我们在动物类 – hitesh141 2015-04-30 13:05:35