调用Java中的构造函数 [英] Calling of Constructors in a Java

查看:164
本文介绍了调用Java中的构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java:完整的参考

In the book Java: The complete reference

// Demonstrate when constructors are called.
// Create a super class.
class A {
     A() {
        System.out.println("Inside A's constructor.");
     }
}
// Create a subclass by extending class A.
class B extends A {
      B() {
             System.out.println("Inside B's constructor.");
      }
 }
// Create another subclass by extending B.
class C extends B {
    C() {
        System.out.println("Inside C's constructor.");
    }
}
class CallingCons {
    public static void main(String args[]) {
        C c = new C();
    }
}

输出:
A的构造函数
B里面的构造函数
里面的C构造函数

Output: Inside A’s constructor Inside B’s constructor Inside C’s constructor

它演示了如何调用子类的构造函数。但为什么在没有super()构造函数的情况下调用超类的构造函数。

It is demonstrating how the constructor of a subclass is called. But why are constructors of the super class called in the absence of a super() constructor.

为什么Java语言设计者认为有必要这样做?

Why did the Java Language designers consider it necessary to do so?

推荐答案

正如其他人所指出的,如果您不使用 super(...)调用启动构造函数,编译器将调用 super()

As others have pointed out, if you don't start your constructor with a super(...) call, the compiler will put in a call to super() for you.

至于为什么什么是构造函数首先:初始化对象。这是什么意思,具体?

As to the why, you have to start with remembering what a constructor is for in the first place: initializing the object. What does that mean, specifically? In practice, it means assigning values to the object's fields, and establishing invariants.

没有调用 super() B A 类不会有机会为它们包含的任何字段。你甚至不能让 C()构造函数为它们做这些,如果这些字段是私有的,因为私有字段在你的类之外是不可访问的超类的字段可访问)。即使你可以,这不是一个好主意;它也会破坏封装。例如,假设如果一个超级类(可能是一个复杂的类,其内部不是专家)突然决定更改其实现细节,则必须更改代码。

Without a call to super(), the B and A classes wouldn't have a chance to do that for whatever fields they contain. And you can't even have the C() constructor do it for them, if those fields are private, since private fields aren't accessible outside your class (not even your super class's fields are accessible). Even if you could, it wouldn't be a good idea; it would also break encapsulation. For instance, imagine having to change your code if a super class -- possibly a complex one whose internals you're not an expert in -- suddenly decided to change its implementation details.

为了说明这一点,考虑一组非常简单的类:

To illustrate this, consider a very simple set of classes:

public class Super {
    private final String name;

    Super() {
        name = "default";
    }

    public String name() {
        return name.toUpperCase();
    }
}

public class Sub extends Super {
    public Sub() {
        // don't do anything
    }
}



当您实例化 Sub ,它将通过调用 Super 的构造函数开始。如果没有, name 字段将为null(引用类型的默认值)。但是 name()方法不检查null;它假定引用是非空的,因为构造函数建立了不变量。因此,在不调用超级构造函数的伪Java中, Super.name 必须更复杂一些 - 它必须检查 name == null

When you instantiate Sub, it will start out by calling Super's constructor. If it didn't, the name field would be null (the default value for reference types). But the name() method doesn't check for null; it assumes that the reference is non-null, because the constructor establishes that invariant. So, in our pseudo-Java that doesn't call the super constructor, Super.name has to get a bit more complicated -- it has to check for name == null.

你可以想象,随着类获得更多字段,更有趣的不变式,越来越复杂。强制您调用超级构造函数 - 无论是显式还是隐式 - 允许该超类的作者建立其不变量,从而产生更简单,更易于维护的代码。

You can imagine that as the classes gain more fields, with more interesting invariants, this toy example can become more and more complicated. Forcing you to call the super constructor -- either explicitly or implicitly -- lets the authors of that super class establish their invariants, resulting in simpler, more maintainable code.

这篇关于调用Java中的构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆