Why does this output wrong (get/set methods) - java

Just going through get/set methods and I'm having trouble with my output. Instead of displaying the First/Last name of the object it is displaying null/null.
Could anyone offer any insight, i'm not familiar with get/set methods.
Code
public class Person {
private String firstName;
private String lastName;
public Person (String a, String b){
a = firstName;
b = lastName;
}
public String getfirstName(){
return firstName;
}
public void setfirstName(){
this.firstName = firstName;
}
public String getlastName(){
return lastName;
}
public void setlastName(){
this.lastName = lastName;
}
public String toString() {
String s = "First name:" + firstName + "Last name:" + lastName;
return s;
}
}
This is my class just to create the object and run to toString method
public class PersonDriver {
public static void main(String[]args){
Person p1 = new Person ("Thomas", "Brown");
System.out.print(p1.toString());
}
}

You need to assign the parameters to the instance variables and not the reverse. What you're doing currently is reassigning a and b which were passed to the constructor, whereas you need to assign the values of a and b to the firstName and lastname fields of the class.
public Person (String a, String b){
firstName = a;
lastName = b;
}

You inverted the variables within your constructor
You need Change below code
public Person (String a, String b){
a = firstName;
b = lastName;
}
to
public Person (String a, String b){
firstName = a;
lastName = b;
}

Primarily setters has to be
public void setFirstName(String firstName){
this.firstName = firstName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}

Your setters should take an argument - the value to be set. Your constructor should assing the values of the arguments to the class properties not the other way round.

I think the constructor has to be like
public Person (String a, String b){
firstName = a;
lastName = b;
}

You need to swap the variabels. You assign the value of the object the parameters.
public Person (String a, String b){
firstName= a;
lastName= b;
}
Also your set method are useless without parameters :
public void setlastName(String parameter){
this.lastName = parameter;
}

You sure your methods shouldn't be more in line with this?
public class Person {
private String firstName;
private String lastName;
public Person (String a, String b){
firstName=a;
lastName=b;
}
public String getfirstName(){
return firstName;
}
public void setfirstName(String firstName){
this.firstName = firstName;
}
public String getlastName(){
return lastName;
}
public void setlastName(String lastName){
this.lastName = lastName;
}
public String toString() {
String s = "First name:" + firstName + "Last name:" + lastName;
return s;
}
}
You need to pass the setter methods the values you would want to set the variables to. Apart from that, like the others mentioned, you swapped the variable names in the constructor. :)

Related

How to create objects for parameterized constructors in Java, when we have two classes with the same attributes?

I have class Student, that has first name, last name and age, and a method to print the name and the age of the student.
public class Student {
private String firstName;
private String LastName;
private int age;
}
Student() {}
public Student(String firstName, String lastName, int age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void printInfoStudent(){
System.out.println("Student: " + firstName + " " + lastName + ", " + age);
}
And I have a second class Professor, that has first name, last name, and university. And I have a method to print the info about the professor.
public class Professor {
private Student firstName;
private Student lastName;
private String uni;
}
Professor() {
}
public Professor(Student firstName, Student lastName, String uni) {
this.firstName = firstName;
this.lastName = lastName;
this.uni = uni;
}
public Student getFirstName() {
return firstName;
}
public void setFirstName(Student firstName) {
this.firstName = firstName;
}
public Student getLastName() {
return lastName;
}
public void setLastName(Student lastName) {
this.lastName = lastName;
}
public String getUni() {
return uni;
}
public void setUni(String uni) {
this.uni = uni;
}
public void printInfo(){
System.out.println("Professor: " + firstName + " " + lastName + ", uni: " + university);
}
And in the main class I create two objects.
Student s = new Student("John", "John", 24);
Professor p = new Professor("Johnny", "Johnny", "Oxford");
printInfo.p();
printInfoStudent.s();
And it's showing me an error: String cannot be converted to Student, can someone explain why is that, and how should I fix this?
You've created the objects properly but are not calling their functions properly.
Student s = new Student("John", "John", 24);
Professor p = new Professor("Johnny", "Johnny", "Oxford");
p.printInfo()
s.printInfoStudent();
You need to name the instance first then specify the method inside to call after the dot.

Got stuck at step 4

Create a Student Class with the following instance variables:
-LastName
-MatNo
-Age
-GPA e.g A+, B-```
Create a Constructor that takes all the instance variables (class fields) as input parameters.
Create Accessor(Getter) and Mutator (Setter) methods for each of the instance variables.
Create a method called calAge that returns the age of a student based on yearofBirth as input parameter.
Create a Tester Program to test the Student class. Do the following:
-Calculate the age of each student object created based on the calAge method.
-Change the GPA of each student by calling the Mutator method of GPA.
-Make sure data about each of the students is printed to the Console.```
My code so far:
package ict;
public class Student {
private String firstName;
private String lastName;
private int mattNo;
private int age;
private String gpa;
public Student(String first, String last, int matt, int ag, String gp)
{
setFirstName(first);
setLastName(last);
setMattNo(matt);
setAge(ag);
setGpa(gp);
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getMattNo() {
return mattNo;
}
public void setMattNo(int mattNo) {
this.mattNo = mattNo;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGpa() {
return gpa;
}
public void setGpa(String gpa) {
this.gpa = gpa;
}
}
Create a method called calAge that returns the age of a student based
on yearofBirth as input parameter.
int calAge (int yearofBirth) {
Year y = Year.now();
return y.getValue () - yearOfBirth;
}
now this does not seem to be a very good way, I think you need to consider the month and day that you were born.
also consider to make this method static

Best practices for assigning values passed through constructor - JAVA

What is the quickest/most elegant way to assign values that were passed through a constructor?
For example, if I have the class below:
public MyClass {
private String firstName;
private String middleName;
private String lastName;
private int age;
private int birthDay;
private int birthMonth;
private int birthYear;
public MyClass(String firstName, String middleName, String lastName,
int age, int birthDay, int birthMonth, int birthYear) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
this.age = age;
this.birthDay = birthDay;
this.birthMonth = birthMonth;
this.birthYear = birthYear;
}
}
Is this really the best way to assign all the values to the class? It seems very bloated and redundant.
Is there any other method available to cut down the redundancy?
The way you're doing it is just fine. Think of the following:
By initializing/setting variables through a constructor (or really any method) you can do additional validation on the values passed through.
You can e.g. check if the birthMonth parameter is a number between 1 and 12 and throw an IllegalArgumentException if it is not. Or you can check that firstName does actually contain something and is not just "" (an empty string).
There is no cleaner or quicker way to do it.
You need to specify what field you assign what value to. In the language standard there is no definition of how fields are internally ordered, each JVM implementation could do it differently, so without using an absolute identifier you can't reliably assign parameters to values.
Parameter names are not stored in the java bytecode, thus you cannot assign parameter values from a constructor automagically to fields. You can circumvent this by, e.g., creating setters for each field that adhere to a naming convention you define. But now you can't use a simple constructor anymore and the whole thing is blowing out of proportion...
I think the problem here is not so much the assignments as the number of distinct fields that this class has to manage. It looks to me like we're managing a name and a date - each of these can be a single instance of a class, a Name class that you whip up for yourself and a java.util.Date (or something fancier if you need something fancier).
age is a straightforward calculation from the birthdate and today's date and can be omitted.
Doing this will allow you to push some complexity - managing the printing of names, doing calendar arithmetic - down into classes which can and should specialize in those specific problems.
Best practice to don't have such big classes and split them to few smaller. Having constructor that receives more than 3-4 arguments it's the sign that you need to do something with that class. It's very similar to this principle https://en.wikipedia.org/wiki/Interface_segregation_principle
public MyClass {
private Person person;
public MyClass(Person person) {
this.person = person;
}
}
//when this class will receive more parameters you could
// be extract name, surname, etc. to Name class
class Person {
private String name;
private String middleName;
private String lastName;
private Date birthDay;
//constructor
Date getAge() {
Date today = new Date();
return today.difference(birthDay); //something like that
}
}
class Date {
private int birthDay;
private int birthMonth;
private int birthYear;
//constructor
}
It's a good practice passing values in this way. You can take a look to que Oracle docs it have several examples about to pass values to constructor.
And by doing on this way you can validate, convert or whatever you need to do with the information that you send to constructor.
Applying the Builder Pattern can be used as an alternative to the telescoping constructor problem.
public class MyClassBuilder {
private MyClass myClass;
public MyClassBuilder() {
myClass = new MyClass();
}
public MyClassBuilder setFirstName(String firstName) {
myClass.setFirstName(firstName);
return this;
}
public MyClassBuilder setMiddleName(String middleName) {
myClass.setMiddleName(middleName);
return this;
}
public MyClassBuilder setLastName(String lastName) {
myClass.setLastName(lastName);
return this;
}
public MyClassBuilder setAge(int age) {
myClass.setAge(age);
return this;
}
public MyClassBuilder setBirthDay(int birthDay) {
myClass.setBirthDay(birthDay);
return this;
}
public MyClassBuilder setBirthMonth(int birthMonth) {
myClass.setBirthMonth(birthMonth);
return this;
}
public MyClassBuilder setBirthYear(int birthYear) {
myClass.setBirthYear(birthYear);
return this;
}
public MyClass build() {
return myClass;
}
}
Your class would then provide setters for each of the fields, instead of requiring them in the constructor.
public class MyClass {
private String firstName;
private String middleName;
private String lastName;
private int age;
private int birthDay;
private int birthMonth;
private int birthYear;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setAge(int age) {
this.age = age;
}
public void setBirthDay(int birthDay) {
this.birthDay = birthDay;
}
public void setBirthMonth(int birthMonth) {
this.birthMonth = birthMonth;
}
public void setBirthYear(int birthYear) {
this.birthYear = birthYear;
}
}

Overloaded constructors in a class

I'm doing a project with overloaded constructors in a class and I'm a little stuck, below is what I'm supposed to be doing with the overloaded constructors:
"One that allows first, middle, and last names to be passed as Strings with an int for age
One that accepts a Name object reference, and an age as an int
Make a new Name inside Person, copying the references for the parts of the name."
I'm not quite sure what to do with my code, here is what I got:
public class Person {
int age;
Name aPersonHasAName;
Name newPerson = new Name();
public Person(String firstName, String middleName, String lastName, int age) {
newPerson.firstName = firstName;
newPerson.middleName = middleName;
newPerson.lastName = lastName;
}
public Person(Name aPersonHasAName, int age) {
}
public void details() {
System.out.println(aPersonHasAName + " age: " + age);
}
}
I'm just lost as to what I'm supposed to be typing. I believe I've done the first overloaded constructor, but I am new to this.
So what should I be doing to make this work with overloaded constructors?
I think having the code from the other two classes might help.
Here is PersonTester:
public class PersonTester {
public static void main(String[] args) {
Person person1 = new Person("a1", "b1", "c1", 11);
Person person2 = new Person(new Name("a2", "b2", "c2"), 22);
Person person3 = new Person(new Name("a3", "c3"), 33);
Person person4 = new Person(new Name("a4"), 44);
Person person5 = new Person(new Name(), 55);
System.out.println(person1.details());
System.out.println(person2.details());
System.out.println(person3.details());
System.out.println(person4.details());
System.out.println(person5.details());
}
}
Then here is the Name class:
public class Name {
String firstName;
String middleName;
String lastName;
public Name(String firstName, String middleName, String lastName) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
}
public Name(String firstName, String lastName) {
this(firstName, "", lastName);
}
public Name(String firstName) {
this(firstName, "", "");
}
public Name() {
this("", "", "");
}
public String getLastName() {
return lastName;
}
public String getMiddleName() {
return middleName;
}
public String getFirstName() {
return firstName;
}
public String getFullName(String nameString) {
StringBuilder build = new StringBuilder();
build.append(nameString);
build.deleteCharAt(nameString.length() - 1);
build.insert(0, build.hashCode());
return build.toString();
}
}
The problem I am having now is the error message in PersonTester which is: The method println(boolean) in the type PrintStream is not applicable for the arguments (void)
I just need to know what in which class needs to be fixed to make it work.
I am very new to Java and object oriented programming.
So far so good. But eventually you'll reach a point where you duplicate a fair bit of code.
The constructor
public Person(String firstName, String middleName, String lastName, int age) {
is the most comprehensive one in the sense that it takes in all the possible data.
With the other constructors, say one that takes a last name and an age, you can use delegating constructors:
public Person(String lastName, int age) {
this(null, null, lastName, age); /*calls the other constructor*/
}
If you can't make such an assumption then you'll need to split up the name string by hand.
Updating your code:
public Person(String firstName, String middleName, String lastName, int age) {
newPerson.firstName = firstName;
newPerson.middleName =
newPerson.lastName = lastName;
this.age = age; //<---- was missing in your code
}
And your second contructor may look like this:
public Person(Name aPersonHasAName, int age) {
this.newPerson = aPersonHasAName;
this.age = age;
}
These contructors are implemented as you needed.
Notice that you already done your overloading, if you got multiple constructors with not the same titles you contructors overloading
public class Person {
int age;
Name aPersonHasAName;
public Person(String firstName, String middleName, String lastName, int age) {
aPersonHasAName = new Name();
aPersonHasAName.firstName = firstName;
aPersonHasAName.middleName = middleName;
aPersonHasAName.lastName = lastName;
this.age = age;
}
public Person(Name aPersonHasAName, int age) {
this.aPersonHasAName = aPersonHasAName;
this.age = age;
}
public void details() {
System.out.println(aPersonHasAName + " age: " + age);
}
}
I guess it also depends on if Name has a constructor for firstName, middleName, lastName

Newbie need help understanding java code

I'm very new to the java programming language and I would really like some help understanding what the following code is doing. I have a pretty decent understanding of what is going on within the Main class. My problem is what part "this._" plays within the code. How exactly are the names getting transferred? This is not homework just self study. The exercise can be found here:http://www.learnjavaonline.org/Functions Also, suggested reading would be great! Thanks!
class Student {
private String firstName;
private String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void printFullName(){
System.out.println(this.firstName+" "+this.lastname);
}
}
public class Main {
public static void main(String[] args) {
Student[] students = new Student[] {
new Student("Morgan", "Freeman"),
new Student("Brad", "Pitt"),
new Student("Kevin", "Spacey"),
};
for (Student s : students) {
s.printFullName();
}
}
}
this references to the object your is working in.
so in your sample
class Student {
private String firstName;
private String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void printFullName(){
System.out.println(this.firstName+" "+this.lastname);
}
}
this.firstName is the private String firstName; value in your object/class
and firstName is the method parameter.
the this is required in this example as it otherwise would be firstName = firstName and that would assign the value of your parameter to itself.
The reason this is used is because the variables firstName and lastName are shadowed by the constructor parameters. See the differences with this:
class Student {
private String firstName;
private String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Compared to without this:
class Student {
private String myFirstName;
private String myLastName;
public Student(String firstName, String lastName) {
myFirstName = firstName;
myLastName = lastName;
}
You use this to reference variables in the current object.
See that variables with "this" are in constructor. This means THE OBJECT, so in the lines:
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
you assing variable to your object. Remember that these variables are in constructor !

Categories