// Here we define all the attributes and operations that every animal will // have. Other specialized classes for different types of animals will // build on this basic definition. // The classifier "protected" means that these attributes can be accessed // in this file, and in subclasses, but nowhere else. // // By the way, I've included print statements in the constructors just so // we can see what's going on. In the long run, we usually wouldn't do this. public class Animal { protected double weight; protected boolean isWarmBlooded; protected boolean isHungry; public Animal() { weight = 10; isWarmBlooded = false; isHungry = true; System.out.println("Just created an animal."); } public String toString() { return "animal"; } // An animal should only exercise if it's had enough to eat (if not hungry). // We also have special cases for fish and birds. // Here in the Animal class we can look down and see if an Animal object is // a Fish or a Bird, but we can't call any specific Fish or Bird function. // without using a cast. Another alternative is to write separate // exercise() versions in Bird and the other subclasses as desired. public void exercise() { if (isHungry) System.out.println("Too hungry to exercise, sorry."); else { if (this instanceof Fish) System.out.println(this + " swims about!"); else if (this instanceof Bird && ((Bird)this).canFly()) System.out.println("watch " + this + " fly!"); else System.out.println(this + " gets a workout!"); isHungry = true; } } // Only feed the animals if they are really hungry. public void feed() { if (! isHungry) System.out.println(this + " isn't hungry at the moment. Try later."); else { System.out.println(this + " is grateful for the grub!"); weight += 0.1; isHungry = false; } } public double getWeight() { return weight; } }