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
Related
Having some problems trying to call a method from a class.
Have my main method below
private static boolean findStudentId() {
System.out.println("Please enter your student ID to search for your profile");
int searchId = scanner.nextInt();
//need to be able to find a student's profile from the arraylist by searching their ID
return false;
}
I am trying to call a method from another class and cannot do so. this is my other class I am trying to call
public boolean findStudent(int id) {
for(int i = 0; i< students.size();i++)
{
if (students.equals(id)) {
System.out.println("Found the profile containing information for " + id);
// System.out.println(id.getFirstName()+id.getFirstName()+id.getLastName()+id.getDob());
return true;
} else
System.out.println("Could not find a profile based on the ID you provided");
}
return false;
}
this is my student class that I have created that proclaims the students
public class Student {
private int id;
private String firstName;
private String lastName;
private String dob;
public Student(int id,String firstName, String lastName, String dob) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.dob = dob;
}
public int getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getDob() {
return dob;
}
public static Student createStudentID(int id,String firstName, String lastName, String dob)
{
return new Student(id,firstName, lastName, dob);
}
}
I suggest to add a new class and put all the methods that you are going to be using in that class then in the main class create an object and you could easily use that methods with no problem
+small note the condition in findStudent method should be like
if (students.get(i).id == id)
so it would search for the id in the arraylist
If you want to call a method from another class you can for example create an object of the class you are trying to get the method from. For instance...
If the method you have is located inside of Class A, then create an object of that class.
A classAttribute = new A();
Then to call the method use....
classAttribite.someMethod();
So let say I have a Person class which is the super class--> looks something like this:
public class Person {
private String firstName;
private String lastName;
private String adhaarID;
private int employeeID;
public Person(String firstName, String lastName, String adhaarID, int employeeID) {
this.firstName = firstName;
this.lastName = lastName;
this.adhaarID = adhaarID;
this.employeeID = employeeID;
}
public Person() {
}
public String getFullName()
{
return firstName+" "+lastName;
}
public String getFirstName()
{
return firstName;
}
public String getAdhaarID() {
return adhaarID;
}
public String getLastName()
{
return lastName;
}
public int getEmployeeID() {
return employeeID;
}
}
And I have a sub class Employee which extend class Person and have no new method (other than what Class Person already have). In the worst case it gonna have all the methods that class Person have.
In all its method the class Employee calls its super methods:---> looks something like this:
public class Employee extends Person {
public Employee(String firstName, String lastName, String adhaarID, int employeeID) {
super(firstName, lastName, adhaarID, employeeID);
}
public String getFullName() {
return super.getFullName();
}
public String getAdhaarID() {
return super.getAdhaarID();
}
public String getLastName() {
return super.getLastName();
}
public int getEmployeeID() {
return super.getEmployeeID();
}
}
Now I am traversing through all the method of Class Employee through java Reflection.
and I have Class Person object named person.
I am passing that object to invoke the method. Like lets say getAdhaarID of Employee class is invoke on person then the value stored in person object should be returned.
How should I do it. This does not work (see below):
Class<?> clazz = Employee.class;
Method[] arrayOfMethods = clazz.getDeclaredMethods();
for(Method method : arrayOfMethods)
{
String methodReturnValue = method.invoke(person,null).toString();
}
This given an error Person cant be cast to Employee.
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;
}
}
I have a code with two different methods, but one of them is working and other is not compilled, I don`t get what is wrong.
Here is the code:
public class CollectorOperations {
public int averageAgeInt(List<Person> persons) {
return persons.stream()
.collect(Collectors.averagingInt(person -> person.getAge()));
}
public double averageAgeDouble(List<Person> personList, int i) {
return personList.stream()
.collect(Collectors.averagingInt(person -> person.getAge()));
}
}
class Person {
private String name;
private String lastName;
private int age;
public Person(String name, String lastName) {
this.name = name;
this.lastName = lastName;
}
public Person(String name, String lastName, int age) {
this.name = name;
this.lastName = lastName;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
The only difference between this two methods is return type, when return type is int I can't get person.age() from lambda expression, but when I change return type to double it's working.
P.S.
sorry for my english.
It is not compiling due a type mismatch here:
persons.stream().collect(Collectors.averagingInt(person -> person.getAge()));
That operation returns an object of the type Double, but your method is defined to return an integer.
The reason is that a Double object can not be cast into an int, but since that is a Double object, you can get the integer value calling the method Double#intValue()
You need to do something like
return persons.stream().collect(Collectors.averagingInt(person -> person.getAge())).intValue();
I don’t get why you have a parameter int i in the method averageAgeDouble (the variable is never used), so you can define a more elegant way if you get rid off that variable:
public int averageAgeInt(List<Person> persons) {
return (int) averageAgeDouble(persons);
}
public double averageAgeDouble(List<Person> personList) {
return personList.stream().collect(Collectors.averagingInt(person -> person.getAge()));
}
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. :)