I am learning JAVA OOP, I have to compare the age between 2 objects:
In java Procedural, I will have done:
public static int calculateDifferenceAge(int agePlayer1, int agePlayer2){
int differenceAge = agePlayer1 - agePlayer2;
if(differenceAge < 0){
differenceAge = -differenceAge;
}
return differenceAge;
}
Then
public static void displayDifferenceAge(String namePlayer1, String namePlayer2, int agePlayer1, int agePlayer2){
System.out.println("Age difference between " + namePlayer1 + " and " + namePlayer2 + " is of" + calculateDifferenceAge(agePlayer1, agePlayer2) + " year(s).");
}
}
I don't understand how to create my calculateDifferenceAge() method in OOP ?
In my main file I have this:
List<Player> players = new ArrayList <Player>();
players.add(new Player("Eric", 31, true));
players.add(new Player("Juliette", 27, false));
I am stuck into my 2 methods:
How to subtract the age of 2 objects?
public static int calculateAgeDifference(List <Player> players){
Player differenceAge = (players.get(0) - players.get(1));
return differenceAge;
}
public static void displayCalculateAgeDifference(List <Player> players){
System.out.println(calculateAgeDifference().age);
}
Class Player
public class Player {
public String name;
public int age;
public boolean sex;
public Player(String name, int age, boolean sex){
this.name = name;
this.age = age;
this.sex = sex;
}
you're only missing a little step in your code. The steps to extract the ages of the list should be:
1.- Extract the object from the list
2.- Extract the age of that object (or player, in this case)
3.- Substract the ages
There's some ways to do it, but I would do it this way:
public static int calculateAgeDifference(List<Player> players) {
int age1= players.get(0).age;
int age2= players.get(1).age;
int differenceAge = age1 - age2;
if(differenceAge < 0){
differenceAge = -differenceAge;
}
return differenceAge;
}
I hope that helps. What i've done there is extract the objects player from the list: players.get(0) extracts the first object inside the list, which is a Player. Now that I have a player and it has an age variable i have to extract it with player.age. I collapsed those steps, if you have any questions I can explain you further
Display method:
public static int displayCalculateAgeDifference (List<Player> players){
String name1= players.get(0).name;
String name2= players.get(1).name;
//as you know this method return the difference in a number form
int difference= calculateAgeDifference(players);
System.out.println("Age difference between " + name1 + " and " + name2 + " is of" + difference + " year(s).");
}
Let's start with a class Player. Let's give it a name and an age, and a calculateAgeDifference method. It should look something like,
public class Player {
private int age;
private String name;
public Player(String name, int age) {
this.name = name;
this.age = age;
}
public int calculateAgeDifference(Player player2) {
return Math.abs(this.age - player2.age);
}
}
Then you can call it like
Player a = new Player("Eric", 40);
Player b = new Player("Sally", 51);
System.out.println(a.calculateAgeDifference(b));
You must have a similar Player class. Yours appears to also have a boolean field. It isn't clear why. So I can't speak to that.
Why did your method interface change from two parameters to a list? You can still pass two instances of the object. You can still return the integer age value from the method, no need to create a Frankenstein's Player instance only to hold the age.
I am assuming your Player class has a method getAge() to extract the age value which was passed in in the constructor:
public static int calcAgeDiff(final Player player1, final Player player2) {
int age1 = player1.getAge();
int age2 = player2.getAge();
return Math.abs(age2 - age1);
}
Alternatively, you can add an instance method to your Player class itself to calculate the age difference to a different player:
public class Player {
// fields
// constructor
// getters
public int ageDiffTo(final Player otherPlayer) {
return Math.abs(this.age - otherPlayer.age); // <- a class can always access its private fields, even of other instances
}
}
then call as player1.ageDiffTo(player2)
Related
I've been studying code on my own, and I got a problem that I do not know how to answer.
I am given a student and classroom class, and from those two I need to be able to create a method for getTopStudent, as well as thegetAverageScore.
**Edit: All of the code was given except for the two methods, I needed to create those 2. The thing is that I'm not sure if what I'm doing is correct.
public class Student
{
private static final int NUM_EXAMS = 4;
private String firstName;
private String lastName;
private int gradeLevel;
private double gpa;
private int[] exams;
private int numExamsTaken;
public Student(String fName, String lName, int grade)
{
firstName = fName;
lastName = lName;
gradeLevel = grade;
exams = new int[NUM_EXAMS];
numExamsTaken = 0;
}
public double getAverageScore() //this is the method that I need to, but I'm not sure if it is even correct.
{
int z=0;
for(int i =0; i<exams.length; i++)
{
z+=exams[i];
}
return z/(double) numExamsTaken;
}
public String getName()
{
return firstName + " " + lastName;
}
public void addExamScore(int score)
{
exams[numExamsTaken] = score;
numExamsTaken++;
}
public void setGPA(double theGPA)
{
gpa = theGPA;
}
public String toString()
{
return firstName + " " + lastName + " is in grade: " + gradeLevel;
}
}
public class Classroom
{
Student[] students;
int numStudentsAdded;
public Classroom(int numStudents)
{
students = new Student[numStudents];
numStudentsAdded = 0;
}
public Student getTopStudent() //this is the other method I need to create
{
int x=0;
int y=0;
for(int i =0; i<numStudentsAdded; i++)
{
if(x<students.getAverageScore())
{
x=students.getAverage();
y++;
}
}
return students[y];
}
public void addStudent(Student s)
{
students[numStudentsAdded] = s;
numStudentsAdded++;
}
public void printStudents()
{
for(int i = 0; i < numStudentsAdded; i++)
{
System.out.println(students[i]);
}
}
}
I have something down for each of them but it isn't running. I don't fully understand arrays yet, but this is apparently a beginner code using arrays. If anyone could help with what I need to do and tell me how arrays work, much would be appreciated.
getAverageScore() is a method of Student. But students is not a Student object, it's an array of Student objects. (And getAverage(), which you call inside the for loop, isn't a method at all.) An array is a separate object that contains other objects or primitives (like ints) in it. So students.getAverageScore() is not going to compile, because students doesn't have that method, each of its members (student[0], student[1], etc.) has it.
Try replacing the getTopStudent method with something like this:
public Student getTopStudent() //this is the other method I need to create
{
int x=0; //this will contain the highest average
int y=0; //this will be the index in the array of the highest scoring student
for(int i =0; i<numStudentsAdded; i++)
{
int currentAverage = students[i].getAverageScore(); //run the getAverageScore() on the current student
if(x<currentAverage) // compare it to the previous high average
{
x=currentAverage; // replace x with new high average
y=i; //replace the index of the highest scoring student with current index i
}
}
return students[y]; // so if the fifth student had the highest score, y would be 4
}
So you are having trouble int the method public Student getTopStudent()
public Student getTopStudent() //this is the other method I need to create
{
double x= students[0].getAverageScore();
int y = 0;
for(int i=1;i<students.length;i++){
if(x<students[i].getAverageScore()) {
x = students[i].getAverageScore();
y =i;
}
}
return students[y];
}
See if this helps
Currently a beginner, I wrote a simple program which uses getters and return values (current course). I'd like to ask when should I use the void solution and the int solution, if both gives me the same outcome?
I really hope the formatting isn't too terrible.
class Database {
String name;
int age;
String getName() {
return name;
}
int getAge() {
return age;
}
int yearsPlusFifty() {
int year = age + 50;
return year;
}
void plusFifty() {
int year2 = age + 50;
System.out.println(year2);
}
}
public static void main(String args[]) {
Database person1 = new Database();
person1.name = "Josh";
person1.age = 30;
int year = person1.yearsPlusFifty();
System.out.println("The age plus 50 is: " + year);
person1.plusFifty();
}
Use the int method (yearsPlusFifty) as that one has one responsibility - to calculate the value. Println in plusFifty is a side effect, which is not desirable. Keep the responsibilities of calculating and printing separate (makes it more reusable, testable, and easier to understand).
Basically, void should be used when your method does not return a value whereas int will be used when your method returns int value.
Now coming to your methods, they both are not same, they are doing two different things:
int yearsPlusFifty() - adding 50 and returning int value
void plusFifty() - better rename to printPlusFifty() - this method does both adding plus printing as well
int yearsPlusFifty() {//only adding and returning int value
int year = age + 50;
return year;
}
void printPlusFifty() {//adding + printing
int year2 = age + 50;
System.out.println(year2);
}
So I have a bunch of classes used for an animal hospital. My superClass, Pet, has four constants, MALE, FEMALE, SPAYED, NEUTERED, that are set to numbers. When a data file is read in, in my AnimalHospitalClass, it is supposed to set the gender to a number, go back to the Pet class compare the "sexId" to the constant, and then return the gender. The issue Im having is not logical but technical. For some reason my setter is (setSex(sexID)) is getting the number that my gender is set to, but when I try to make the if statements in my getter to compare the numbers and return the gender, the sexID ( which is a variable in the Pet class) is set back to 0, instead of what I set it to.
heres my Pet Class:
public class Pet{
private String petName;
private String ownerName;
private String color;
protected int sexID;
public static final int MALE = 1;
public static final int FEMALE = 2;
public static final int SPAYED = 3;
public static final int NEUTERED = 4;
public Pet(String petName, String ownerName, String color){
this.petName = petName;
this.ownerName = ownerName;
this.color = color;
}
// getters
public String getPetName(){
return petName;
}
public String getOwnerName(){
return ownerName;
}
public String getColor(){
return color;
}
public String getSex(){
/* this is where I am having issues, instead of sexID being set to what
it is in the setter, it is set back to 0*/
System.out.println("SEXID: " + sexID); // will print 0
if(sexID == MALE){
return("male " );
}
else if(sexID == FEMALE){
return("female");
}
else if(sexID == SPAYED){
return("spayed");
}
else if(sexID == NEUTERED){
return("neutered");
}
else{ // will print else only since sexID is equal to 0
return("Not Available. " + sexID);
// in case there is no gender in the file
}
}
public void setSex(int sexID){
this.sexID = sexID;
System.out.println("SEX: " + sexID); // this will print the correct
// sexID that was set in the other class
}
public String toString(){
return(petName + "owned by " + ownerName
+ "\nColor: " + color
+"\nSex: " + getSex() );
}
}
here is my Animal hospital class (only one method since it is large):
import java.util.*;
import java.io.*;
public class AnimalHospital{
Scanner input;
private String pName;
private String pName2;
private String oName;
private String color ;
private String specialType; // store hair length for cats, size for dogs
private String gender;
private String type; // finds CAT, DOG, BIRD
public AnimalHospital(String inputFile)throws FileNotFoundException{
input = new Scanner(new File(inputFile));
}
public void printPetInfoByOwner(String name){
Pet pet = new Pet(pName,oName,color);
while(input.hasNext()){
String type = input.next(); // finds Cat, Dog, Bird
pName = input.next(); // gets pet name
oName = input.next(); // gets owner name
color = input.next();
gender = input.next();
if(gender.equals("male")){ // this is where I set the gender
int male = 1; // to a number so I can compare
pet.setSex(male);
}
if(gender.equals("female")){
int female = 2;
pet.setSex(female);
}
if(gender.equals("spayed")){
int spayed = 3;
pet.setSex(spayed);
}
if(gender.equals("neutered")){
int neutered = 4;
pet.setSex(neutered);
}
if(!(type.equals("BIRD"))){
specialType = input.next(); // since Bird does not have a special type
}
if(type.equals("CAT") && oName.equals(name)){
Cat cat = new Cat(pName, oName, color, specialType);
System.out.println(cat.toString());
break;
}
if(type.equals("DOG") && oName.equals(name)){
Dog d = new Dog(pName, oName, color, specialType);
System.out.println(d.toString());
break;
}
if(type.equals("BIRD") && oName.equals(name)){
Bird b = new Bird(pName, oName, color);
System.out.println(b.toString());
break;
}
}
}
here is an example output:
CAT: Busker owned by Samantha
Color: Black
Sex: Not Available. 0 // reads sex as 0 should be 2, and female
Hair: short
AnimalHospital#55f96302 // also how do I get rid of this?
Note:
This is an assignment, and I understand if you don't want to give me the answer, any hints would be helpful, but I've thought about this for days and can't figure it out.
thanks!
You're setting the sex on the pet variable, of type Pet. Then you create a Cat, Bird or Dog, never set its sex, and print it. So, since you never set the sex of the Cat, Bird or Dog, it's 0.
So here is my Superhero class:
public class Superhero {
public int strength;
public int powerUp;
public int defaultStrength = 10;
public String name;
public Superhero(String name) {
this.strength = 10;
System.out.println("The Superheroes available are :" + name);
}
public Superhero(String name, int strength) {
if (strength >= 0) {
this.strength = strength;
System.out.println("The Superheroes available are :" + name);
} else {
System.out.println("Error. Strength cannot be < 0");
}
}
public void setStrength( int strength ) {
this.strength = strength;
}
public int getStrength() {
return strength;
}
public void powerUp(int powerUp) {
this.strength += powerUp;
}
}
Here is my Fight class the problem here is when I run it I get back that the winner result is null and I don't understand why it is doing that.
import java.io.*;
public class Fight {
public static void main (String args[]) {
Superhero gambit = new Superhero( "Gambit" );
Superhero groot = new Superhero( "Groot", 79);
System.out.println( "Gambit's strength is: " + gambit.strength);
System.out.println( "Groot's strength is: " + groot.strength);
System.out.println("The winner of the fight is: " + fight(gambit, groot));
}
static String fight(Superhero a, Superhero b)
{
if (a.strength > b.strength)
{
return a.name;
} else
{
return b.name;
}
}
}
Look at your constructor:
public Superhero(String name) {
this.strength = 10;
System.out.println("The Superheroes available are :" + name);
}
That sets the instance field strength, but doesn't do anything with the name instance field. Your other constructor is the same. You need to include:
this.name = name;
to copy the value from the parameter into the instance variable. Do this in both constructors. Otherwise you just end up with the default value for name, which is a null reference.
As an aside, I'd strongly recommend making your fields private and adding a getName() method to retrieve the name from else your fight method. I'd also throw an exception instead of just printing out an error message if the strength is below 0, and also I'd make the constructor which doesn't take a strength parameter just chain to the one that does:
public Superhero(String name) {
this(name, 10);
}
public Superhero(String name, int strength) {
if (strength < 0) {
throw new IllegalArgumentException("strength cannot be negative");
}
this.strength = strength;
this.name = name;
System.out.println("The Superheroes available are :" + name);
}
(The message displayed by the constructor is a bit odd, given that it's only listing a single name, but that's a different matter.)
The problem is in your constructors:
public Superhero(String name) {
this.strength = 10;
System.out.println("The Superheroes available are :" + name);
}
public Superhero(String name, int strength) {
if (strength >= 0) {
this.strength = strength;
System.out.println("The Superheroes available are :" + name);
} else {
System.out.println("Error. Strength cannot be < 0");
}
}
Your constructors have an argument of a String name, but you never set the instance variable to a value. The default value of an uninitialized variable that contains an object is null.
You never set the name in any of the constructors of Superhero. To fix the first constructor, for example:
public Superhero(String name) {
this.name = name;
this.strength = 10;
System.out.println("The Superheroes available are :" + name);
}
You are never assigning the "incoming" name to the attribute field "name" of your class. So the later one stays null.
Btw: you really want to read those exception traces carefully. They provide all the information that you need to have in order to figure whats going on.
Final note: consider using the keyword final for the attributes of your class. That way you would have not run into this problem; as the compiler would have told you that the field "name" isn't initialized in your code.
Make a getter method that returns the String name in your superhero class, then call that method within your Fight class. I would also suggest changing your global variables in your superhero class from public to private, so they are only accessible within that class.
EDIT: As stated in another answer, your constructor that takes name as an argument is never assigned to a variable.
You are not setting the values of name variable in the constructor, use this
public Superhero(String name) {
this.strength = 10;
this.name = name;
System.out.println("The Superheroes available are :" + name);
}
public Superhero(String name, int strength) {
this.name = name;
if (strength >= 0) {
this.strength = strength;
System.out.println("The Superheroes available are :" + name);
} else {
System.out.println("Error. Strength cannot be < 0");
}
}
My question today is, how can I assign values for my state variables/methods, in order to compare values to determine the winner?
Also, how do I direct the values to "Jack" and "Jill" (player p1 and p2)?
Should I use if-else statements?
And last question: why does my console print "null" for my getScore, getcardSuit, getcardValue, etc??
(I will give you my console printout after all of this)
Here is my code for my "player class", and my "tester" project is below this code (to test my player class):
public class player {
// The two players are going to enter:
String p1[] = {"Jack", "h", "k"};
String p2[] = {"Jill", "d", "9"};
//Setting up values
String Jack = "Jack";
String Jill = "Jill";
String h = " Hearts ";
String d = " Diamonds ";
String k = " King ";
int val = 9;
// Score
public int score = 0; // State variable score, set equal to 0
// Player name - Jack, Jill
public player(String Jack, String h, String k) {
// TODO Auto-generated constructor stub
}
public String playerName(String player)
{
player = "Jack";
player = "Jill";
return player;
}
// Card suit
public String cardSuit(String getcardSuit)
{
return cardSuit;
}
// Card Value for player 1
public String getCardValue()
{
return cardValue;
}
public String getScore(String score)
{
return score;
}
public String player;
public String playerName;
public String cardSuit;
public String cardValue;
public double getScore;
public String getCardSuit()
{
return cardSuit;
}
public int getScore() {
return 0;
}
}
Here is my "Tester", to test my "player class":
public class Tester {
public static void main(String[] args) {
// Create an object for player 1
player p1 = new player("Jack", "h", "k");
// Create an object for player 2
player p2 = new player("Jill", "d", "9");
// Use p1 object and methods getCardSuit and getCardValue to report p1's card
System.out.println(p1.playerName+"'s card is a "+p1.getCardValue()+" of "+p1.getCardSuit()+".");
// Should print:
// Jack's card is a King of Hearts.
// Use p2 object and methods getCardSuit and getCardValue to report p2's card
System.out.println(p2.playerName+"'s card is a "+p2.getCardValue()+" of "+p2.getCardSuit()+".");
// Should print:
// Jill's card is a 9 of Diamonds.
// Compare player's scores to determine winner
if(p1.getScore()>p2.getScore())
System.out.println(p1.playerName+" is the winner!");
else if (p1.getScore()<p2.getScore());
System.out.println(p2.playerName+" is the winner!");
// Should print:
// "Jack is the winner!"
}
}
CONSOLE:
null's card is a null of null.
null's card is a null of null.
null is the winner!
how can I fix this "null" stuff and actually have their values printed??
Thanks so much, in advance! :)
I'll start by answering the question you asked:
The values are null because they were never initialized. Your constructor for the player class:
public player(String Jack, String h, String k) {
// does absolutely nothing with the values.
}
does nothing. This means you created a new player player1 and a new player player2 but didn't actually use the values to do anything at all.
player p1 = new player("Jack", "h", "k");
calls the constructor, sends in values and the values are ignored. An instance of player1 is created and absolutely nothing is done with the information. You, therefore, cannot compare the values to each other since they have not been initialized.
Other considerations
When you make a class, in object oriented programming you should think in an OO sort of way.
The player class can/should have a String name; variable and you can then create a Player object and pass the name, exactly like you did. The difference is in your constructor:
//Setting up values
String name;
String suit;
String value;
public player(String name, String suit, String value) {
this.name = name;
this.suit = suit;
this.value = value;
}
This technique creates a player1 object with a name, a suit and a value. Now the values within this object can be compared to equal values in another player object if you so choose.
So I tried to clean up your Player class a bit:
public class Player
{
// The two players are going to enter:
String p1[] = {"Jack", "h", "k"};
String p2[] = {"Jill", "d", "9"};
//Setting up values
String jack = "Jack";
String jill = "Jill";
String h = " Hearts ";
String d = " Diamonds ";
String k = " King ";
int val = 9;
// Score
public int score = 0; // State variable score, set equal to 0
// Player name - Jack, Jill
public Player(String jack, String h, String k)
{
this.jack = jack;
this.h = h;
this.k = k;
}
public String playerName(String player)
{
// not sure what this is doing?
// this first line does nothing at all
// because player gets reassigned to "Jill"
player = "Jack";
player = "Jill";
return player;
}
// Card suit
public String cardSuit(String getcardSuit)
{
return cardSuit;
}
// Card Value for player 1
public String getCardValue()
{
return cardValue;
}
public String getScore(String score)
{
return score;
}
public String player;
public String playerName;
public String cardSuit;
public String cardValue;
public double getScore;
public String getCardSuit()
{
return cardSuit;
}
public int getScore()
{
return 0;
}
}
There are a couple of conventions you should start using. Class names should start with an uppercase letter. Variables and stuff like that should all have lower case letters (unless it is a static).