Setters, why won't this work? - java

I've been toying for hours, changing static, private, public etcetera :) But it still won't work. If I change static at one place, I get an error at another place etc.
I have a class called person. I've used NON-static Setters because the Person() constructor is also non-static.
public class Person {
private String name;
private String lastname;
private String nickname;
Person() {
this.name = "";
this.lastname = "";
this.nickname = "";
}
public void setName(String name) {
this.name = name;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
Then I have a file with my main method, and different methods for interacting with the user.This method is also static because it calls that methods that take the userInput which is using the Scanner class.
public class Interaction {
public static void takeName() {
String name;
String lastname;
String nickname;
System.out.println("What is your firstname:");
name = userInput(); // calls method with Scanner class
System.out.println("What is your lastname:");
lastname = userInput(); // calls method with Scanner class
System.out.println("What is your nickname:");
nickname = userInput();
person.setName(name);
person.setLastname(lastname);
person.setNickname(nickname);
}
//editor: missing closing bracket
What I've tried:
I've tried to dat Person.person.setname(name);
Declare the String in the public class Interaction, and then pass the String using this.name and call the method from the public class Interaction
tried to change static, private etc. etc.
Delete the constructor class Person() in Person class.
What am I missing here?
EDIT: I'VE ADDED SOME MORE INFO as you requested :)
My new Person object will be declared if it passes an if statement.
IF there is a place available then a new person will be created and added to this place.
public class Theater {
void reservationSystem () {
if (availability > 0) {
for (int i = 0; i < freespaces.length; i++) {
if (freespaces[i].person == null) {
freespaces[i].person = new Person();
break;
}
}
} else {
System.out.println("No tickets for you today :) ");
}
}
//editor: missing closing bracket
So my way of thinking is:
I fill a constructor with the data from the Userinput() using the Scanner class;
and THEN I create the new Person object so it has that data!
When I create a new Person in the reservation system, then the data in the constructor will be filled with data AGAIN but now with new data :)
If you need any more information please let me know :)

The first thing to note is that your Person constructor is a little useless, you can rewrite Person as such:
public class Person {
private String name = "";
private String lastname = "";
private String nickname = "";
public void setName(String name) {
this.name = name;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
Now onto your Interaction class. This needs to by public rather than Public but I assume that's a typo.
You need to have an instance of Person to call your setters on as they are instance methods. You need to somewhere call new Person().
The easiest way of writing your takeName() method is by creating a Person in the method and returning the instance:
public class Interaction {
public static Person takeName() {
final Person person = new Person();
System.out.println("What is your firstname:");
person.setName(userInput());
System.out.println("What is your lastname:");
person.setLastname(userInput());
System.out.println("What is your nickname:");
person.setNickname(userInput());
return person;
}
}

Your 'takeName()` function should update a single instance of the Person class.
One approach is to create the Person externally and pass it to the function:
Public class Interaction {
public static void takeName(Person person) {
String name;
String lastname;
String nickname;
System.out.println("What is your firstname:");
name = userInput(); // calls method with Scanner class
System.out.println("What is your lastname:");
lastname = userInput(); // calls method with Scanner class
System.out.println("What is your nickname:");
nickname = userInput();
person.setName(name);
person.setLastname(lastname);
person.setNickname(nickname);
}
}
But I think it would be more intuitive to create the person instance inside the function and return it:
Public class Interaction {
public static Person takeName() {
String name;
String lastname;
String nickname;
Person person = new Person();
System.out.println("What is your firstname:");
name = userInput(); // calls method with Scanner class
System.out.println("What is your lastname:");
lastname = userInput(); // calls method with Scanner class
System.out.println("What is your nickname:");
nickname = userInput();
person.setName(name);
person.setLastname(lastname);
person.setNickname(nickname);
return person;
}
}

Because this is not valid syntax: Person.person.setname(name);
What this would mean in this context is:
get class named Person
get static field of Person class named person
find and invoke instance methid setname with argument name
But your Person class - appropriately - does not have a static field named person...
The root cause of your issues is most likely not being entirely familiar with the concept of classes, instances, and in connection, the meaning of static and instance members and methods...
Static always means the referenced part is connected with the class.
Whereas an instance variable or method (e.g. everything non-static) is connected to the instances of said classes.

Related

trying to call superclass method in subclass

Probably a pretty noob question, but I cant figure it out. I have a class Person to store a name that is input from the keyboard
public class Person {
private String firstName;
private String lastName;
public Person()
{
firstName = "";
lastName = "";
}
public Person(String first, String last)
{
setName(first, last);
}
public String toString()
{
return(firstName + " " + lastName);
}
public void setName(String first, String last)
{
firstName = first;
lastName = last;
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
}
I am trying to call the toString method in a subclass called Patient
public class Patient extends Person {
private int patientID, patientAge;
public Patient()
{
patientID = 0; //for a different part of the class that works
patientAge = 0;
}
#Override
public String toString()
{
return ("Patient Name: "+super.toString());
}
}
I cannot get it to output the name in main when I call the toString method from the Patient class, but when I tested it, it output the name when I call the toString method from the Person class.
The method call in main looks like Patient pnt = new Patient(); System.out.print(Pnt.toString());
it prints out in the console "Patient Name: ". Any feedback on what I am doing wrong or ideas on how to get it to work
Here:
public Person()
{
firstName = "";
lastName = "";
}
Your subclass is missing a reasonable call to a super class constructor. So when you instantiate your Patient objects, the above constructor is used, and all patients end up with "" as first and last name!
When you create a Patient, then a patient should have a name, too! But your constructor in Patient only sets the Patient related fields. And implicitly, the default super constructor is called. Therefore the Person fields are all set to be empty strings!
A much better approach would look like this:
class Person {
private final String firstName;
... lastName
public Person(String firstName, String lastName) {
this.firstName = firstName;
...
and then
class Patient extends Person {
private final int patientID;
public Patient(int patientID, String firstName, String lastName) {
super(firstName, lastName);
this.patientID = patientID;
)
Why is that better: names and IDs don't change (normally). There is no point in having getters for them. You create your object once, and then that data is fixed! There is also no point in having that default constructor in Person. A person with empty names doesn't make sense. Thus: don't create a class that allows you to create "invalid" objects. Your classes model reality. There are no real people without names!
And one other hint: use #Override when overriding methods, so that the compiler can tell you when you get something wrong!
if the problem is to output the name in main when you call the toString method from the Patient class, I think the code bellow will help you.
have you tried to construct the Patient object like this?
public static void main(String[] args) {
Patient p = new Patient();
System.out.println(p.toString());
}
Actually I do not see problem in your code.
Person person = new Person();
person.setName("aa", "bb");
System.out.println(person); // aa bb
Patient patient = new Patient();
patient.setName("cc", "dd");
System.out.println(patient); // Patient Name: cc dd
I think that you set name wrong pr use not correct reference. Check it.
You don't have any constructor for your PATIENT subclass. You don't set any firstName or lastName to any patient.
To keep familiar constructor as you used in your parent class, tru to use:
public Patient() {
super("default_firstName", "default_lastName");
this.patientID = 0;
this.patientAge = 0;
}
public Patient(String firstName, String lastName, int patientAge) {
super(firstName, lastName);
this.patientID = 0; //can be implemented some method for automatically setting numbers
this.patientAge = patientAge;
}
This way you always get firstName and lastName even if constructor will be called empty.
According to you toString method, it's correct and it call super class method:
#Override
public String toString()
{
return("Patient name is "+super.toString());
}
But notice that you return STRING value so to make it visible on the screen remember to use:
System.out.println(patient.toString());
Then it will be visible :)
I have added some comments and code in your Person class that should fix your issues.
public class Person {
private String firstName; //store the first name
private String lastName; //sore the last name
//initialize firstName and lastName to an empty string
public Person() {
firstName = "";
lastName = "";
}
//set firstname and lastname according to the parameters.
public Person(String first, String last) {
//setName(first, last); remove this crap.
// Use the contructor properly when initialize your person object. Like this:
this.firstName = first;
this.lastName = last;
}
//method to output the first name and last name
#Override
public String toString() {
return (firstName + " " + lastName);
}
//method to set firstName and lastName according to the paramters
public void setName(String first, String last) {
//
firstName = first;
lastName = last;
}
}

How to display in one line that have many behavior in LinkedList

Our prof gave us an activity about creating a linked list with another class that has attributes or behavior of last name, first name, age, course, etc.
So my question is if I set a cumulative setter with the following given attributes. if I add it to the linked list will the linked list itself will create one list only with the given attributes? and thus if I search it in the list will the linked list need those attributes to be able to search it?
Here's my code for the class with attributes/behavior. I minimized it only with a little attributes so that it is better to correct it:
class Student2 {
public String lastName;
public String firstName;
public Student2() {
}
public void setlastName(String lastName) {
this.lastName = lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public void setInfo() {
Scanner in = new Scanner(System.in);
System.out.println("Enter your LastName here:");
setlastName(in.nextLine());
System.out.println("Enter your FirstName here:");
setFirstName(in.nextLine());
}
}
Here's the code of the main method in which the class with attributes will be called. The menu method will ask the user if he/she wants to add a student or search a student on the list :
public class Project {
public static LinkedList<Student2> list = new LinkedList<Student2>();
public static Student2 info = new Student2();
public static void main(String args[]) {
menu();
}
public static void insert() {
info.setInfo();
list.add(info);
System.out.println("Student added!");
}
public static void search() {
Scanner in = new Scanner(System.in);
System.out.println("Enter the LastName:");
String lastname = in.nextLine();
System.out.println("Enter the FirstName:");
String firstname = in.nextLine();
boolean found = false;
for (Student2 student2 : list) {
if (lastname.equals(student2.lastName) && firstname.equals(student2.firstName)) {
found = true;
break;
}
}
if (found) {
System.out.println(lastname + " found ");
} else {
System.out.println(lastname + " not found ");
}
}
}
No linkedlist will be generic and independent of any behavior. As list doesn't have any information about what object it is going to hold (that is the whole purpose of abstraction). Today, it is student; tomorrow it could be car or burger.
It seems that you don't get the base differences between the classes you are using.
First of all, classes are a model that somehow represent the "real" things you want to work with.
Coming from there: a list is nothing but a generic container of elements. Like a suitcase. You can put many different things into that suitcase, and it doesn't matter (to the suitcase), if you put one shoe into it, or two gloves. It is just a container. And to the contrary: the specifics of the elements in that container should not matter at all to the container.

Initialize each element of the array with Student objects

public class Student {
int marks;
String name;
char sex;
String email;
}
Student[] s = new Student[10];
public class StudentDemo {
Student s[] = new Student[10];// array Student//
Student s1 = new Student();// Student Object//
s1.setName("John"); //Eclipse says here there is a mistake an ask to delete John//
Student[0]=s1;
}
I have created a Student class with name and other attributes. But now I want to initialize each element of the array with Student objects. Is this code right? Eclipse throws a lot of red dots.
Help.
class Student {
int marks;
String name;
char sex;
String email;
public void setName(String string)
{
// TODO Auto-generated method stub
}
}
public class StudentDemo{
public static void main(String [] args)
{
Student s[] = new Student[10];// array Student//
Student s1 = new Student();// Student Object//
s1.setName("John"); //Eclipse says here there is a mistake an ask to delete John//
s[0]=s1;
}
}
Try this.
Problems in your code:
You wrote your function logic outside of function. Corrected in my
code using main method.
You can't have 2 public classes in a class file. So i made Student file as non-public.
You din't have setter for name property of Student.
Well you never defined a setName method so I am assuming thats why you got the compiler error. Something like this should work inside the Student class
public String setName(String name){
this.name = name;
}
use the reference of the array you created instead of the type of array
Thus, replace Student[0] with s[0]
A lot is wrong with your code.
It should be
Student[] s = new Student[10];
s[0] = new Student();
s[0].setName();
You need to also write your code inside a method. Like so:
public void doStuffHere()
{
// Code goes here.
}
Notice I use that fact that at position 0 there is a Student object and then I just set the name. There is no real reason to use s1.
A few things:
First of all, your first array should be written like this:
Student[] s = new Student[10];
Secondly, you never defined the method setName(String name) in your Student class. This would look something like this:
public void setName(String name)
{
this.name = name;
}
On top of that, you can't just call the method in the class, it needs to go inside a method, constructor, or initialisation block.
For example:
public class StudentDemo
{
Student[] studentArray = initStudentArray();
private Student[] initStudentArray()
{
Student[] ret = new Student[10];
Student s = new Student();
s.setName("John");
ret[0] = s;
...
return ret;
}
}
This can help you.
class Student {
int marks;
String name;
char sex;
String email;
void setName(String name){
this.name = name; //this.name represents the current instance non-static variable
}
public String toString(){ //Overridden Objectclass method for string representation of data
return " Student Name: "+name+
"\n Gender: "+sex+
"\n Email: "+email+
"\n Marks: "+marks;
}
}
public class StudentDemo {
public static void main(String[] args){
Student s[] = new Student[10];
s[0] = new Student();
s[0].setName("John"); //similarly u can set values to other attributes of this object
System.out.println(s[0]); // same as s[0].toString() its an implicit call
}
}

String Array object in Java

I am trying to print the first element on the two arrays in my Athlete class, country and name. I also need to create a object that simulates three dive attemps an athlete had (that is initially set to zero). I am new to OOP and I dont know how to go abouts doing this in my main... as far as constructors go. This is what i have done so far...
this is the main:
import java.util.Random;
import java.util.List;
public class Assignment1 {
public static void main(String[] args) {
Athlete art = new Athlete(name[0], country[0], performance[0]);
}
}
I just really am not sure what to do...
And this is the class with the arrays.
import java.util.Random;
import java.util.List;
public class Athlete {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germant", "USA"};
//Here i would like to create something that would be representing 3 dive attemps (that relate to dive and score. eventually.)
Athlete(String[] name, String[] country, Performance[] performance) {
this.name = name;
this.country=country;
this.performance=performance;
}
public Performance Perform(Dive dive){
dive.getDiveName();
return null;
}
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
public String[] getCountry() {
return country;
}
public void setCountry(String[] country) {
this.country = country;
}
}
thanks in advance for any help and input!
btw there is other classes too, just not relevant atm..
First, as for your Athlete class, you can remove your Getter and Setter methods since you have declared your instance variables with an access modifier of public. You can access the variables via <ClassName>.<variableName>.
However, if you really want to use that Getter and Setter, change the public modifier to private instead.
Second, for the constructor, you're trying to do a simple technique called shadowing. Shadowing is when you have a method having a parameter with the same name as the declared variable. This is an example of shadowing:
----------Shadowing sample----------
You have the following class:
public String name;
public Person(String name){
this.name = name; // This is Shadowing
}
In your main method for example, you instantiate the Person class as follow:
Person person = new Person("theolc");
Variable name will be equal to "theolc".
----------End of shadowing----------
Let's go back to your question, if you just want to print the first element with your current code, you may remove the Getter and Setter. Remove your parameters on your constructor.
public class Athlete {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germany", "USA"};
public Athlete() {
}
In your main method, you could do this.
public static void main(String[] args) {
Athlete art = new Athlete();
System.out.println(art.name[0]);
System.out.println(art.country[0]);
}
}
Currently you can't access the arrays named name and country, because they are member variables of your Athelete class.
Based on what it looks like you're trying to do, this will not work.
These arrays belong in your main class.
Your attempt at an athlete class seems to be dealing with a group of athletes, which is a design fault.
Define a class to represent a single athlete, with fields that represent the athlete's attributes:
public class Athlete {
private final String name;
private final String country;
private List<Performance> performances = new ArrayList<Performance>();
// other fields as required
public Athlete (String name, String country) {
this.name = name;
this.country = country;
}
// getters omitted
public List<Performance> getPerformances() {
return performances;
}
public Performance perform(Dive dive) {
// not sure what your intention is here, but something like this:
Performance p = new Performance(dive, this);
// add new performance to list
performances.add(p);
return p;
}
}
Then your main method would use ti like this:
public class Assignment1 {
public static void main(String[] args) {
String[] name = {"Art", "Dan", "Jen"};
String[] country = {"Canada", "Germant", "USA"};
Dive[] dive = new Dive[]{new Dive("somersault"), new Dive("foo"), new Dive("bar")};
for (int i = 0; i < name.length; i++) {
Athlete athlete = new Athlete(name[i], country[i]);
Performance performance = athlete.perform(dive[i]);
// do something with athlete and/or performance
}
}
}
I think you are a little messed up with what you doing.
Athlete is an object, athlete has a name, i has a city where he lives.
Athlete can dive.
public class Athlete {
private String name;
private String city;
public Athlete (String name, String city){
this.name = name;
this.city = city;
}
--create method dive, (i am not sure what exactly i has to do)
public void dive (){}
}
public class Main{
public static void main (String [] args){
String name = in.next(); //enter name from keyboad
String city = in.next(); //enter city form keybord
--create a new object athlete and pass paramenters name and city into the object
Athlete a = new Athlete (name, city);
}
}
public static void main(String[] args) {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germant", "USA"};
// initialize your performance array here too.
//Your constructor takes arrays as an argument so you need to be sure to pass in the arrays and not just objects.
Athlete art = new Athlete(name, country, performance);
}
First off, the arrays are pointless, let's get rid of them: all they are doing is providing values for mock data. How you construct mock objects has been debated ad nauseum, but clearly, the code to create the fake Athletes should be inside of a unit test. I would use Joshua Bloch's static builder for the Athlete class, but you only have two attributes right now, so just pass those in a Constructor. Would look like this:
class Athlete {
private String name;
private String country;
private List<Dive> dives;
public Athlete(String name, String country){
this.name = name;
this.country = country;
}
public String getName(){
return this.name;
}
public String getCountry(){
return this.country;
}
public String getDives(){
return this.dives;
}
public void addDive(Dive dive){
this.dives.add(dive);
}
}
Then for the Dive class:
class Dive {
private Athlete athlete;
private Date date;
private double score;
public Dive(Athlete athlete, double score){
this.athlete = athlete;
this.score = score;
this.date = new Date();
}
public Athlete getAthlete(){
return this.athlete;
}
public Athlete getAthlete(){
return this.athlete;
}
public Athlete getAthlete(){
return this.athlete;
}
}
Then make a unit test and just construct the classes, and manipulate them, make sure that they are working. Right now they don't do anything so all you could do is assert that they are retaining the Dives that you are putting in them. Example:
#Test
public void testThatDivesRetainInformation(){
Athlete art = new Athlete("Art", "Canada");
Dive art1 = new Dive(art, 8.5);
Dive art2 = new Dive(art, 8.0);
Dive art3 = new Dive(art, 8.8);
Dive art4 = new Dive(art, 9.2);
assertThat(art.getDives().size(), is(5));
}
Then you could go through and add tests for things like, making sure that you can't construct a dive without an athlete, etc.
You could move construction of the athletes into the setup method of the test so you could use it all over the place. Most IDEs have support for doing that with a refactoring.

Calling a non-static method in a seperate class to a main program

I have a Java program where I have a main class and another class called Person (that makes a 'person' class) with 2 methods. The methods are non-static and are called getName and getAge that stores this info a person element of an ArrayList.
How do I call these in the main program? I know I have to declare an instance of the class but I'm still not sure how to actually do it.
Considering Person a Class with 2 methods:
public class Person{
private String mName;
private int mAge;
public Person(String name, String age){
this.mName = name;
this.mAge = age;
}
//If you want this class to be Immutable please remove the setter methods()//
public void setName(String name){
this.mName = name;
}
public void setAge(String age){
this.mAge = age;
}
public String getName(){
return this.mName ;
}
public String getAge(){
return this.mAge ;
}
}
The Class containing main() method:
public class TestMain{
public static ArrayList<Person> aList = new ArrayList<Person>();
public static void main(String[] args){
Person person1 = new Person("Vivek",26);
Person person2 = new Person("Vicky",27);
aList.add(person1);
aList.add(person2);
}
}
In your main code you can do something like:
Person p = new Person();
p.setName("Jericho Jones");
p.setAge(153);
Of course, it's impossible to tell exactly without seeing the Person class.
You need to instantiate an object for this class.
Person p = new Person();
p.getName()....

Categories