1

コンストラクターのオーバーロードを行っているときに、「一貫したコンストラクター」と呼ばれるものに出くわしました。コンストラクターのオーバーロードとは何かを理解しています。

Class Person
{
  String Name;
  String City;

  Person(String N,String C)
  {
    Name=N;
    City=C;
  }

  Person(String N)
  {
    this(N,NULL);
  }
}

Class NewClass
{
  public static void main(String[] args)
  {
    Person obj1=new Person("carl","max");
    Person obj2=new Person("Tommy");
  }
}

私によれば、一貫したコンストラクターとは何ですか::thisインスタンス変数を初期化するためのコンストラクターの1つで示したように、その使用....私の例では、常に2つの引数を持つコンストラクターが呼び出されます!


  1. Javaの一貫したコンストラクタとは何ですか?

  2. これらの実用的なアプリケーションは何ですか?

  3. なぜJavaで使用されるのですか?

  4. このトピックを理解するための情報はありますか?

誰かが私のような初心者のために、このトピックについて素人の言葉でより多くの説明と、このトピックについて学ぶためのより多くの情報を提供できますか?

4

3 に答える 3

2

「一貫したコンストラクター」と呼ばれることは聞いたことがありません。「連鎖コンストラクター呼び出し」と呼ばれていると聞いたことがあると思います。あるコンストラクターのキーワードを使用しthisて別のコンストラクターを呼び出す場合です。

これらの実用的なアプリケーションは何ですか?

コードの重複が減るため、保守性が向上します。「Name=N」コードが各コンストラクターで複製されていると想像してください。

Person(String N,String C)
{
  Name=N;
  City=C;
}

Person(String N)
{
  Name=N;
  City=null;
}

次に、名前を検証したいとします。

Person(String N,String C)
{
  if (N == null || N.length() == 0) throw new IllegalArgumentException();
  Name=N;
  City=C;
}

Person(String N)
{
  Name=N;
  City=null;
}

1 つのコンストラクターを変更しましたが、もう 1 つのコンストラクターを忘れたので、名前の制限を回避できます。クラスが非常に複雑な場合、これは実際のリスクです。

this(N,null);あるコンストラクターを別のコンストラクターから呼び出すようにすることで、コンストラクターのメイン ロジックを 1 か所で維持できるので、これは良いことです

なぜJavaで使用されるのですか?

Java は、他の一部の言語とは異なり、オプションの引数をサポートしていません。一部の言語では、次のようにコンストラクターを記述できます。

Person(String N, String C=null) {
  Name=N;
  City=C;
}

その場合、コンストラクターは 1 つしかなく、1 つまたは 2 つの引数で呼び出すことができ、都市が指定されていない場合はデフォルトで null になります。これは有効な Java ではありませんが、オーバーロードで偽造することは可能です。

于 2013-11-30T15:26:07.807 に答える
2

よく使うテクニックですが、名前がわかりません。オーバーロードされたメソッドにも適用できます。主な利点は、複数の入力ケースに対して単一のロジックがあり、デフォルトを提供してその使用を簡素化することです。つまり、次のような完全な署名を持つメソッドがあります。

foo(a, b, c, d) {...}

そしてかなり長いです。これはコードのにおいかもしれません。つまり、これらのパラメーターを 1 つまたは 2 つのパラメーター オブジェクトまたはインスタンス状態に結合する方がよい場合があります。とにかく、この署名を持つ理由があるかもしれないので、このメソッドの使用を簡単にするために、デフォルトでそれを呼び出す署名を提供することができます:

foo(a, b){
    return foo(a, b, defaultC, defaultD);
}

リバースケース

foo(a)パラメータ化したいメソッドがあります:

foo(name){
    System.out.println("Hello, " + name);
}

"Hello, "また、単一のケースに対してのみパラメーターとして渡す必要があります。これが実際のプロジェクトであり、foo他の 100 の場所で使用されている場合、次のようにすることができます。

foo(a){
    foo("Hello", a);
}

foo(greeting, name){
    System.out.println(greeting +", " + name);
}

一部の IDE はこれをリファクタリングとしてサポートしているため、非常に便利な手法です。

于 2013-11-30T15:28:41.703 に答える
2

一貫したコンストラクターについて聞いたことはありませんが、異なるコンストラクターによって初期化されるパラメーターに関するものだと思います。一貫性のないコンストラクターがどのように見えるかを見てみましょう。

class Person {
    String firstName;
    String lastName;
    Integer age;

    Person(String firstName, String lastName, Integer age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    Person(String firstName, String lastName) {
        this(firstName, lastName, 0);
    }

    Person(String firstName) {
        this(firstName, null, null);
    }
}

Person p1 = new Person("Joe", "Doe", 24);
Person p2 = new Person("Joe", "Doe");
Person p3 = new Person("Joe");

矛盾はどこにありますか?個人番号 #2 と #3 ( p2, p3) の年齢は未定義であると予想されます。つまり、その値は-10またはになりnullます。を使用している限り、どちらを使用しても問題ありませんPerson(String, String)Person(Stringまったく同じ、一貫した値が得られます。

この例では、2 番目のコンストラクターは に初期化ageされます0が、3 番目のコンストラクターはこのプロパティをnull- に初期化します。これはかなり矛盾しているようです。

于 2013-11-30T15:36:53.273 に答える