3

継承に関する質問です。

1 つのスーパークラスと 2 つのサブクラスがあります。

問題: フィールドageとメソッドgetAge()に継承を使用できますか? 私を混乱させるのは、Dog クラスのフィールド年齢が固定(15) であり、パラメーターではないことです。メソッド getAge() をスーパークラスに移動したいのですが、犬の年齢の固定値が私を混乱させます。1 つの (サブ) クラスのフィールドが値に固定されていて、それが他のクラスにない場合の対処方法。まだ継承を使用できますか?これを解決するには?

//Super class:
    public class Animal
    {
       private String name;

       public Animal(String nam)
       {
          name = nam;
       }

       public void displayName("This animal is: " + name);
    }

//Subclass 1:
public class Cat extends Animal
{
private int age;

       public Cat(String nam, int a)
       {
          super(nam);
          age = a;
       }

       public int getAge()
       {
           return age;
       }
}

//Subclass 2:
public class Dog extends Animal
{
private int age;

       public Dog(String nam)
       {
          super(nam)
          age = 15;
       }

       public int getAge()
       {
           return age;
       }
}

マット

4

3 に答える 3

2

どうですか:

public abstract class Animal
{
   private String name;
   private int age;

   public Animal(String nam)
   {
      name = nam;
   }

   public void displayName() 
   {
      System.out.println("This animal is: " + name);
   }

   public abstract int getAgeInAnimalYears();
}

public class Cat extends Animal
{
       private int age;

       public Cat(String nam, int a)
       {
          super(nam);
          age = a;
       }

       @Override
       public int getAgeInAnimalYears()
       {
           return age * 9;
       }
}

public class Dog extends Animal
{
       private int age;

       public Dog(String nam)
       {
          super(nam)
          age = 15;
       }

       @Override
       public int getAgeInAnimalYears()
       {
           return age * 7;
       }
}

これAnimal. Animalこれは、オブジェクトをインスタンス化できなくなったことを意味することに注意してください。それらはCats またはDogs または の他のサブクラスでなければなりませんAnimal。これは合理的な設計上の選択だと思いますが、何らかの理由で純粋なAnimals をインスタンス化する必要がある場合は、それらを通常のクラスのままにして、代わりに例外をスローできます。

public class Animal
{
   private String name;
   private int age;

   public Animal(String nam)
   {
      name = nam;
   }

   public void displayName() 
   {
       System.out.println("This animal is: " + name); 
   }

   public int getAgeInAnimalYears() {
      throw new UnsupportedOperationException();
   }
}

それの何がすごいの?

コードの再利用に関するあなたの質問に答えるには:displayName()一度だけ実装することで、すでにスペースを節約しています。コード。ただし、はるかに魅力的なのは、継承によって実行できる次の機能です。

public class Zoo
{
    private ArrayList<Animal> list = new ArrayList<Animal>();

    public void addAnimal(Animal a)
    {
        list.add(a);
    }

    public void everyoneSayHello()
    {
        for (Animal a : list) {
            a.displayName();
            System.out.println("It is " + a.getAgeInAnimalYears() + \
                               " animal-years old!")
        }
    }
 }

Dogs、Cats などをリストに追加できるようになりました。 を呼び出すとeveryoneSayHello()Polymorphismが自動的にその権利getAgeInAnimalYears()を呼び出します。継承がなければ、これは拡張が難しい大きなif/ブロックでのみ機能します。case継承を使用すると、 を拡張する別のクラスを追加するだけで、Animal他のコードを変更する必要はありません!

于 2013-01-02T03:44:21.287 に答える
0

あなたが聞きたい質問を私が理解したら..あなたがしたいことはAnimal次のように変更することです

public class Animal
{
    ....
    protected int age;
    public int getAge()
    {
        return age;
    }
}

ageそして、サブクラスの定義とサブクラスから定義を削除します-getAgeこれは、すべての動物には年齢があると想定している(そしてあなたもそうしたいと思う)ためですが、あなたの場合のように、動物ごとに異なる方法で管理される可能性があります。

コードの残りの部分は変更する必要はありません(サブクラスで設定できるように age を保護しました) setAge。例えば犬の場合は15)

于 2013-01-02T03:41:25.913 に答える
0

どちらの場合も、年齢を変更する API メソッドを公開しません。フィールドとゲッターの両方をスーパークラスに移動できます。年齢は変更されないため、期待どおりに機能します。

セッター (または年齢を変更する任意のメソッド) をスーパークラスに追加する場合は、Dog クラスでそのメソッドをオーバーライドし、適切なアクション (何もしない、UnsupportedOperationException をスローするなど) を実行するだけで済みます。

于 2013-01-02T03:42:17.903 に答える