3

继承问题。

我有 1 个超类和 2 个子类。

问题:我可以对字段age和方法getAge()使用继承吗?让我感到困惑的是 Dog 类中的字段年龄是固定的(15)而不是参数。我想将方法​​ getAge() 移动到超类,但是 Dog 的年龄的固定值让我感到困惑。当一个(子)类中的字段固定为一个值而它不在另一个类中时该怎么办。你还能使用继承吗?如何解决这个问题?

//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;
       }
}

这使用一个抽象类 ( http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html ) 用于Animal. 请注意,这意味着您不能再实例化Animal对象,它们必须是Cats 或Dogs 或Animal. 我认为这是一个合理的设计选择,但是如果由于某种原因需要实例化 pure 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()多态会自动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这是因为我假设(并且我认为您也想这样做)所有动物都有年龄,但是对于不同的动物,它们可能会受到不同的管理,就像您的情况一样。

您的其余代码无需更改(我已设置年龄保护,以便可以在子类中设置它),但不是您这样做的方式,而是使用设置器setAge并根据需要自定义(忽略年龄并设置15 以狗为例)

于 2013-01-02T03:41:25.913 回答
0

在任何一种情况下,您都不会公开 API 方法来改变年龄。您可以将字段和 getter 都移到超类中,并且由于年龄永远不会修改,因此它将按您的预期工作。

如果您要向超类添加一个 setter(或任何修改年龄的方法),您需要做的就是在 Dog 类中覆盖该方法并采取适当的操作(例如,什么都不做,抛出 UnsupportedOperationException 等)。

于 2013-01-02T03:42:17.903 回答