1

これに対する答えを探してみましたが、正確な答えを見つけることができませんでした... これが状況です。クラスとサブクラスがあり、次のように定義しました。

public class Shape{
   public methodA{
     System.out.println("Hello!");
  }
}

public class Square extends Shape{
   public methodB{
     System.out.println("I'm a Square!);
  }
}

主に、私はこのようにそれらをインスタンス化しますが、今はメソッド B を呼び出すことができません。

Shape square = new Square();
square.methodB() // This doesn't work.

子クラスのメソッドも呼び出せるようにしたい場合、これをすべて間違って設計したのでしょうか? Shape クラスから継承する多くの形状があるため、このようにしていますが、すべての形状クラスをプロジェクトにインポートしたくありませんでした。調べてみましたが、納得のいく答えが見つかりませんでした。ありがとう。

-RB

4

4 に答える 4

4

methodB()クラスである親クラスで定義されていないため、機能しませんShape。これを修正するには、Shapeクラス (または、より一般的には のサブクラスShape) でメソッドを作成する必要があります。その後、クラスでそのメソッドをオーバーライドして、Squareその動作を変更できます。したがって、次のように変更できます。

public class Shape{

    public void methodA(){
        System.out.println("Hello");
    }

    public void methodB(){
        System.out.println("I'm a shape");
    }
}

public class Square extends Shape{

    public void methodB(){
        System.out.println("I'm a square");
    }
}

実行してShape shape = new Square();を呼び出すshape.methodB();と、「I'm a square」と出力されます。

于 2013-09-03T23:16:10.820 に答える
1

あなたが望むものを決める必要があります。

ポリモーフィズムのポイントは、共通のもの (インターフェースまたは基本クラスまたは抽象クラス) にプログラミングすることにより、実装に固有の詳細を抽象化できることです。

子クラスのメソッドも呼び出せるようにしたい場合、これをすべて間違って設計しただけですか

あなたの意図はわかりませんが、おそらくそうではありません。この特定のケースで子クラスのメソッドを呼び出せるようにしたい場合は、参照型を変更するだけです

Square square = new Square();
square.methodB() // This doesn't work.

一般に、どこからでも任意の形状で methodB を呼び出せるようにしたい場合は、Square ではなく Shape 自体で methodB を定義する必要があります。

public class Shape{
   public void methodA{
     System.out.println("Hello!");
  }

  public abstract void methodB();
}

public class Square extends Shape{
   public void methodB{
     System.out.println("I'm a Square!);
  }
}

これで、すべての形状が methodB メソッドを持つことが保証されます。

覚えておくべき重要な点は、オブジェクトをインスタンス化するとき、継承されるのは参照型だけだということです。を呼び出すときShape s = new Square()、コンパイラはそのコンストラクタに Square のみを使用します。一度呼び出されると、あなたがそう言ったので、それが正方形であるという知識を忘れます。したがって、s.methodB()コンパイラは s が正方形、円、三角形などであるかどうかを知らないため、コンパイルされません。忘れるように指示しました。

正方形でのみ使用できる正方形に関する何かがある場合、呼び出しコードは Shape ではなく Square クラスを使用する必要があります。

于 2013-09-03T23:31:59.450 に答える
0

あなたのデザインは間違っています。コードのどこかで (methodB() を実装していない) 他の子クラス オブジェクトを Shape クラス変数に割り当ててから methodB() を呼び出した場合、Java はその時点で何をすべきでしょうか?

このことを考慮:

class Animal { public void move() {} };
class Human extends Animal { public void talk() {} };
class Dog extends Animal { public void wagTail() {} };

void processAnimal(Animal a) {
  a.move(); // Valid: All animals can walk
  a.talk(); // INVALID: All animals are not known to be able to talk
  a.wagTail(); // INVALID: All animals are not known to be able to wag tail
}

void processHuman(Human m) {
  m.move(); // Valid: All animals can walk and Man is an animal
  m.talk(); // Valid: All humans can talk
  m.wagTail(); // INVALID: Humans can NOT wag tail
}

void processDog(Dog g) {
  g.move(); // Valid: All animals can walk and dogs are animals
  g.talk(); // INVALID: Dogs can NOT talk
  g.wagTail(); // Valid: All dogs can wag tail
}

// These are good. ProcessAnimal() expects an animal and all 3 arguments below are animals
processAnimal(new Animal());
processAnimal(new Human());
processAnimal(new Dog());

processHuman(new Animal()); // INVALID: Expecting a specialized Animal, namely Human, which can talk
processHuman(new Human()); // Valid
processHuman(new Dog()); // INVALID: Expecting Human, which can talk

processDog(new Animal()); // INVALID: Expecting a specialized Animal, namely Dog, which can bark
processDog(new Human()); // INVALID: Expecting Dog, which can bark
processDog(new Dog()); // Valid

あなたのための修正:

if (square instanceof Square) {
    Square identifiedSquare = (Square) square;
    identifiedSquare.methodB();
}

Square クラスを Java ファイルにインポートすることは避けられません

于 2013-09-03T23:45:51.093 に答える