Java继承问题

3

假设我扩展了一个类并覆盖了其中的方法。为什么在我的新类构造函数中调用被覆盖的方法是一种不良实践?


1
为什么你说这是不好的做法?这可能取决于具体情况... - jk.
2
Netbeans会将其下划线并给出警告。 - user489041
好的,那个警告说什么? - gatkin
C#中类似的问题 https://dev59.com/V3VD5IYBdhLWcg3wAWoO - Bala R
它只是在下划线并显示“构造函数中的可重写方法调用”,好像在警告我即将发生不好的事情。 - user489041
@user489041,不好意思如果我之前提过了,但是你有34个问题没有被接受的答案。 - Peter Lawrey
5个回答

12

在构造函数中避免调用可重写方法的主要原因是它允许子类看到半构造状态的类。这可能或可能不是安全风险,但它是一个等待发生的错误。在此处阅读更多


+1 个链接......终于有了去海滩时可以阅读的东西! - SJuan76

5
一般来说,在构造函数中进行工作是不好的实践 - 只需获取并分配对象依赖项即可。

3

因为类的实例可能处于不一致的状态。以下是一个具体的例子。

public class Foo {
    private int number;

    public Foo() {
        number = 42;
        multiplyNumber();
    }

    public void multiplyNumber() {
        number = number * 2;
    }

    public int getNumber() {
        return number;
    }
}

public class Bar extends Foo {

    private int number;

    public Bar() {
        multiplyNumber();
    }

    @Override
    public void multiplyNumber() {
        number = number * 3;
    }
}

public class FooBar {

    public static void main(String[] args) {
        Foo foo = new Foo();
        Foo bar = new Bar();
        System.out.println("Foo number 1 = " + foo.getNumber()); // Returns 84
        System.out.println("Foo number 2 = " + bar.getNumber()); // Returns 42; 
    }
}

运行调试时,bar 构造函数中的 multiplyNumber() 方法从未被调用,直接跳过。因此,number 属性没有预期的值。 构造函数应该是简单的实体;最好不要在其中放置任何非常复杂的内容。

3

有人可以从您的类继承并更改您在构造函数中依赖的行为。

这意味着您不知道该函数将要做什么。


1

想象一下,在构造函数中调用一个可重写的方法。你再次创建子类并进行覆盖。第二个子类可以中断第一个子类所依赖的工作,以使其被视为完全初始化,从而使其处于损坏状态。

至于构造函数中的工作,你可以做一些工作,但通常应该是初始化对象所需的类型的工作。

作为最佳实践,尽量避免继承,如果你决定将构造函数工作分成方法,请使用可见性修饰符确保所有工作都保留在正在构建的类中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接