java Java构造函数扩展

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10675076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:03:03  来源:igfitidea点击:

Java constructor extending

java

提问by ShadowPrince

When I extend some class,for example:

当我扩展某个类时,例如:

public class First {
    int id;
    public First(int _id) {
        id = _id;
    }
}

and

public class Second extends First {

}

I must redeclare the constructor for Second class, when I just need to do the same. I can:

当我只需要做同样的事情时,我必须重新声明 Second class 的构造函数。我能:

public Second(int _id) {
    super(_id);
}

But every time I change the parent constructor all of the extended classes' constructors need to be edited.

但是每次我更改父构造函数时,都需要编辑所有扩展类的构造函数。

How can I extend the constructor fully?

如何完全扩展构造函数?

Damn, don't tell me about phone and antenna, I have used OOP many times.

该死的,别跟我说电话和天线,我用过很多次OOP。

Now I only ask - can't I write public Class(){} on extended classes, and use the parent constructor?

现在我只问 - 我不能在扩展类上编写 public Class(){} 并使用父构造函数吗?

It seems that I can't. Okay.

我好像不能 好的。

回答by Ted Hopp

When you define a subclass, it does not inherit constructors from the superclass. For anything other than the default superclass constructor, you need to explicitly call a superclass constructor in each subclass constructor. (That means, among other things, that if the base class does not have a default constructor, neither can any child classevery child class constructor must explicitly call a superclass constructor—and no child class can have simply a compiler-generated default constructor. There's one exception to this; see [*]below.)

定义子类时,它不会从超类继承构造函数。对于默认超类构造函数以外的任何内容,您需要在每个子类构造函数中显式调用超类构造函数。(这意味着,除其他外,如果基类没有默认构造函数,那么每个子类构造函数的任何子类都不能显式调用超类构造函数——并且没有子类可以具有简单的编译器生成的默认构造函数。对此有一个例外;请参阅下面的[*]。)

Inheriting constructors could cause all sorts of problems. Imagine something like this:

继承构造函数可能会导致各种问题。想象一下这样的事情:

class Base {
    private int mId;
    public Base(int id) {
        mId = id;
    }
    . . .
}

Now we want to derive a class that has a second attribute—a tag—that we want to ensure is never null. So we write the following:

现在我们想要派生一个具有第二个属性(一个标签)的类,我们希望确保它是 never null。所以我们写如下:

class Derived extends Base {
    private Object mTag;
    public Derived(Object tag, int id) {
        super(id);
        if (tag == null) {
            throw new IllegalArgumentException("tag cannot be null");
        }
        mTag = tag;
    }
    . . .
}

Now imagine constructing an instance of Derivedlike this:

现在想象构建一个这样的实例Derived

Derived derived = new Derived(3);

If constructors were inherited, this would presumably be legal. What would it mean? For one thing, mTagwould be set to its default value of null. There would be no way for Derivedto enforce the rule that all instances of Derivedmust have a non-null tag.

如果构造函数是继承的,这大概是合法的。这意味着什么?一方面,mTag将设置为其默认值null。没有办法Derived强制执行所有实例都Derived必须具有非空标记的规则。

At the cost of requiring a bit more typing, Java rules out inheriting constructors precisely to allow each class to fully control how its instances get created.

以需要更多类型为代价,Java 排除了继承构造函数的可能性,以允许每个类完全控制其实例的创建方式。

[*]There's one case where the compiler will automatically generate a non-default constructor. Consider the Baseclass above and this code:

[*]在一种情况下,编译器会自动生成一个非默认构造函数。考虑Base上面的类和这段代码:

Base foo = new Base(3) {
    . . . // some extended functionality
};

Now foois being initialized to an anonymous subclass of Base. For ease of reference, let's call this subclass Base$Anon. The compiler will generate code equivalent to:

现在foo正在被初始化为 的匿名子类Base。为了便于参考,我们称这个子类为Base$Anon。编译器将生成等效于以下内容的代码:

class Base$Anon extends Base {
    Base$Anon(int id) {
        super(id);
    }
    . . . // some extended functionality
}

Base foo = new Base$Anon(3);

This is the only case where the compiler generates a non-default constructor if you don't specify any constructors of your own. In fact, the language syntax doesn't even let you declare a constructor for an anonymous class; you must rely on the compiler generating one for you.

如果您不指定任何自己的构造函数,这是编译器生成非默认构造函数的唯一情况。事实上,语言语法甚至不允许您为匿名类声明构造函数;您必须依靠编译器为您生成一个。

回答by Alexander Torstling

This limitation is one of the reasons why I prefer composition over inheritance. Consider using code like this instead:

这种限制是我更喜欢组合而不是继承的原因之一。考虑使用这样的代码:

public class Second {
    private final First first;

    public Second(final First first) {
         this.first=first;
    }

    public int getId() {
        return first.getId();
    }
}

This construct also leaves your two classes less coupled and makes the relation between the classes clearer in my opinion. For a more thorough discussion of composition over inheritance, see for instance this question: Prefer composition over inheritance?

在我看来,这种结构还使您的两个类不那么耦合,并使类之间的关系更加清晰。有关组合而不是继承的更深入讨论,请参见例如这个问题:更喜欢组合而不是继承?