I wrote a test program in java in which the object has 3 parameters:
id, name and age.
The name and age are initialised using constructor but id should be incremented automatically from the last id. (and it should start from 1 for 1st created object).
I used id as static variable to achieve the same.
import java.util.*;
class Test
{
private static int id = 1;
private int age;
private String name;
public Test(String name, int age)
{
this.id = id;
this.age = age;
this.name = name;
id++;
}
public String toString()
{
return id + " " + name + "," + age;
}
public static void main(String args[])
{
Test c1 = new Test("A", 12);
Test c2 = new Test("B", 32);
Test c3 = new Test("C", 58);
Test c4 = new Test("D", 17);
Test c5 = new Test("E", 42);
ArrayList<Test> testList = new ArrayList<Test>();
testList.add(c1);
testList.add(c2);
testList.add(c3);
testList.add(c4);
testList.add(c5);
for(int i = 0; i < testList.size(); i++)
System.out.println(testList.get(i).toString());
}
}
But in the output I am getting same id for all the test objects.
Can anyone please explain why this is happening ?
Any help will be highly appreciated.
A static variable means that the variable is shared between all the instances of the given class, if you change the value of a static variable in one of the instances it will be changed in all.
What you want to accomplish probably is doable in the next way:
class Test
{
public static int counter = 1;
private int id;
private int age;
private String name;
public Test(String name, int age)
{
this.id = counter;
this.age = age;
this.name = name;
counter++;
}
public String toString()
{
return id + " " + name + "," + age;
}
....
Make the counter public, you might actually need to reference it from outside the class instance, or if you cannot afford to expose it as public make it private and create a static getter for it which will allow you to get the current id counter from outside the class.
Another option is to use the Factory Pattern but probably that is not needed for this particular case.
Related
Tody i have tried to code a program, with administrate virtual Footballplayers. Now i have the problem, that i dont know how to initialize an Array of another Class in the Constructer.
This are my declarations for my "Teams"
Manager managerOfBayern = new Manager("Manager1",55,125);
Manager managerOfBvb = new Manager("Manager2",60,122);
Team fcBayern = new Team(managerOfBayern,playerArrFcB,"FcBayern");
Team bvb = new Team(managerOfBvb,playerArrBvb,"Bvb");
Now i want to initialize my Team.
public class Team {
Manager theManager;
Player[] thePlayer;
String name;
public Team(Manager theManager, Player[] thePlayer, String name) {
this.theManager = theManager;
for (int i = 0; i < thePlayer.length; i++) {
thePlayer[i] = thePlayer[i];
}
this.name = name;
}
But how can i correctly initialize an Array (thePlayer)
i hope you guys can help me with this problem.....
What you are doing is almost correct!
just in the the part of array initialization that is the for loop that you are running in the constructor for copying the array, just replace left hand side of the operator '=' with 'this.thePlayer[i]' and you also need to specify the size of the array beforehand to initialize and use it in the for loop i.e the resultant constructor code should be like this
public Team(Manager theManager, Player[] thePlayer, String name) {
this.theManager = theManager;
this.thePlayer = new Player[thePlayer.length];
for (int i = 0; i < thePlayer.length; i++) {
this.thePlayer[i] = thePlayer[i];
//or this.thePlayer[i] = new Player(thePlayer[i]); in case you want true deep copy, then in Player class you make a constructor of this signature(also known as copy constructor) and copy all the properties of Object passed as an argument
}
this.name = name;
}
I don't have the right solution for your problem but I can think for another way if it's good for you. check it out :
For Player class :
private String name;
private int age;
private int height;
public Player(String name, int Age , int height){
this.name=name;
this.age= Age;
this.height = height;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public int getHeight(){
return this.height;
}
#Override
public String toString(){
return this.name +" , "+ this.age +" , "+ this.height;
}
For Manager class :
private String name;
public Manager(String name){
this.name = name;
}
public String getManager(){
return this.name;
}
For Manager class :
Manager theManager;
Player[] thePlayer;
String name;
public Team(Manager theManager, Player[] thePlayer , String name){
this.theManager = theManager;
this.thePlayer = thePlayer;
this.name = name;
}
#Override
public String toString(){
String list = null ;
for (int i = 0;i<thePlayer.length;i++){
list += thePlayer[i].toString()+"\n";
}
return "Team name : " + this.name + "\n Team manager : " + this.theManager.getManager() + "\n Team players : \n" + list;
}
For team class :
Manager theManager;
Player[] thePlayer;
String name;
public Team(Manager theManager, Player[] thePlayer , String name){
this.theManager = theManager;
this.thePlayer = thePlayer;
this.name = name;
}
#Override
public String toString(){
String list = null ;
for (int i = 0;i<thePlayer.length;i++){
list += thePlayer[i].toString()+"\n";
}
return "Team name : " + this.name + "\n Team manager : " + this.theManager.getManager() + "\n Team players : \n" + list;
}
and finally the test class , so if you noticed you don't really need to put that loop inside the team constructor for player :
For test class(main) :
Manager A = new Manager("Flic");
Player P1 = new Player("Robert Levandowski",32,182);
Player P2 = new Player("David Alaba",32,179);
Player P3 = new Player("Joshoa Kimmich",23,175);
Player[] Aplayers = {P1,P2,P3};
Team B = new Team(A , Aplayers ,"FcBayern");
System.out.println(B.toString());
}
And I'm a barcelona fan by the way hahaha still want the revenge for that 8-2 have a great day !
I have a program I am working with to help me practice my coding skills. The program has the following scenario: there is a classroom of 20 students, where the record is taken of the students' names, surnames, and age. Half of these students take part in the school's athletics. Here, record is kept of their races that they have done and the ones they've won.
In this program, I have three classes:
runStudents - class with main method
Students (String name, String surname, int age) - parental class
AthleticStudents (String name, String surname, int age, int races, int victories) - sub class
The user should be able to add another race (and win) to the object. As seen by the code provided, an Array is created to store the 20 Students objects. I have to be able to access a method to alter the object in the array, but this method is not in the parental class (the class the objects are created from.
public class Students
{
private String name;
private String surname;
private int age;
public Students()
{
}
public Students(String name, String surname, int age)
{
this.name = name;
this.surname = surname;
this.age = age;
}
public String getName()
{
return this.name;
}
public String getSurname()
{
return this.surname;
}
public double getAge()
{
return this.age;
}
public void setName(String name)
{
this.name = name;
}
public void setSurname(String surname)
{
this.surname = surname;
}
public void setAge(int age)
{
this.age = age;
}
public String toString()
{
return String.format("name\t\t: %s\nsurname\t\t: %s\nage\t\t: %s",
this.name, this.surname, this.age);
}
}
public class AthleticStudents extends Students
{
private int races;
private int victories;
public AthleticStudents()
{
}
public AthleticStudents(String name, String surname, int age, int
races, int victories)
{
super(name, surname, age);
this.races = races;
this.victories = victories;
}
public int getRaces()
{
return this.races;
}
public int getVictories()
{
return this.victories;
}
public void setRaces(int races)
{
this.races = races;
}
public void setVictories(int victories)
{
this.victories = victories;
}
public void anotherRace()
{
this.races = this.races + 1;
}
public void anotherWin()
{
this.victories = this.victories + 1;
}
public String toString()
{
return super.toString() + String.format("\nnumber of races\t:
%s\nnumber of wins\t: %s", this.races, this.victories);
}
}
public class runStudents
{
public static void main(String[]args)
{
Students[] myStudents = new Students[20];
myStudents[0] = new Students("John", "Richards", 15);
myStudents[1] = new AthleticStudents("Eva", "Grey", 14, 3, 1);
myStudents[2] = new Students("Lena", "Brie", 15);
for (int i = 0; i < 3; i++)
System.out.println(myStudents[i].toString() + "\n\n");
}
}
I want to be able to do the following:
AthleticStudents[1].anotherRace();
but cannot do so as the array object is derived from the parental class, and I declared the method in the sub class. How can I link the two?
I assume that you create an array of the parent class instances. Just cast the instance this way (you better check whether the element is the instance of a subclass):
if (AthleticStudents[1] instanceof AthleticStudents)
((AthleticStudents) AthleticStudents[1]).anotherRace();
I'm not sure if this is exactly what you're looking for but it worked well for me. Instead of trying to access AthleticStudents method anotherRace() like that, try this in your main method.
Students[] myStudents = new Students[20];
myStudents[0] = new Students("John", "Richards", 15);
myStudents[1] = new AthleticStudents("Eva", "Grey", 14, 3, 1);
myStudents[2] = new Students("Lena", "Brie", 15);
AthleticStudents addRace= (AthleticStudents)myStudents[1];
addRace.anotherRace(); //This will increment Eva's race count to 4
for (int i = 0; i < 3; i++)
System.out.println(myStudents[i].toString() + "\n\n");
All I did was cast the element into an object AthleticStudents named 'addRace'. By casting myStudents[1] to this new object you are able to access all of AthleticStudents methods.
I just saw the other answer posted which works just as well!
Hope this helps!
I’m not sure that i understand your question, because you are a bit inconsistent with your capitalization. runStudents is a class, while AthleticStudents is both a class and an array. But i’ll try.
IF i did understand your question, you have an array Student[] studentArray. Some Student objects in studentArray are AthleticStudents, others are not. You have a specific AthleticStudent eva which is in studentArray[] having let’s say index 1, and you want to add to her anotherRace(). Your call studentArray[1].anotherRace does not compile because the compiler treats that element as a Student and not as a AthleticStudent.
The trick is to cast the element to AthleticStudent. I omit the test of the element of being really an AthleticStudent; you will have to do that test in your code.
((AthleticStudent) studentArray[1]).anotherRace();
I have been asked to create a class which simply prints "You have been registered".
In the second part, I am to create a test class. The test class should create two student instances (also called objects). Then to print their names and call the registered method of both of them. I keep getting errors saying 'the assignment to variable yearOfBirth has no effect' and in the test class 'The constructor String is undefined'.
Can you help with understanding the errors in my code.
public class Student{
//Attributes
private String name;
private String gender;
private int yearOfBirth;
//Constructors
public Student (String name, String gender, int yearOfBirth){
this.name = name;
this.gender = gender;
this.yearOfBirth = yearOfBirth; // Default age of new student
}
public Student (String name, String gender){
this.name = name;
this.gender = gender;
this.yearOfBirth = 0;
}
//Getters & Setters
public String getName() {
return name; }
public void setName (String name) {
this.name = name;
}
public String getGender () {
return gender;
}
public void setGender (String gender) {
this.gender = gender;
}
public int getYearOfBirth() {
return yearOfBirth;
}
public void setYearOfBirth() {
if(yearOfBirth >= 0 && yearOfBirth <= 100) {
this.yearOfBirth = yearOfBirth;
}else {
System.out.println("Age not valid");
}
}
// Other Methods
public void Registered() {
System.out.println(name + "You have been registered");
}
}
public class StudentTest {
public static void main(String[] args) {
Student student1 =new Student("Kevin Sanches", "male", "1972");
Student student2 = new Student("Cameron Young", "male", "1993");
student1.Registered();
student2.Registered();
System.out.println(student1);
System.out.println(student1);
}
}
There are two issues in your code:
The assignment to variable yearOfBirth has no effect. You are invoking a setter method on a property but you are not passing any value, hence the warning. You should provide a value as a parameter and set that to the corresponding object property.
The constructor problem is that the age parameter is of type int instead when you construct the objects you are passing the age as string.
Your constructor expects two strings and an integer as parameters. You are passing three strings.
Correct way:
Student student1 =new Student("Kevin Sanches", "male", 1972);
Student student2 = new Student("Cameron Young", "male", 1993);
Also, in your method setYearOfBirth you forgot to pass the yearOfBirth as parameter.
public void setYearOfBirth(int yearOfBirth) {
if(yearOfBirth >= 0 && yearOfBirth <= 100) {
this.yearOfBirth = yearOfBirth;
}else {
System.out.println("Age not valid");
}
}
You are trying to send 3 Strings which none of your constructors are ready to take. You have a constructor with 2 Strings and an int, so the correct way of creating the object would be,
Student student1 = new Student("Kevin Sanches", "male", 1972);
Without the double quotes 1972 would be an int.
You are assigning this.yearOfBirth to this.yearOfbirth in the setter. Even though code is just this.yearOfBirth = yearOfBirth; technically both are this.yearOfBirth variables.
This needs to change by accepting the value and assigning it like:
public void setYearOfBirth(int yearOfBirth) {
if(yearOfBirth >= 0 && yearOfBirth <= 100) {
this.yearOfBirth = yearOfBirth;
}else {
System.out.println("Age not valid");
}
}
You are trying to pass a String value to the constructor that accepts int for the yearOfBirth value, change it like:
Student student1 =new Student("Kevin Sanches", "male", 1972);
Student student2 = new Student("Cameron Young", "male", 1993);
class Human{
// declared instance variables
String name;
int age;
// instance method
void speak(){
System.out.println("My name is: " + name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return age;
}
String getName(){
return name;
}
// so when I create an instance, i can't have constructor?
// error here
Human(int age){
age = this.age;
}
}
}
public class GettersAndReturnValue {
public static void main(String[] args) {
// error here because I created a constructor Human(int a)
Human human1 = new Human();
human1.name = "Joe";
human1.age = 25;
human1.speak();
int years = human1.calculateYearsToRetirement();
System.out.println("Years till retirements " + years);
int age = human1.getAge();
System.out.println(age);
}
}
I tried to create a constructor Human(int age) to practice 'this' keyword and to change the age from 25 to something else but I get an error because I have one Human class and one Human constructor. When I try to create an instance of Human Type in my main method, eclipse is asking me to remove the constructor
You've swapped the order in your assignment,
Human(int age){
age = this.age;
}
should be something like (don't forget to initialize name too)
Human(int age){
this.age = age;
this.name = "Unknown";
}
You're assigning the default value 0 to the passed in parameter. If you provide a constructor then the compiler will no longer insert the default constructor,
Human() {
this.age = 0;
this.name = "Unknown";
}
and you might as well add a constructor that takes the name,
Human(int age, String name) {
this.age = age;
this.name = name;
}
then you could call it (in main) like
Human human1 = new Human(25, "Joe");
// human1.name = "Joe";
// human1.age = 25;
You have to create a no parameter constructor, because when you are calling Human h = new Human();, you are calling a no parameter constructor.
Try doing this instead:
Human h = new Human(age);
When you create a non-empty constructor, the empty constructor will not be available anymore. You do can have more than one constructor, but if you want the no-argument constructor along with other, you will have to recreate it.
//Please, make it public for constructors
public Human(int age){
this.age = age; //this.age first, to receive the parameter age
}
public Human() {} //Empty constructor. It doesn't has to be a content.
So you call:
Human humanOne = new Human(); //Using no-argument constructor
Human humanTwo = new Human(25); //Using constructor with int to set age
When you create a constructor in the class, it will no longer use the default constructor. In your code, you've created a public Human(int) constructor, so there is no default constructor. Because of that, you cannot create human object like this:
Human a = new Human();
To do that, you have to manually implement a no-argument Human constructor.
Here is a solution:
class Human{
String name;
int age;
//default constructor
public Human (){
}
//paramete constructor
public Human(int a){
this.age=a;
}
void speak(){
System.out.println("My name is: " + this.name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return this.age;
}
String getName(){
return this.name;
}
}
Here's the working code :
Create a class GettersAndReturnValue and add this. You need a empty constructor.
class Human{
// declared instance variables
String name;
int age;
// instance method
void speak(){
System.out.println("My name is: " + name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return age;
}
String getName(){
return name;
}
// so when I create an instance, i can't have constructor?
// error here
Human(int age){
this.age = age;
}
public Human() {
// TODO Auto-generated constructor stub
}
}
public class GettersAndReturnValue {
public static void main(String[] args) {
// error here because I created a constructor Human(int a)
Human human1 = new Human();
human1.name = "Joe";
human1.age = 25;
human1.speak();
int years = human1.calculateYearsToRetirement();
System.out.println("Years till retirements " + years);
int age = human1.getAge();
System.out.println(age);
}
}
Output :
My name is: Joe
Years till retirements 40
25
I have just started doing object oriented programming as part of my course, but I am struggling with it, specifically the toString method in a Person Class. I need to write a toString() method to display the contents of instance variables.
I need to by sample print out:
Person[forName=joe, surname= smith, age= 25, height= 1.57, gender= male]
I also need to format it like this using the format method:
smith joe 25 1.57 male
davis sian 18 1.73 female
*** *** *** *** ***
I havent written a tester yet, but here is what I have written so far for the class and now I'm stuck, I'm not even sure if I am getting the toString statement wrong. I am using netBeans for this:
public class Person
{
private String surname;
private String forname;
private int age;
private double height;
private String gender;
public String toString()
{
return getClass().getName() + "[surname= " + surname + " forname= " + forname + " age= " + age + " height= " + height + " gender " + gender + "]";
}
}
What I need to do is make a class called Person that I can test. It needs to be able to hold the five variables above (surname etc) for different people. I need to be able to print out each of the instance variables with a toString() method and to use a format() method to produce a string with formatting infomation in order for the string printed out by the toString() method to be formatted like the second quotation.
Am I on the right track and regardless, how can I work through this?
EDIT: I have looked at the Person Class and have done what I can with it, does it seem decent enough? I am going to try and get a PersonTester together.
public class Person
{
private String surName;
private String forName;
private int age;
private double height;
private String gender;
#Override
public String toString()
{
return getClass().getName() + "[surName= " + surName + " forName= " + forName + " age= " + age + " height= " + height + " gender " + gender + "]";
}
public void format()
{
System.out.format("%10s%10s%10d%10f%10s", "surName", "forName", age, height, "gender");
}
public String getSurName()
{
return surName;
}
public String getForName()
{
return forName;
}
public int getAge()
{
return age;
}
public double getHeight()
{
return height;
}
public String getGender()
{
return gender;
}
public void setSurName(String surName)
{
this.surName = surName;
}
public void setForName(String forName)
{
this.forName = surName;
}
public void setAge(int age)
{
this.age = age;
}
public void setHeight(double height)
{
this.height = height;
}
public void setGender(String height)
{
this.gender = gender;
}
}
EDIT 2: Started on a class Tester, but I am running into errors again about the setter's not having a ; and not being a statement.
Here's the tester so far:
public class PersonTester
{
public static void main(String[] args)
{
System.out.println("PersonClassTester");
System.out.println("*****************");
System.out.println("");
Person joeSmith = new Person();
String "smith" = joeSmith.setSurName();
String "joe" = joeSmith.setForName();
int 25 = joeSmith.setAge();
double 1.57 = joeSmith.setHeight();
String "male" = joeSmith.setGender();
joeSmith.toString();
joeSmith.format();
}
}
First of all you have to noticed that every object you create extends class Object. This Object class contains methods like toString, equals, hashCode...
your object have also this methods(inherited from Object). When you override (you should annotate this method with #Override) for eg. toString you will always use this toString method instead of inherited one. Its called polymorphism. Your toString method looks fine. In your main method you should use some kind of loop through all Persons and there format the output from toString method.
You have error in your code
public String toString(); {
remove the ; after ()
public class Main {
public static void main(String[] args) {
Person a = new Person("smith", "joe", 25, 1.57, "male");
Person b = new Person("davis", "sian", 18, 1.73, "female");
List<Person> persons = new ArrayList<Person>();
persons.add(a);
persons.add(b);
for(Person p : persons){
System.out.format("%s %s %s %d %.2f %s", p.getClass().getName(), p.getSurname(), p.getForname(), p.getAge(), p.getHeight(), p.getGender());
System.out.println();
}
}
}
If you call this
System.out.println(p.toString());
than you ll get your person via toString method.
I just edit your Person class and add constructor and geters + seters
public Person(String surname, String forname, int age, double height,
String gender) {
super();
this.surname = surname;
this.forname = forname;
this.age = age;
this.height = height;
this.gender = gender;
}
Here is geter and seter sample.
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
As already mentioned your toString() is fine.
Please note that the toString() method and the format() method are IMO supposed to work independently as they do serve different purposes.
I suggest to put the format method not in the person class (or at least make it static method). This is because a single Person instance has not enough information for it to be printed in the table format. It at least needs to know the column widths. Otherwise you could end up with something like this:
smith joe 25 1.57 male
someVeryLongFirstName sian 18 1.73 female
*** *** *** *** ***
So the format method should take a list of persons that should be printed out and then first calculate the column widths. After this is done you then just pad the property value to the column width and print this out.
You are on the right track:
Inside of the Person class you need to add public methods for each private variable to set the data:
public void setAge(int age) {
this.age = age;
}
Then you can create a Person object in your main class and set his age:
public class Main {
public static void main(String[] args) {
Person p = new Person();
p.setAge(15);
}
}
As an alternative, you can use a constructor inside of your Person class to set your object's variables:
public Person(String surname, int age) {
this.surname = surname;
this.age = age;
}
And create the object in the main method like this:
Person p = new Person("Nillas", 25);
You can always run your toString() method in the main class after you've created the object and see the result:
System.out.println(p.toString());
Hope this helps, good luck!