Java构造函数扩展

Sha*_*nce 4 java

当我扩展一些类时,例如:

public class First {
    int id;
    public First(int _id) {
        id = _id;
    }
}
Run Code Online (Sandbox Code Playgroud)

public class Second extends First {

}
Run Code Online (Sandbox Code Playgroud)

当我只需要做同样的事情时,我必须重新声明第二类的构造函数.我可以:

public Second(int _id) {
    super(_id);
}
Run Code Online (Sandbox Code Playgroud)

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

如何完全扩展构造函数?

该死的,不要告诉我手机和天线,我多次使用过OOP.

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

好像我不能.好的.

Ted*_*opp 9

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

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

class Base {
    private int mId;
    public Base(int id) {
        mId = id;
    }
    . . .
}
Run Code Online (Sandbox Code Playgroud)

现在我们想要派生一个具有第二个属性的类 - 一个我们想要确保永远不会的标记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;
    }
    . . .
}
Run Code Online (Sandbox Code Playgroud)

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

Derived derived = new Derived(3);
Run Code Online (Sandbox Code Playgroud)

如果构造函数是遗传的,那么这可能是合法的.这是什么意思?首先,mTag将其设置为其默认值null.没有办法Derived强制执行Derived必须具有非null标记的所有实例的规则.

需要更多输入的代价是,Java排除了精确继承构造函数以允许每个类完全控制其实例的创建方式.

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

Base foo = new Base(3) {
    . . . // some extended functionality
};
Run Code Online (Sandbox Code Playgroud)

现在foo正被初始化为一个匿名子类Base.为了便于参考,让我们调用这个子类Base$Anon.编译器将生成相当于的代码:

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

Base foo = new Base$Anon(3);
Run Code Online (Sandbox Code Playgroud)

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


Ale*_*ing 2

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

public class Second {
    private final First first;

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

    public int getId() {
        return first.getId();
    }
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这种构造还可以减少两个类的耦合,并使类之间的关系更加清晰。有关组合而不是继承的更彻底的讨论,请参见例如这个问题:更喜欢组合而不是继承?