java - 継承 - 暗黙的スーパー コンストラクター object() は未定義です。別のコンストラクターを明示的に呼び出す必要があります




Javaで別のコンストラクタを呼び出すにはどうすればよいですか? (12)

"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

別のクラスからコンストラクタを呼び出すことは可能ですか(サブクラスではなく同じクラス内で)? はいの場合はどうですか? そして、別のコンストラクタを呼び出す最良の方法は何か(もしそれがいくつかの方法があれば)?


[ 注:私は他の答えには見られなかった1つのアスペクトを追加したいだけです:これは最初の行になければならないという要件の限界を克服する方法です。 ]

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;

  }

}

this(args)を使う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 super(someValue)使用します。 superへの呼び出しは、コンストラクターの最初の呼び出しでなければなりません。そうしないと、コンパイラー・エラーが発生します。


thisキーワードは、コンストラクタからコンストラクタを呼び出すために使用できます。クラスのコンストラクタをいくつか記述すると、重複したコードを避けるために別のコンストラクタから1つのコンストラクタを呼び出すことができます。

Bellowは、コンストラクタとgetters()とsetters()について他のトピックを説明するリンクで、2つのコンストラクタを持つクラスを使用しました。 説明と例があなたに役立つことを願っています。

セッターメソッドまたはコンストラクター


これは、テクスコーピングコンストラクタのアンチパターンまたはコンストラクタチェーンと呼ばれます。 はい、間違いなく可能です。 私は上記の多くの例を見ています。あなたは2つまたは3つのコンストラクタだけが必要であることを知っているなら、大丈夫かもしれません。 しかし、もっと必要な場合は、Builderパターンのような異なるデザインパターンを使用してみてください。 例えば:

 public Omar(){};
 public Omar(a){};
 public Omar(a,b){};
 public Omar(a,b,c){};
 public Omar(a,b,c,d){};
 ...

もっと必要な場合があります。 この場合、ビルダーパターンは素晴らしい解決策になります。 ここに記事がありますので参考にしてhttps://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e


はい、 this()を使用して別のコンストラクタから1つのコンストラクタを呼び出すことは可能です

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() 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");
    }
}

これは、コンストラクタのオーバーロードとして知られています。
コンストラクタでは、継承またはオーバーライドではなく、オーバーロードの概念のみが適用可能であることに注意してください。


はい、可能です:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}

同じクラスのものではなく、特定のスーパークラスのコンストラクタに連結するには、 this代わりにsuperを使用します。 1つのコンストラクターにのみ連結でき 、コンストラクター本体の最初のステートメントで なければならないことに注意してください

C# に関するこの同じ質問を参照してください。ただし、同じ原則が適用されます。


コンストラクタ内でthisキーワードを使用すると、同じクラスの別のコンストラクタを呼び出すことができます。 そうすることは、 明示的なコンストラクタ呼び出しと呼ばれます

ここに、別のRectangleクラスがあります。これは、オブジェクトセクションのものとは異なる実装です。

public class Rectangle {
    private int x, y;
    private int width, height;

    public Rectangle() {
        this(1, 1);
    }
    public Rectangle(int width, int height) {
        this( 0,0,width, height);
    }
    public Rectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

}

このクラスには、一連のコンストラクタが含まれます。 各コンストラクタは、矩形のメンバ変数の一部またはすべてを初期化します。


別のコンストラクタからコンストラクタを呼び出す

class MyConstructorDemo extends ConstructorDemo
{
    MyConstructorDemo()
    {
        this("calling another constructor");
    }
    MyConstructorDemo(String arg)
    {
        System.out.print("This is passed String by another constructor :"+arg);
    }
}

また、 super()コンストラクターをsuper()呼び出しを使用して呼び出すこともできます


私はこの質問の例が非常に多いことを知っていますが、私が私のアイデアを分かち合うためにここに置いていることがわかりました。 コンストラクタをチェーンするには2つの方法があります。 Sameクラスでは、このキーワードを使用できます。 継承では、superキーワードを使用する必要があります。

    import java.util.*;
    import java.lang.*;

    class Test
    {  
        public static void main(String args[])
        {
            Dog d = new Dog(); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
            Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.

            // You need to Explicitly tell the java compiler to use Argument constructor so you need to use "super" key word
            System.out.println("------------------------------");
            Cat c = new Cat();
            Cat caty = new Cat("10");

            System.out.println("------------------------------");
            // Self s = new Self();
            Self ss = new Self("self");
        }
    }

    class Animal
    {
        String i;

        public Animal()
        {
            i = "10";
            System.out.println("Animal Constructor :" +i);
        }
        public Animal(String h)
        {
            i = "20";
            System.out.println("Animal Constructor Habit :"+ i);
        }
    }

    class Dog extends Animal
    {
        public Dog()
        {
            System.out.println("Dog Constructor");
        }
        public Dog(String h)
        {
            System.out.println("Dog Constructor with habit");
        }
    }

    class Cat extends Animal
    {
        public Cat()
        {
            System.out.println("Cat Constructor");
        }
        public Cat(String i)
        {
            super(i); // Calling Super Class Paremetrize Constructor.
            System.out.println("Cat Constructor with habit");
        }
    }

    class Self
    {
        public Self()
        {
            System.out.println("Self Constructor");
        }
        public Self(String h)
        {
            this(); // Explicitly calling 0 args constructor. 
            System.out.println("Slef Constructor with value");
        }
    }

複雑な構造の必要性をカバーするデザインパターンがあります。簡潔に行うことができない場合は、ファクトリメソッドまたはファクトリクラスを作成します。

最新のJavaとlambdaの追加により、任意の初期化コードを受け入れるコンストラクタを作成するのは簡単です。

class LambdaInitedClass {

   public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
       init.accept(this);
   }
}

それと呼んで...

 new LambdaInitedClass(l -> { // init l any way you want });






constructor