2

調査を行ったところ、次のことがわかりました。

次のコンストラクターを持つ、以下のようなクラスがあるとします。

public class Triangle implements Shape {

    public String  type;
    public String height;

    public Triangle(String type) {
        super();
        this.type = type;
    }

    public Triangle(String height) {
        super();
        this.height = height;
    }

    public Triangle(String type, String height) {
        super();
        this.type = type;
        this.height = height;
    }
}

これにより、コンパイル時エラーが発生します。しかし、heightからに変更するStringと、intすべて正常に動作します。以下は、変更されたコード部分です。

public class Triangle implements Shape {

    public String  type;
    public int height;

    public Triangle(String type) {
        super();
        this.type = type;
    }

    public Triangle(int height) {
        super();
        this.height = height;
    }

    public Triangle(String type, int height) {
        super();
        this.type = type;
        this.height = height;
    }
}

ここでの質問は次のとおりです。最初のケースのようにしたいStringとします。heightなぜ失敗したのですか?説明してください。

4

5 に答える 5

9

同じ署名を持つコンストラクターをオーバーロードすることはできません

なんで?

メソッド/コンストラクターを解決して JVM を呼び出すには、メソッドを一意に識別するものが必要ですが (戻り値の型では不十分です)、コンストラクター/メソッドへのパラメーターは同じであってはなりません


見る

于 2012-07-02T14:13:23.767 に答える
9

同じ引数を持つ 2 つのコンストラクターがあります。どちらも 1 つの文字列を引数として取ります。

「何とかTriangle tri = new Triangle("blah");」が高さなのかタイプなのかを判断する方法はありません。それを見ればわかるかもしれませんが、JVM ではわかりません。各コンストラクターには、一意の引数が必要です。

于 2012-07-02T14:16:06.917 に答える
1

または、クラスに静的ファクトリを追加できます

public class Triangle implements Shape {

...

private Triangle(int height) {
  // initialize here
}

private Triangle(String type) {
  // initialize here
}

private Triangle(String type, int height) {
  // initialize here
}

public static createByHeight(String height) {
  return Triangle(Integer.parseInt(height);
}

public static createByType(String type) {
  return Triangle(type);
}

public static createByTypeAndHeight(String type, String height) {
  return Triangle(type, Integer.parseInt(height);
}

}

于 2012-07-02T15:24:14.250 に答える
1

最初のケースでコンパイル エラーが発生する理由は、文字列パラメーターを渡してクラス Triangle のオブジェクトを初期化するときに、コンパイラーがどのコンストラクターを呼び出すかをどのように認識するかということです。タイプを初期化するものまたは高さを初期化するもの。これはコンパイラにとってあいまいなコードであるため、エラーがスローされます。 私が言うように;

Triangle t = new Triangle("xyz");

どの変数が初期化されるかは誰にもわかりません。タイプまたは高さ。

于 2012-07-02T14:22:34.167 に答える
0

コンストラクターに 2 つの文字列を使用する場合は、文字列を Value オブジェクトに変換できます。

http://c2.com/cgi/wiki?ValueObject

例えば:

class Height {
   private String height;

   public Height(String height){
       this.height = height;
   }

   public String value(){
       return this.height;
   } 

   @Override
   public String toString(){
      return height;
   }

   @Override
   public boolean equals(Object other){
        return this.height.equals((Height)other).value()); // Let your IDE create this method, this is just an example
       // For example I have missed any null checks
   }
}

次に、Type に対して同じことを行うと、2 つのコンストラクターを持つことができます。

public Triangle(Type type) {
    this.type = type;
}

public Triangle(Height height) {
    this.height = height;
}

また、 Type は列挙型のように聞こえます

于 2012-07-02T15:01:25.303 に答える