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.
Related
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.
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.
I try to:
Create a Car object in the Main.
Send the object as an argument to the carOwners class.
Print the entire carOwners data from main.
Name and Address will be printed, but not the Car.
What is wrong with my code?
public class TestProgram {
public static void main(String [] args){
Car Saab = createCar();
carOwners guy = createCarOwners (Saab);
printAll(guy);
}
public static Car createCar (){
//user input a, b, c, d
Car temporary = new Car (a, b, c, d);
return temporary;
}
public static carOwners createCarOwners (Car x){
//user input a, b
Car c = x;
carOwners temporary = new carOwners (a, b, c);
return temporary;
}
public static void printAll (carOwners x){
x.printCarData();
x.printNameAddress();
}
}
public class Car {
private String model;
private String Year;
private String licensePlate;
private String color;
public Car (String x, int y, String z, String q){
model = x;
Year = y;
licensePlate = z;
color = q;
}
}
public class carOwners {
private String name;
private String address;
private Car TheCar;
public carOwners (String n, String a, Car b){
name = n;
address = a;
TheCar = b;
}
public void printNameAddress(){
System.out.println();
System.out.println(name);
System.out.println(address);
}
public void printCarData(){
System.out.println(TheCar);
}
}
override toString(), so you can custom the output format of Car
public String toString(){
return "Model :" + this.model + ",Year :" + year;
}
Your Problem is here:
public void printCarData(){
System.out.println(TheCar);
}
You want to print an Object. That doens't work because Java uses the toString-Method for that. If you want to do it like that you have to override the toString()-Method of your car class like that:
public String toString()
{
return "CarModel: " + this.model + ", Production Year: " + year;
}
I'm just trying to Override and use the toString method to print some information about my classes.
Can someone please provide advice as to how I would do this?
I've never done this before, and I'm becoming stuck.
My Base Class:
public class Vehicle {
int seatNumber;
int numberMade;
int yearMade;
public Vehicle(int seatNumber, int numberMade, int yearMade) {
this.seatNumber = seatNumber;
this.numberMade = numberMade;
this.yearMade = yearMade;
}
public int getSeatNumber() {
return seatNumber;
}
public int getNumberMade() {
return numberMade;
}
public int getYearMade() {
return yearMade;
}
}
A derived class:
public class Car extends Vehicle {
public int topSpeed;
public Car(int seatNumber, int numberMade, int yearMade, int topSpeed) {
this.seatNumber = seatNumber; //takes the value you pass as parameter
this.numberMade = numberMade; // and stores it into the instance variable
this.yearMade= yearMade;
this.topSpeed = topSpeed;
}
}
Main Class:
public class Assignment2 {
public static void main(String[] args) {
Car myCar = new Car(5, 20000, 1998, 180);
Motorbike myMotorbike = new Motorbike(1, 5000, 2015, 300);
System.out.println(myCar);
System.out.println(myMotorbike);
}
}
You can do it like this:
public class Vehicle {
int seatNumber;
int numberMade;
int yearMade;
// Getters, setters, constructor, etc
#Override
public String toString() {
return String.format("[Vehicle] seats: %d, number made: %d, yearMade %d", seatNumber, numberMade, yearMade);
}
}
Same for the other Class
I'm just trying to Override and use the toString method to print some information about my classes
There are 2 ways you can override a method in the subclass.
Override by modification
Override it with new implementation
Can someone please provide advice as to how I would do this?
Overridding in Java is very simple. Just rewrite the method with similar method signature in the subclass according to the method in its super class.
Below shows an example of overriding by modification:
class Animal
{
#Override
public String toString(){
return "An animal";
}
}
class CatFamily extends Animal{
#Override
public String toString(){
return super.toString() + " from the cat family.";
}
}
class Lion extends CatFamily{
#Override
public String toString(){
return super.toString() + " - A Lion";
}
}
Create a super & subclass instance for testing:
public static void main(String[] args)
{
System.out.println(new Animal());
System.out.println(new CatFamily());
System.out.println(new Lion());
}
OUTPUT:
An animal
An animal from the cat family.
An animal from the cat family. - A Lion
I have public class Vehicle with two subclasses Car and Truck that each extend Vehicle. The constructor for each class is the same with 3 fields, color, brand and gas mileage.
I've declared an array
Vehicle [] vehArray = new Vehicle[6];
that will store 6 different vehicles. I know a call
Car car1 = new Car("Red", "Ford", 15);
will instantiate car1 with an object of type Car.
How would I store car1 in vehArray[0]?
Try doing something like this:
vehArray[0] = car1;
Shortest way is:
vehArray [0] = new Car("Red", "Ford", 15);
Or even
Vehicle[] vehArray = new Vehicle[]{new Car("Red", "Ford", 15), new Truck("Silver", "Mercedes", 2)};
As below;
1) Test.java;
public class Test {
public static void main(String[] args) {
//Array Initialization with null Vehicle placeholders
Vehicle[] vehicleArray = new Vehicle[6];
//Car class object instances are assiged
for( int i = 0; i < vehicleArray.length; i++ )
vehicleArray[i] = new Car("Red", "Ford", 15+i);
for( int i = 0; i < vehicleArray.length; i++ )
System.out.println
(
i +
" : " + vehicleArray[i].getColor() +
" : " + vehicleArray[i].getBrand() +
" : " + vehicleArray[i].getGasMilage()
);
}
}
2) Vehicle.java
public class Vehicle {
private String color;
private String brand;
private int gasMilage;
public Vehicle() {}
//Constructor with fields
public Vehicle(String color, String brand, int gasMilage) {
this.color = color;
this.brand = brand;
this.gasMilage = gasMilage;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getGasMilage() {
return gasMilage;
}
public void setGasMilage(int gasMilage) {
this.gasMilage = gasMilage;
}
}
3) Car.java
public class Car extends Vehicle {
//no-arg constructor
public Car() {
super();
}
//field constructor
public Car(String color, String brand, int gasMilage) {
super(color, brand, gasMilage);
}
}
4) Truck.java
public class Truck extends Vehicle {
//no-arg constructor
public Truck() {
super();
}
//field constructor
public Truck(String color, String brand, int gasMilage) {
super(color, brand, gasMilage);
}
}
I suggest declaring all objects of subclasses first then it can be stored in vehicle like so :
Vehicle[] vehicleArray = {ob1,ob2,ob3,ob4,andSo_On};
Do you mean calling parent class constructor so you can use the fields in parent class?
Here's my take :)
Vehicle.java
public class Vehicle {
String color, brand;
int mileage;
Vehicle(String c, String d, int e){
color = c;
brand = d;
mileage = e;
}
}
Car.java
public class Car extends Vehicle{
Car(String c, String d, int e){
super(c, d, e);
}
}
Test.java
public class Test {
public static void main(String[] args) {
Vehicle [] vehArray = new Vehicle[6];
Car car1 = new Car("Red", "Ford", 15);
Car car2 = new Car("Blue", "Audi", 17);
vehArray[0] = car1;
vehArray[1] = car2;
System.out.println("Color: " + car1.color + "\nBrand: " + car1.brand + "\nMileage: " + car1.mileage + "\n");
System.out.println("Color: " + car2.color + "\nBrand: " + car2.brand + "\nMileage: " + car2.mileage);
for(int i=0; i<2; i++) {
if(vehArray[i].color == "Blue")
{
System.out.println("\nCar is " + vehArray[i].brand);
}
}
}
}
I even did testing at the end just to make sure. You're welcome :D