我所知道的是,编译器在字节码中编写了一个默认的无参数构造函数。但是如果我们自己编写它,那么构造函数会自动调用。这种现象是构造函数的重写吗?
答案 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 将缺少这些属性并成为一个损坏的对象。哈士奇从来没有这些特性,只是从狗身上继承了它们。 另一方面,如果你打算给哈士奇狗所拥有的一切,那么从概念上讲,你可以用哈士奇“覆盖”狗,但是创建一个与狗相同的类是没有意义的,它实际上不是一个继承类但完全替代。