Hierarchy of Java Classes - java

I created a model of the zoo. In my zoo I only have birds. In my main class, Zoopark, I put an animal in a cage. Currently, an unlimited number of birds can be added to the cage. But there should not be more than two birds in each cage. How do I make this revision?
Main class
public class Zoopark {
public static void main(String[] args) {
Bassein V1 = new Bassein();
Bird B = new Bird("Vala", 100, true);
V1.putAnimal(B);
Bird C = new Bird("Lilu", 100, true);
V1.putAnimal(C);
Bird D = new Bird("Abara", 100, true);
V1.putAnimal(D);
OpenCage V2 = new OpenCage();
Hippo E = new Hippo("Kala", 1000, true);
V2.putAnimal(E);
Hippo I = new Hippo("Nala", 1000, true);
V2.putAnimal(I);
Hippo F = new Hippo("Mala", 1000, true);
V2.putAnimal(F);
Hippo U = new Hippo("Ala", 1000, true);
V2.putAnimal(U);
}
}
Class with cages
import java.util.ArrayList;
import java.util.List;
public class Valers {
private final static int CageLimit=2;
List<Animals> result = new ArrayList<Animals>();
public void putAnimal(Animals a) {
int numAnimals=result.size();
if (numAnimals>=CageLimit) {
System.out.println("This cage is full!");
System.out.println(" ");
}
else {
this.result.add(a);
System.out.println("Animal added in cage");
System.out.println(" ");
}
}
public int getCageAnimals() {
return result.size();
}
}
Bassein cage class:
public class Bassein extends Valers {
}
OpenCage cage class:
public class OpenCage extends Valers {
}
Abstract class Animal:
abstract public class Animals {
private String name;
private int weight;
// is this boy?
private boolean isMale;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return weight;
}
public void setAge(int age) {
this.weight = weight;
}
public boolean isMale() {
return isMale;
}
public void setMale(boolean isMale) {
this.isMale = isMale;
}
public Animals(String name, int weight, boolean isMale) {
this.name = name;
this.weight = weight;
this.isMale = isMale;
}
}
Class bird:
public class Bird extends Animals {
public Bird(String name, int weight, boolean isMale) {
super(name, weight, isMale);
System.out.println(name + " " + weight + " " + isMale);
}
}
Class with hippos:
public class Hippo extends Animals {
public Hippo(String name, int weight, boolean isMale) {
super(name, weight, isMale);
System.out.println(name + " " + weight + " " + isMale);
}
}
Now this output:
Vala 100 true
Animal added in cage
Lilu 100 true
Animal added in cage
Abara 100 true
This cage is full!
Kala 1000 true
Animal added in cage
Nala 1000 true
Animal added in cage
Mala 1000 true
This cage is full!
Ala 1000 true
This cage is full!
And should be:
Vala 100 true
Animal added in cage
Lilu 100 true
Animal added in cage
Abara 100 true
This cage is full
Kala 1000 true
Animal added in cage
Nala 1000 true
Animal added in cage
Mala 1000 true
Animal added in cage
Ala 1000 true
Animal added in cage
Thank you!

Add this before adding the animal in Valers.putAnimal():
if (result.size() >= 2) {
System.out.println("This cage is full!");
return;
}

While #LW001's answer would give the proper print output, I believe that, logically, you would still have a third animal added to the cage. What may be better is for you to add a method to check the cage for # of animals. Then add an if statement to only add an animal if there's less than two animals. For instance:
import java.util.ArrayList;
import java.util.List;
public class Valers {
private final static int CageLimit=2;
List<Animals> result = new ArrayList<Animals>();
public void putAnimal(Animals a) {
int numAnimals=result.size();
if (numAnimals>=CageLimit) {
System.out.println("This cage is full!");
System.out.println(" ");
}
else {
this.result.add(a);
System.out.println("Animal added in cage");
System.out.println(" ");
}
}
public integer getCageAnimals() {
return result.size();
}
}
Notice that I included a private final static intfor CageLimit. This is because good practice dictates not to include 'magic numbers' in the logic of your code. So initialize it at the start as an immutable value.

Related

How to create a working super class with a sub class using private members Java

I am doing a coding boot camp and created a Superclass "Animal" with a subclass "Lion". All the variables are private variables.
When I try and pass in the values required I get an error saying Lion cannot be resolved to a type. This is my first question ever asked on StackOverflow, so sorry if the normal convention isn't followed right.
///Animal class with subclass lion///
public class Animal {
private int numTeeth;
private boolean spots;
private int weight;
public Animal(int numTeeth, boolean spots, int weight) {
this.setNumTeeth(numTeeth);
this.setSpots(spots);
this.setWeight(weight);
}
int getNumTeeth() {
return numTeeth;
}
boolean getSpots() {
return spots;
}
int getWeight() {
return weight;
}
public void setNumTeeth(int numTeeth) {
this.numTeeth = numTeeth;
}
public void setSpots(boolean spots) {
this.spots = spots;
}
public void setWeight(int weight) {
this.weight = weight;
}
class Lion extends Animal {
private boolean maine;
private String region;
private int type;
public Lion(boolean maine, String region, int type) {
super(numTeeth, spots, weight);
this.setMaine(maine);
this.setRegion(region);
this.setType(type);
}
boolean getMaine() {
return maine;
}
String getRegion() {
return region;
}
int getType() {
return type;
}
public void setMaine(boolean maine) {
this.maine = maine;
}
public void setRegion(String region) {
this.region = region;
}
public void setType(int type) {
this.type = type;
}
void showAnimal() {
System.out.println("The number of teeth is: " + getNumTeeth());
System.out.println("Does the animal have spots!: " + getSpots());
System.out.println("The animals weight!: " + getWeight());
System.out.println("Do the animal have a maine!: " + getMaine());
System.out.println("The animal is from: " + getRegion());
System.out.println("The animal is a: " + getType());
}
}
}
///Animal stats I am trying to pass in "AnimalDetails" which is a new class file///
public class AnimalStats {
public static void main(String[] args) {
Lion stats = new Lion();
stats.setMaine(true);
stats.setNumTeeth(20);
stats.setRegion("South Africa");
stats.setSpots(false);
stats.setType(2);
stats.setWeight(150);
}
}
The error I find is in / Lion stats = new Lion(); / Lion cannot be reloved to a type
Lion is not declared static
In order to construct Lion in the way you are, Lion should be a static inner class.
The declared constructor in Lion does not include params for super
Add params for the call to super, or provide default values inside the constructor implementation for numTeeth, spots, and weight when you call super.
Lion does not have a zero-argument constructor
Your code is trying to instantiate a Lion with no arguments. If you want a zero-argument constructor, add one and set defaults for all of the members.
Otherwise, call the constructor you've already defined.
Something like:
public class Animal {
private int numTeeth;
private boolean spots;
private int weight;
public Animal(int numTeeth, boolean spots, int weight) {
this.setNumTeeth(numTeeth);
this.setSpots(spots);
this.setWeight(weight);
}
int getNumTeeth() {
return numTeeth;
}
boolean getSpots() {
return spots;
}
int getWeight() {
return weight;
}
public void setNumTeeth(int numTeeth) {
this.numTeeth = numTeeth;
}
public void setSpots(boolean spots) {
this.spots = spots;
}
public void setWeight(int weight) {
this.weight = weight;
}
static class Lion extends Animal {
private boolean maine;
private String region;
private int type;
public Lion(boolean maine, String region, int type, int numTeeth, boolean spots, int weight) {
super(numTeeth, spots, weight);
this.setMaine(maine);
this.setRegion(region);
this.setType(type);
}
boolean getMaine() {
return maine;
}
String getRegion() {
return region;
}
int getType() {
return type;
}
public void setMaine(boolean maine) {
this.maine = maine;
}
public void setRegion(String region) {
this.region = region;
}
public void setType(int type) {
this.type = type;
}
void showAnimal() {
System.out.println("The number of teeth is: " + getNumTeeth());
System.out.println("Does the animal have spots!: " + getSpots());
System.out.println("The animals weight!: " + getWeight());
System.out.println("Do the animal have a maine!: " + getMaine());
System.out.println("The animal is from: " + getRegion());
System.out.println("The animal is a: " + getType());
}
}
public static void main(String[] args) {
Lion stats = new Lion(true, "South Africa", 2, 20, false, 150);
}
}
This is a case of a nested class with one outer class and one inner class.
You will have to use the Outer class to instantiate the inner class.
Since there is no default constructor available, you will have to put value while instantiating.
Animal.Lion stats = new Animal(20, false, 150).new Lion(true, "South Africa", 2);
AnimalStats class:
public class AnimalStats {
public static void main(String[] args) {
Animal.Lion stats = new Animal(20, false, 150).new Lion(true, "South Africa", 2);
}
}
Note: This solution is with the assumption that class Animal has to be kept as is and only caller code has to be fixed.

JAVA: How can I access to members of each classes?

How can I access to members of each classes?
I have class Dog and Cat. They have different member variable of class.
I try to create one function "CommUtil.display()" to access many classes (Dog or Cat) and display all members of class.
I try to access from mainClass to access Dog or Cat class.
but it can't.
Anyone can help will be appreciated.
I have made an example below:
class Dog {
private String name = null;
private String weight = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
}
class Cat {
private String name = null;
private String age = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
class commUtil {
//TODO: output members of class
public void display (Object obj){
//Question: How to access members of each classes?
//code here...
}
}
class mainClass {
public static void main(String[] args) {
Dog d = new Dog();
commUtil.display(d);
or
Cat c = new Cat();
commUtil.display(c);
}
}
In case 1:
Dog d = new Dog();
d.setName("Lion");
d.setWeight("2Kg");
commUtil.display(d);
It will display Name and Weight of Dog
In case 2:
Cat c = new Cat();
c.setName("MiMi");
c.setAge("1");
commUtil.display(c);
It will display Name and Age of Cat
If the code can still change, you may be able to use java interface. The idea is that both Dog and Cat implements a common interface for output display. In practice though, it will have the same result as modifying toString() like the other comments already covered. Anyway, here is an example:
public interface AnimalInfo {
public String getInfo();
}
and then both Dog and Cat classes can implements this interface.
class Dog implements AnimalInfo {
...
public String getInfo() {
return "name="+name+", weight="+weight;
}
class Cat implements AnimalInfo {
...
public String getInfo() {
return "name="+name+", age="+age;
}
and then inside commUtil the argument can use the interface type AnimalInfo
public void display (AnimalInfo animal){
System.out.println("It will display " +
animal.getInfo() + " of " + animal.getClass().getSimpleName());
}
This is what inheritance is for, so you would make an abstract super class possibly called Animal in this case and then Dog and Cat would extend that class as subclasses. Here is a fairly simple tutorial about inheritance.
public abstract class Animal {
/** Common name property for all animals */
private String name;
/** Common age property for all animals */
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age= age;
}
public int getAge() {
return age;
}
/**
* Abstract method that will need to be implemented
* by a concrete class that inherits from this abstract class
*/
public abstract String getInfo();
public abstract String speak();
public abstract String getType();
}
public class Dog extends Animal {
/*
Any Dog specific properties would also go in here
*/
private boolean isPedigree = false;
/** Class Constructor */
public Dog(String name, int age, boolean isPedigree) {
super(name, age);
this.isPedigree = isPedigree;
}
public boolean isPedigree() {
return isPedigree;
}
#Override
public String getInfo() {
return "I am a Dog named " + name + " and I am " + age + " years old.";
}
#Override
public String speak() {
return "WOOF";
}
#Override
public String getType() {
return Dog.class.getSimpleName();
}
}
public class Cat extends Animal() {
/*
Any Cat specific properties would also go in here
*/
/** Class Constructor */
public Cat(String name, int age) {
super(name, age);
}
#Override
public String getInfo() {
return "I am a " + getType() + named " + name + " and I am " + age + " years old.";
}
#Override
public String speak() {
return "meow";
}
#Override
public String getType() {
return Cat.class.getSimpleName();
}
}
public class MyMainClass {
public static void main(String[] args) {
/*
Just creating a random array to show that
any animal whether Dog or Cat can be placed into
this array as they inherit from Animal
*/
List<Animal> animals = new ArrayList<>();
animals.add(new Dog("James", 5, true));
animals.add(new Cat("Treacle", 2));
for (Animal animal : animals) {
display(animal);
if (animal instanceof Dog) {
boolean isPedigree = ((Dog) animal).isPedigree();
System.out.println("Q: Am I a Pedigree? A: " + String.valueOf(isPedigree));
}
}
}
private void display(Animal animal) {
System.out.println("I'm an animal of type " + animal.getType() + " and I can say " + animal.speak());
System.out.println(animal.getInfo());
}
}
Our output would be:
I'm an animal of type Dog and I can say WOOF
I am a Dog named James and I am 5 years old.
Q: Am I a Pedigree? A: true
I'm an animal of type Cat and I can say meow
I am a Cat named Treacle and I am 2 years old.
This answer shows simple inheritance and polymorphism. This of the backbone of OOP (Object Orientated Programming) and when learning Java will be the essential basics you will need to learn and understand.
In my example getInfo() could actually just be a method in Animal as there is nothing specific it is doing per subclass. You could also move display into the Animal abstract class if you which, I only placed it here for the example.
There is no need for any CommonUtils class or anything like that here, everything you want can be done by simply learning about inheritance.
What we are saying in this example is Cat and Dog are Animals they inherit all the characteristics of any Animal. What you can't do though is create a random Animal object like Animal animal = new Animal("Paul", 4);, the Animal has to be of some sort of type whether that is of type Dog, Cat or some other Subclass of Animal you create (i.e. Bird, Fish or even Human).
You can have the CommonUtil class as shown below. Also, make the display method static as you are trying to access it using class name.
class CommUtil {
//TODO: output members of class
public static void display (Object obj){
//Question: How to access members of each classes?
//code here...
if(obj instanceof Dog) {
System.out.println(((Dog) obj).getName());
System.out.println(((Dog) obj).getWeight());
}
}
}
But as mentioned in the comments you can just override toString() method inside every class and display objects for all those classes.
public String toString() {
return "Cat [name=" + name + ", age=" + age + "]";
}
You can use Java reflection to get all fields from object, below is the example, you can achieve this by T parameter method in utility class
public class ArrayMain {
int x=10; String name="anil";
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
ArrayMain m = new ArrayMain();
m1(m);
SomeOther o = new SomeOther();
m1(o);
}
public int getX() {
return x;
}
public String getName() {
return name;
}
static <T> void m1(T type) throws IllegalArgumentException, IllegalAccessException {
Field[] f=type.getClass().getDeclaredFields();
for(Field f1:f) {
System.out.println(f1.getName());
System.out.println(f1.get(type));
}
}
}
Check if the object is an instance of Cat or Dog using the instanceof operator. Then you must perform a cast to access the object’s getter methods.
if(obj instanceof Cat){
Cat cat = ((Cat) obj);
System.out.println(cat.getName());
}

OOP-Java. Adding Animal objects to an Arraylist in the Class from the main

Adding a second Animal, resets the animals Arraylist to index 0. So it holds the last entered animal. I also putted the UML design below, so it might be more understandable what I'm trying.
public class Cage {
private int placeNr;
private ArrayList<Animal> animals = new ArrayList<Animal>();
public Cage(int place) {
this.placeNr = place;
}
public int getCageNr() {
return this.placeNr;
}
public void putAnimal(Animal animal) throws DuplicateNameException {
if(!duplicatedAnimal(animal.getName())) {
animals.add(animal);
}
}
}
At this point I'm confused. How do I add an Animal class in the an Arraylist located in Cage and stack my Animals in it.
private static void addAnimal() {
Animal newAnimal;
Cage cage;
try {
System.out.println("Name: ");
String name = sc.next();
System.out.println("Type: ");
String type = sc.next();
System.out.println("birthYear: ");
int birthYear = sc.nextInt();
System.out.println("Cage number: ");
int cageNumber = sc.nextInt();
cage = new Cage(cageNumber);
newAnimal = new Animal(name, type, birthYear);
cage.putAnimal(newAnimal);
} catch (DuplicateNameException dne) {
dne.getMessage();
} catch (InputMismatchException ime) {
System.out.println("Wrong input");
}
}
If someone can push me in the right direction it will be awesome thanks!
UML:
enter image description here
Every time you call addAnimal you will create a new Cage object and add the new animal to that cage. To add several animals to the same cage the addAnimal method can not be static and cage needs to be a member of some class (AnimalKeeper?)
Something like this
public class AnimalKeeper {
private Cage cage;
public Cage getCage() {
return cage;
}
public addAnimalToCage(Animal animal) {
//the same method as above minus the user input
//which needs to be done somewhere else
}
}
I tried my best to figure out what you meant exactly, refactor your code to smth like this
class DuplicateNameException extends Exception {
private String message;
public DuplicateNameException(String message){
this.message = message;
}
public String getMessage(){
return this.message;
}
}
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Cage {
private int placeNr;
private ArrayList<Animal> animals = new ArrayList<Animal>();
public Cage(int place) {
this.placeNr = place;
}
public int getCageNr() {
return this.placeNr;
}
public void putAnimal(Animal animal) throws DuplicateNameException {
if(!duplicatedAnimal(animal.getName())) {
animals.add(animal);
} else {
throw new DuplicateNameException(animal.getName());
}
}
private boolean duplicatedAnimal(String name) {
for (Animal animal : animals)
if (animal.getName().equals(name))
return true;
return false;
}
public static void main(String[] args) {
Animal newAnimal;
Cage cage;
try {
cage = new Cage(1);
newAnimal = new Animal("Dog");
cage.putAnimal(newAnimal);
cage.putAnimal(new Animal("not dog"));
cage.putAnimal(new Animal("Dog"));
} catch (DuplicateNameException dne) {
System.out.println(dne.getMessage());
}
}
}
Note: with this code you need to consider cases with animals name written in lower case and upper case (equals will return false in this case) use toLowerCase() or toUpperCase() to normelize the name to common ground
another option you can take is to use HashMap object, this structure type has duplication elimination build in, you will have to override the hashCode() function of Animal so the map will know how to hash each object, like
#Override
public int hashCode() {
return this.name.hashCode()
}

Out put a bit off for method

So this class is inheriting things from other classes which when the client class is used will run all of this.
So far my output is
Your drink choice was: The name of the drink :Black coffeeand its price is: 3.0and the size is :2
When I write in the parameters "Coffee coffee = new Coffee("Black coffee",1,2,"Mocha");" into the client class.
This isn't quite right and I also need to calculate the total but I can't figure out where I need to put that bit of code.
public class Drinks extends CoffeeShop {
private String name; // default name
private double price_per_oz= .10; // default price per oz
private int size = 6;// default value
public Drinks(){
super();
}
public Drinks(String name,double price_per_oz,int size){
this.name = name;
this.price_per_oz = price_per_oz;
this.size = size;
}
public String toString(){
return ("The name of the drink :"+ name +
"and its price is: "+price_per_oz+
"and the size is :"+ size );
}
public double getPrice(){
return price_per_oz*size;
}
//getter setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice_per_oz() {
return price_per_oz;
}
public void setPrice_per_oz(double price_per_oz) {
this.price_per_oz = price_per_oz;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
inherited class:
public class CoffeeShop {
public CoffeeShop(){
}
public static void main (String [] args){
Coffee coffee = new Coffee("Black coffee",1,2,"Mocha");
Tea tea = new Tea ("Hot", 10,12, "Earl Grey");
}
}
coffee class:
public class Coffee extends CaffeinatedDrinks {
private String type="drip"; // default type
public Coffee(){
super();
}
public Coffee(String name,double price_per_oz,int size,String type){
super(name,price_per_oz,size);// inherit these from parent
this.type = type; // make type available to use
System.out.println(" "+"Your drink choice was:"+ " " + this);
}
public double getPrice(){
if(6 == super.getSize()){ // if default size then use default price
return super.getPrice();
}
else if(12 == super.getSize()){ // otherwise charge them more
return super.getPrice()+0.5;
}
else{
//must be the large
return super.getPrice()+1;
}
}
}
Tea class:
public class Tea extends CaffeinatedDrinks {
private String flavor =" English Breakfast"; // default flavor
public Tea(){
super();//inherit parent class
}
public Tea (String name,double price_per_oz,int size,String flavor){
super(name,price_per_oz,size);
this.flavor = flavor;
//define flavor in constructor method
}
public double getPrice(){
if(6 == super.getSize()){
return super.getPrice();
}
else if(12 == super.getSize()){
return super.getPrice();
}
else{
//must be the large
return super.getPrice();
}
}
}
Caffeinated drinks class:
public class CaffeinatedDrinks extends Drinks {
public CaffeinatedDrinks(){
super();// inherit parent class Drinks
}
public CaffeinatedDrinks(String name,double price_per_oz,int size){
super(name,price_per_oz*3,size);// take the price per oz from parent function and multiply it by 3
}
}
public class NonCaffeinatedDrinks extends Drinks {
public NonCaffeinatedDrinks(){
super();// inherit parent class drinks
}
public NonCaffeinatedDrinks(String name,double price_per_oz,int size){
super(name,price_per_oz*2,size);// take the price per oz from parent function and multiply it by 2
}
}
expected out put is something like this:
Your drink order consists of:
water, size small, cost :$0.60
coffee, type mocha, size medium, cost: $2.30
tea, flavor earl grey size large, cost: $1.20
The total cost of your order is: $4.10

Getting instance variable from one class using a method in another class?

How would I get the instance variable hitpoints from the Dog class and pass them to the Lion Class through the method eat(X x)?
I'm trying to get the Lion to eat() the Dog and minus points from the instance variable which is stored in a new variable in the Lion Class.
Class Lion
package helloworld;
public class Lion {
public String name;
public int heightCMeters;
public int lengthCMeters;
public float weightKilos;
public int hitPoints;
public Lion(int hitPoints, String name, int heightCMeters, int lengthCMeters, float weightKilos) {
this.name = name;
this.heightCMeters = heightCMeters;
this.lengthCMeters = lengthCMeters;
this.weightKilos = weightKilos;
}
public void lionDetails() {
System.out.println("Name: " + this.name);
System.out.println("Height CM: " + this.heightCMeters);
System.out.println("Length CM: " + this.lengthCMeters);
System.out.println("Weight Kilos: " + this.weightKilos);
}
public void eat(X x) {
int hitPoints = x.hitPoints - 10;
System.out.println(x)
}
}
Class Dog
package helloworld;
public class Dog {
public String name;
public int heightCMeters;
public int lengthCMeters;
public float weightKilos;
public int hitPoints;
public Dog(int hitPoints, String name, int heightCMeters, int lengthCMeters, float weightKilos) {
this.name = name;
this.heightCMeters = heightCMeters;
this.lengthCMeters = lengthCMeters;
this.weightKilos = weightKilos;
}
public void dogDetails() {
System.out.println("Name: " + this.name);
System.out.println("Height CM: " + this.heightCMeters);
System.out.println("Length CM: " + this.lengthCMeters);
System.out.println("Weight Kilos: " + this.weightKilos);
}
public void eat(X x) {
int hitPoints = x.hitPoints - 10;
System.out.println(x)
}
}
Basically, Lions can eat dogs and the converse is true (which is weird, a dog is not brave enough to attack Lions). Anyways, what you need is an abstract class that represents animals that eat animals, this class should contain the hitPoint you mentioned.
abstract class X {
public int hitPoints;
}
// Lions are edible
class Lion extends X{
public void eat(X x) { // pass an edible object
int hitPoints = x.hitPoints - 10;
System.out.println(x)
}
}
//Dogs are edible as well
class Dog extends X{
public void eat(X x) { // pass an edible object
int hitPoints = x.hitPoints - 10;
System.out.println(x)
}
}
And now, for a Lion to a eat dog,
Lion predator = new Lion();
Dog prey = new Dog();
predators.eat(prey); // this passed dog will be eaten
Best way write a test class or write main method for Lion class which will maintain hitpoints of both the classes.
class Test{
public static void main(String[] args){
Dog puppy=new Dog(10,"Moti",12,12,31);
Lion oldLion=new Lion(20,"Old Lion",12,12,43);
oldLion.eat(puppy);
}
}
You must have an abstract class Animal, with all the common methods defined there.
For eat method of Lion class,
public void eat (Animal animal) {
this.hitPoints-=animal.hitPoints;
}
For eat method of Dog class, also the same logic.
Based on the response of sleiman jneidi:
You should create an abstract containing the hitPoints and the eat method (that it's the same behavior for each animal) Then you have not to wrote the method each time
abstract class X {
public int hitPoints;
public void eat(X x) { // pass an edible object
int hitPoints = x.hitPoints - 10;
System.out.println(x)
}
}
// Lions are edible
class Lion extends X{
}
//Dogs are edible as well
class Dog extends X{
}
The instance variable contained in the Animal class is inherited by the Lion and Dog class.
It retains the value each time the eat(Aniamal a) method is called with an Animal object passed as a parameter. So than working on the instance variable contained in the Animal object that has been passed to the eat method we can perform various functions on the instance variable.
public class Animal {
public int hitPoints;
}
public class Lion extends Animal {
public String name;
public Lion(String name) {
this.name = name;
}
public void eat(Animal a) {
a.hitPoints = a.hitPoints - 10;
System.out.println(this.name + " Has: " + a.hitPoints + " HitPoints");
}
}
public class Dog extends Animal {
public String name;
public Dog(String name) {
this.name = name;
}
public void eat(Animal a) {
a.hitPoints = a.hitPoints - 10;
System.out.println(this.name + " Has: " + a.hitPoints + " HitPoints");
}
}
public static void main(String[] args) {
Cat adam = new Cat("adam");
Lion dam = new Lion("dam");
dam.eat(adam);
}
I would make anything that can be eaten implement an interface Edible. Then that interface can have a method isEaten that takes the hit point deduction.
Something like this:
public interface Edible {
void isEaten(final int hitPointsToDeduct);
}
Then your Lion and Dog would implement this so that they could be eaten.
The Dog class would be:
public class Dog implements Edible {
public String name;
public int heightCMeters;
public int lengthCMeters;
public float weightKilos;
public int hitPoints;
public Dog(final int hitPoints, final String name, final int heightCMeters, final int lengthCMeters, final float weightKilos) {
this.name = name;
this.heightCMeters = heightCMeters;
this.lengthCMeters = lengthCMeters;
this.weightKilos = weightKilos;
}
public void dogDetails() {
System.out.println("Name: " + this.name);
System.out.println("Height CM: " + this.heightCMeters);
System.out.println("Length CM: " + this.lengthCMeters);
System.out.println("Weight Kilos: " + this.weightKilos);
}
public void eat(final Edible x) {
x.isEaten(10);
System.out.println(x);
}
public void isEaten(final int hitPointsToDeduct) {
this.hitPoints = this.hitPoints - hitPointsToDeduct;
}
}
And the Lion class:
public class Lion implements Edible {
public String name;
public int heightCMeters;
public int lengthCMeters;
public float weightKilos;
public int hitPoints;
public Lion(final int hitPoints, final String name, final int heightCMeters, final int lengthCMeters, final float weightKilos) {
this.name = name;
this.heightCMeters = heightCMeters;
this.lengthCMeters = lengthCMeters;
this.weightKilos = weightKilos;
}
public void lionDetails() {
System.out.println("Name: " + this.name);
System.out.println("Height CM: " + this.heightCMeters);
System.out.println("Length CM: " + this.lengthCMeters);
System.out.println("Weight Kilos: " + this.weightKilos);
}
public void eat(final Edible x) {
x.isEaten(10);
System.out.println(x);
}
public void isEaten(final int hitPointsToDeduct) {
this.hitPoints = this.hitPoints - hitPointsToDeduct;
}
}
The advantage of this is that the hitPoints field is held centrally to one object. The Lion is not pulling out the value of the Dogs hitPoints. Look at this page for an explanation of the "Tell Dont Ask" concept.
EDIT
Having just had a play, I noticed that you're not setting the hitPoints value in either of your constructors and that your objects print out with the object reference rather than the details. For this, override the toString method. Here's the rewritten bits of the Dog clas:
public Dog(final int hitPoints, final String name, final int heightCMeters, final int lengthCMeters, final float weightKilos) {
this.name = name;
this.heightCMeters = heightCMeters;
this.lengthCMeters = lengthCMeters;
this.weightKilos = weightKilos;
this.hitPoints = hitPoints;
}
#Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("Name: ");
builder.append(this.name);
builder.append(", Height CM: ");
builder.append(this.heightCMeters);
builder.append(", Length CM: " );
builder.append(this.lengthCMeters);
builder.append(", Weight Kilos: ");
builder.append(this.weightKilos);
builder.append(", Hit Points: ");
builder.append(this.hitPoints);
return builder.toString();
}
So then with this main method:
public static void main(final String[] args) {
final Lion adam = new Lion(500, "Adam", 5, 5, 5);
final Dog fido = new Dog(500, "Fido", 5, 5, 5);
adam.eat(fido);
}
I got the following output:
Name: Fido, Height CM: 5, Length CM: 5, Weight Kilos: 5.0, Hit Points: 490
Notice the hit points have been reduced from 500 to 490.

Categories