別のコンストラクターを呼び出すことは可能ですか (サブクラスからではなく、同じクラス内で)? はいの場合、どのように?そして、別のコンストラクターを呼び出す最良の方法は何ですか (それを行う方法がいくつかある場合)?
23 に答える
はい、可能です:
public class Foo {
private int x;
public Foo() {
this(1);
}
public Foo(int x) {
this.x = x;
}
}
同じクラスのコンストラクターではなく、特定のスーパークラス コンストラクターにチェーンするには、super
代わりにthis
. チェーンできるのは 1 つのコンストラクターのみであり、それはコンストラクター本体の最初のステートメントでなければならないことに注意してください。
この関連する質問も参照してください。これは C# に関するものですが、同じ原則が適用されます。
を使用してthis(args)
います。推奨されるパターンは、最小のコンストラクターから最大のコンストラクターまで動作することです。
public class Cons {
public Cons() {
// A no arguments constructor that sends default values to the largest
this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
}
public Cons(int arg1, int arg2) {
// An example of a partial constructor that uses the passed in arguments
// and sends a hidden default value to the largest
this(arg1,arg2, madeUpArg3Value);
}
// Largest constructor that does the work
public Cons(int arg1, int arg2, int arg3) {
this.arg1 = arg1;
this.arg2 = arg2;
this.arg3 = arg3;
}
}
最近提唱されている valueOf または単に「of」のアプローチを使用することもできます。
public class Cons {
public static Cons newCons(int arg1,...) {
// This function is commonly called valueOf, like Integer.valueOf(..)
// More recently called "of", like EnumSet.of(..)
Cons c = new Cons(...);
c.setArg1(....);
return c;
}
}
スーパー クラスを呼び出すには、 を使用しますsuper(someValue)
。super の呼び出しは、コンストラクターでの最初の呼び出しでなければなりません。そうしないと、コンパイラ エラーが発生します。
[注: 他の回答では見られなかった 1 つの側面を追加したいだけです: this() が最初の行になければならないという要件の制限を克服する方法)。]
Java では、同じクラスの別のコンストラクターを、コンストラクターから を介して呼び出すことができますthis()
。ただしthis
、最初の行にある必要があることに注意してください。
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, 0.0);
}
public MyClass(double argument1, double argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
}
最初の行に表示する必要があることthis
は大きな制限のように見えますが、静的メソッドを介して他のコンストラクターの引数を構築できます。例えば:
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, getDefaultArg3(argument1, argument2));
}
public MyClass(double argument1, double argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
private static double getDefaultArg3(double argument1, double argument2) {
double argument3 = 0;
// Calculate argument3 here if you like.
return argument3;
}
}
コード内 (最初の行ではなく) から別のコンストラクターを呼び出す必要がある場合は、通常、次のようなヘルパー メソッドを使用します。
class MyClass {
int field;
MyClass() {
init(0);
}
MyClass(int value) {
if (value<0) {
init(0);
}
else {
init(value);
}
}
void init(int x) {
field = x;
}
}
しかし、ほとんどの場合、可能な限り、最初の行の単純なコンストラクターからより複雑なコンストラクターを呼び出すことによって、逆の方法で実行しようとします。上記の例では
class MyClass {
int field;
MyClass(int value) {
if (value<0)
field = 0;
else
field = value;
}
MyClass() {
this(0);
}
}
誰もがすでに言ったように、明示的なコンストラクター呼び出しthis(…)
と呼ばれる を使用します。
ただし、そのような明示的なコンストラクター呼び出しステートメント内では、参照できないことに注意してください。
- インスタンス変数または
- インスタンスメソッドまたは
- このクラスまたはスーパークラスで宣言された内部クラス、または
this
またsuper
.
JLS (§8.8.7.1) に記載されているとおり。
はい、任意の数のコンストラクターをクラスに存在させることができ、[コンストラクター呼び出しとキーワードをthis()
混同しないでください]を使用して別のコンストラクターから呼び出すことができます。または、コンストラクターの最初の行にする必要があります。this()
this
this()
this(args)
例:
Class Test {
Test() {
this(10); // calls the constructor with integer args, Test(int a)
}
Test(int a) {
this(10.5); // call the constructor with double arg, Test(double a)
}
Test(double a) {
System.out.println("I am a double arg constructor");
}
}
これは、コンストラクターのオーバーロードとして知られています。
コンストラクターの場合、オーバーロードの概念のみが適用され、継承やオーバーライドは適用されないことに注意してください。
「this」キーワードを使用して、同じクラスの別のコンストラクターからコンストラクターを作成できます。例 -
class This1
{
This1()
{
this("Hello");
System.out.println("Default constructor..");
}
This1(int a)
{
this();
System.out.println("int as arg constructor..");
}
This1(String s)
{
System.out.println("string as arg constructor..");
}
public static void main(String args[])
{
new This1(100);
}
}
出力 - arg コンストラクターとしての文字列.. デフォルトのコンストラクター.. arg コンストラクターとしての int..
はい、あるコンストラクターを別のコンストラクターから呼び出すことができますthis()
class Example{
private int a = 1;
Example(){
this(5); //here another constructor called based on constructor argument
System.out.println("number a is "+a);
}
Example(int b){
System.out.println("number b is "+b);
}
thisキーワードは、コンストラクターからコンストラクターを呼び出すために使用できます。クラスの複数のコンストラクターを記述する場合、コードの重複を避けるために、あるコンストラクターを別のコンストラクターから呼び出したい場合があります。
ベローは、コンストラクターと getters() および setters() に関する他のトピックを説明するリンクであり、2 つのコンストラクターを持つクラスを使用しました。説明と例が役立つことを願っています。
私はこの方法を好みます:
class User {
private long id;
private String username;
private int imageRes;
public User() {
init(defaultID,defaultUsername,defaultRes);
}
public User(String username) {
init(defaultID,username, defaultRes());
}
public User(String username, int imageRes) {
init(defaultID,username, imageRes);
}
public User(long id, String username, int imageRes) {
init(id,username, imageRes);
}
private void init(long id, String username, int imageRes) {
this.id=id;
this.username = username;
this.imageRes = imageRes;
}
}