I have two constructors for Student and am trying to use both of them with one object. But I should be doing it wrong because my output is not what I expect it to be.
Output:
School: null
Grade Level: 0
Intended Major: null
Student's ID number is: 154324
Student's name: Sam Bay
Student's GPA: 3.56
Code for class definition:
public class Student
{
private int id, gradeLevel;
private String name, school, major;
private double gpa;
//constructor to initialize the instance variables of student object
public Student(int id, String name, double gpa)
{
this.id = id;
this.name = name;
this.gpa = gpa;
}
public Student(int gradeLevel, String school, String major)
{
this.gradeLevel = gradeLevel;
this.school = school;
this.major = major;
}
//toString() to display the attributions of the student object
public String toString()
{
return "School: " + school +
"\nGrade Level: " + gradeLevel +
"\nIntended Major: " + major + "\n" +
"\nStudent's ID number is: " + id +
"\nStudent's name: " + name +
"\nStudent's GPA: " + gpa;
}
}//end class
code for main:
public class StudentDrive
{
public static void main(String [] args)
{
//creating student objects
Student sam = new Student(12, "Alpha High School", "Biology");
sam = new Student(154324, "Sam Bay", 3.56);
System.out.println(sam);
}
}
It seems like I've initialized the first part but I get null and 0??!!!
You can't use two constructors simultaneously on a single object.
In your code:
Student sam = new Student(12, "Alpha High School", "Biology");
creates a new Student object and assigns its reference to the variable sam.
On your next line:
sam = new Student(154324, "Sam Bay", 3.56);
This creates another Student object, separate from the first, and reassigns sam to refer to it instead. In the process, you end up orphaning the original Student and leave it open to garbage collection.
What you really want to do is either pass all data required for by a Student through a single constructor, or provide getters/setters (e.g. setGradeLevel(int level)) and a layer of exceptions that prevent methods from accessing a Student object until all fields are filled. The first option is generally more sound.
For example, a complete constructor would look something like this (formatted for readability):
public Student(int id, int gradeLevel, String name,
String school, String major, double gpa)
{
// fill your fields in here
}
I think you should read through the docs for a constructor again ;)
With Student sam = new Student(12, "Oakton High School", "Biology");
you are creating a Student-object with the given parameters and storing it in the variable sam.
When you call sam = new Student(154324, "Sam Bay", 3.56); you are again creating a new Student-object and storing it in sam. You are not modifying the first object but rather discarding it and creating a new one.
You should try adding a method to your Student object like:
public void setAdditionalValues(int id, String name, double gpa){
this.id = id;
this.name = name;
this.gpa = gpa;
}
Hope this is helpful :)
EDIT: as mentioned earlier you could also use one constructor that takes all the arguments or implement setters for each attribute of the Student-object like this:
public void setName(String name){
this.name = name;
}
Related
I need help with understanding structure for my "small student management app". I need to:
Create SUBJECT.
Subject has a name and number of categories which are types of grades eg. Java, 2, Homework, Project
Each type of grade has weight e.g. Homework, 10
Save that in file
Input grades for STUDENT for selected SUBJECT
Student has ID, name, and grades for each of categories that SUBJECT was chosen.
Save to file
Do some calculations with weight from SUBJECT and inserted grades for student.
I have wrote two methods:
private void createSubject(String name,
int numberOfCat,
List<String> category,
List<Integer> weight);
private void insertGrade(int id, String name, List<Integer> grade);
These methods save input to subjects.txt and students.txt as my database tables. I have also methods for editGrade and deleteSubject as well as viewGrades and viewSubjects
Right now I can add to my filines like that e.g.:
subjects.txt -> (Java, Homework, 10, Project, 40, Final,50,)
students.txt -> (001, John)
My problems start here. I can't imagine right now how can I:
Select one SUBJECT from subjects.txt
Insert grades for student. Number of grades must match number of categories in selected SUBJECT.(Thats why in insertGrade I have saved only ID and name)
Retrieve weights so I can do calculations with grades inserted by user.
If anyone can help me with understanding how can I make it. I don't need a code but I would love to get some clarification how to look at it. Thank you and I'm ready to talk and learn ;)
Are you trying to abstract Subject and Student into classes?
public class Execute {
public static void main(String[] args){
//1.Creating some instance of Grade
Grade grade1 = new Grade("Homework", 10);
Grade grade2 = new Grade("Project,", 40);
Grade grade3 = new Grade("Final,", 50);
//2.Putting all these grades in an ArrayList
List<Grade> grades = new ArrayList<Grade>();
grades.add(grade1);
grades.add(grade2);
grades.add(grade3);
//3.Creating an instance of Subject
Subject Java = new Subject("Java", grades);
//4.Putting the subject in an ArrayList
List<Subject> subjects = new ArrayList<Subject>();
subjects.add(Java);
//5.Creating an instance of Student
Student student = new Student("001", "John", subjects);
/**
* Now you have a student called John, choosing a subject called Java.
* There are 3 parts of this course: Homework, Project, and Final exam.
*/
}
}
public class Student {
private String id;
private String name;
private List<Subject> subjects;
public Student(String id, String name, List<Subject> subjects) {
this.id = id;
this.name = name;
this.subjects = subjects;
}
}
public class Grade {
private String name;
private Integer weight;
public Grade(String name, Integer weight) {
this.name = name;
this.weight = weight;
}
}
public class Subject {
private String name;
private List<Grade> grades;
public Subject(String name, List<Grade> grades) {
this.name = name;
this.grades = grades;
}
}
Well, if I understand you correctly, you do work on the text files. I would not do that.
Load both files on startup and get their content into corresponding classes like students and subjects.
Now with all data loaded, you can easily work on them (like iterate over you lists and so on). At the end, replace the files with the new content.
For the subjects, maybe a map would be nice, if it is really just the two information.
Is it helping you or did I get you wrong?
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 5 years ago.
I want to select a student randomly for messfood(). Trying to print the student name there.Each week, any of the student should be selected for mess food charge. Tried with String random = list.get(new Random().nextInt(list.size()));. But is shows error. Help me with this.
public class Student {
int rollNo, yearOfStudy;
String fName, lName, activity;
Student(int rollNo, String fName, String lName, int yearOfStudy) {
this.rollNo = rollNo;
this.fName = fName;
this.lName = lName;
this.yearOfStudy = yearOfStudy;
}
public void display(){
System.out.println("Roll Number: "+rollNo +"\nName: "+fName+ " "+lName + "\nYear Of Study: "+yearOfStudy+"\n\n");
}
public void messFood(){
System.out.println("week 1, Mess food Incharge: ");
}
}
class Collection {
public static void main(String[] args) {
Student s1 = new Student(1, "Alex", "Iwobi", 2013);
Student s2 = new Student(2, "Denis", "Suarez", 2013);
Student s3 = new Student(3, "Gerard", "Deulofeu", 2013);
Student s4 = new Student(4, "Petr", "Cech", 2013);
List studentList = new ArrayList();
studentList.add(s1);
studentList.add(s2);
studentList.add(s3);
studentList.add(s4);
Iterator it = studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
s.display();
}
}
}
This is precisely why you should be using generics! You risk to encounter runtime errors (as opposed to compile-time errors) involving expected and actual types.
Your call to list.get() will return Object if generics are not used, requiring you therefore to cast it. If the cast happens to be wrong as in your case, it will explode only when run. If you were using generics, your compiler would have told you that you can't convert a Student type to String type!
Take a look at my version:
public class Student {
int rollNo, yearOfStudy;
String fName, lName, activity;
public Student(int rollNo, String fName, String lName, int yearOfStudy) {
this.rollNo = rollNo;
this.fName = fName;
this.lName = lName;
this.yearOfStudy = yearOfStudy;
}
#Override
public String toString() {
return new StringBuilder()
.append("Roll Number: ").append(rollNo)
.append("\nName: ").append(fName).append(" ").append(lName)
.append("\nYear Of Study: ").append(yearOfStudy)
.append("\n\n")
.toString();
}
public void messFood() {
// Establish mess food charge role
}
public static void main(String[] args) {
Student s1 = new Student(1, "Alex", "Iwobi", 2013);
Student s2 = new Student(2, "Denis", "Suarez", 2013);
Student s3 = new Student(3, "Gerard", "Deulofeu", 2013);
Student s4 = new Student(4, "Petr", "Cech", 2013);
List<Student> studentList = new ArrayList<Student>();
studentList.add(s1);
studentList.add(s2);
studentList.add(s3);
studentList.add(s4);
Iterator<Student> it = studentList.iterator();
while (it.hasNext()) {
Student s = it.next();
System.out.println(s.toString());
}
Student randomStudent = getRandomItem(studentList);
randomStudent.messFood();
System.out.println("week 1, Mess food Incharge: ");
System.out.println(randomStudent.toString());
}
private static <T> T getRandomItem(List<T> studentList) {
return studentList.get(new Random().nextInt(studentList.size()));
}
}
Also, in addition to generics, I added a couple of best practices, namely prefering the use of toString() to describe the class rather than printing it out directly (you can do with the String whatever you want afterwards, including calling System.out.println()) .
Also I moved out printing from messFood because again, it is generally preferable to do so. Hope that helps!
Edit: Describing briefly getRandomItem, try not to get too caught up in the details, but <T> says that there will be a type to replace T according to how it will be called. Based on how it is defined, it says if you pass me a List containing type T, I will return to you an object T. T in this case translates to Student, but I kept it generic because it works equally well with other lists. For all intents and purposes, it is as if the signature were the following:
private static Student getRandomItem(List<Student> studentList)
list.get()
will return a student object and not a string, assuming that it's a list of students.
You should do
Student random = list.get(new Random().nextInt(list.size()));
System.out.println(random.getFname + " " + random.getLname);
But of course you need get methods defined.
Include the following:
A method getFirstName that will return a Student object's first name
A method getLastName that will return a Student object's last name
A statement to print "The student's first name is " with your first name returned from the getFirstName method.
A statement to print "The student's last name is " with your last name returned from the getLastName method.
This is what I have so far:
public class Student
{
//the student's full name
String FirstName;
String LastName;
/**
* Create a new student with a given name a
*/
public Student(String name)
{
FirstName = name;
LastName = name;
}
/**
* Return the first name of this student
*/
public String getFirstName()
{
return FirstName;
}
/**
* Return the last name of this student
*/
public String getLastName()
{
return LastName;
}
public static void main(String[] args)
{
//gives a name to the students
Student FirstName = new Student("Samantha");
Student LastName = new Student("Jones");
//each object calls the getName method
System.out.println("The students first name is: " +Student.getFirstName());
System.out.println("The students last name is: " +Student.getLastName());
}
}
You create a new object but do not use it later.
You should add a second argument to the Student constructor for lastname:
public Student(String firstname, String lastname)
{
FirstName = firstname;
LastName = lastname;
}
And in main, use your student-objects after creation.
public static void main(String[] args)
{
//gives a name to the students
Student stud1 = new Student("Samantha", "Jones");
Student stud2 = new Student("Timo", "Hantee");
//each object calls the getName method
System.out.println("The students first name is: " + stud1.getFirstName());
System.out.println("The students last name is: " + stud2.getLastName());
}
Replace with that:
public Student(String _firstname, String _lastname)//constructor header
{
FirstName = _firstname;//description of constructors
LastName = _lastname;
}
In your Student Class, the FirstName and LastName are two different variable, so you need to assign different values to it in your constructor. So rather creating constructor with one argument, create it with two arguments, one for firstName and other for lastName. Like below:
public Student(String firstName, String lastName)//constructor header
{
this.firstName = firstName;//description of constructors
this.lastName = lastName;
}
public static void main(String[] args)
{
//gives a name to the students
Student student= new Student("Samantha", "Jones");
//each object calls the getName method
System.out.println("The students first name is: " +student.getFirstName());
System.out.println("The students last name is: " +student.getLastName());
}
Here I would like to suggest you one more thing, that is very important for java programmers, follow Java Naming Conventions. The variable name should be start with small letter.
I am trying to write a class called Student that is supposed to work with a StudentDriver. However, I am having a very hard time wrapping my head around the concept of methods and classes. I do not know how to receive and return data. Moreover, I don't even know if I am declaring my data correctly. Please help me. I would greatly appreciate it.
Also when I compiled the Student it says that it cannot find the symbol this.setGPA. How so? When in the driver it has .setGPA.
Thank you.
// This will be the "driver" class for the Student class created in
// MinilabWritingClasses (It looks very complicated because of all
// the comments, but it really just creates instances of Student and
// tells them to do things...)
public class StudentDriver
{
public static void main(String[ ] args)
{
//create an instance of Student
System.out.println("***** Creating a Student, calling the default constructor");
Student stud1 = new Student();
//print it so we can see what the default values were for the class data
//note that its toString() will be called automatically
System.out.println("\n***** printing it - notice the default values (set by Java)");
System.out.println(stud1);
//create another instance of a Student, passing in initial values to its constructor
System.out.println("\n***** Creating another Student, passing initial values to its constructor");
Student msBoss = new Student("Bill Gates", 56, 'm', 3.2, true);
//tell it to return its age
System.out.println("\n***** telling it to return its age.");
int theAge = msBoss.getAge();
System.out.println("Its age is: " + theAge);
//print it - note that its toString() will be called automatically;
System.out.println("\n***** printing it - see if values are correct");
System.out.println(msBoss);
//ask it if it is on probation
System.out.println("\n***** asking it if it is on probation (check answer)");
System.out.println("onProbation() returned: " + msBoss.onProbation());
//tell it to change its gpa to 1.3
System.out.println("\n***** telling it to change its gpa to 1.3");
msBoss.setGPA(1.3);
//print it now
System.out.println("\n***** printing it - see if the values are correct");
System.out.println(msBoss);
//ask it if it is on probation now
System.out.println("\n***** asking it if it is on probation (check answer)");
boolean boolAnswer = msBoss.onProbation();
System.out.println("onProbation() returned: " + boolAnswer);
//tell it to complain
System.out.println("\n***** telling it to complain");
System.out.println("complain() returned: " + msBoss.complain());
//tell it to change its onScholarship field to false
System.out.println("\n***** telling it to change its onScholarship field to false");
msBoss.setOnScholarship(false);
//print it now
System.out.println("\n***** printing it - see if the values are correct");
System.out.println(msBoss);
//ask it if it is on probation now
System.out.println("\n***** asking it if it is on probation (check answer)");
boolAnswer = msBoss.onProbation();
System.out.println("onProbation() returned: " + boolAnswer);
//create a different student, tell it to have some different values, and tell it to print itself
System.out.println("\n***** creating a different Student, passing initial values to its constructor");
Student stud2;
stud2 = new Student("Hillary Clinton", 64, 'f', 2.0, true); //notice-can define variable and create it in 2 steps
//print it
System.out.println("\n***** printing it - see if the values are correct");
System.out.println(stud2);
//ask it if it is on probation now
System.out.println("\n***** asking it if it is on probation (check answer)");
boolAnswer = stud2.onProbation();
System.out.println("onProbation() returned: " + boolAnswer);
}
}
Here is the class that I am writing.
public class Student
{
private String name;
private int age;
private char gender;
private double gpa;
private boolean onScholarship;
public Student()
{
}
public Student(String newName, int newAge, char newGender, double newGPA, boolean newScholarship)
{
this.name = newName;
this.age = newAge;
this.gender = newGender;
this.gpa = newGPA;
this.onScholarship = newScholarship;
}
public int getAge(int newAge)
{
return age;
}
public double setGPA (double newGPA)
{
this.setGPA = newGPA;
}
public boolean setOnScholarship (boolean newScholarship)
{
this.setOnScholarship = newScholarship;
}
public String toString()
{
return this.name + "\t" + this.age + "\t" + this.gender + "\t" + this.setGPA + "\t" + this.setOnScholarship;
}
public boolean onProbation()
{
if (onScholarship==true && gpa < 2.0)
return true;
else
return false;
}
}
Try to change this line:
this.setGPA = newGPA;
to this:
this.gpa = newGPA;
setGPA symbol not found is because there is no setGPA field (it is a method). You are trying to change the gpa field.
You also don't need the empty public Student() {} constructor -- this is automatically created by Java.
Also, as #Sam pointed out, since setOnScholarship() doesn't return anything, you can change the return type boolean to void. This is because there is no return statement, and this returning of nothing is a void type.
Overall, though, you have a good understanding on creating instances of another class (i.e., creating Students).
On request (although it doesn't have much to do with your code), here is a brief summary on static.
The static keyword is used with methods and fields that are not used with an instance of that class, but the class itself.
For example, in your case, pretty much all of the Student fields and methods are non-static, because they are properties of Student objects:
this.gpa;
this.setGpa();
On the other hand, if it were not changing a variable related to a single object, for example the total number of students, you could create a static field in Student:
public class Student {
// non-static fields for each instance
public double gpa;
// static field for the class
public static numStudents;
public Student() {
// create student by setting object (non-static) fields, for example...
this.gpa = 3.2;
// edit static variable
numStudents++; // notice how there is no `this` keyword - this changes a static variable
}
}
... and from StudentDriver, numStudents can be retreived with:
Student.numStudents; // notice how this is like `this.[property]`, but with the class name (Student) - it is an instance of the class
I hope this helps! OOP programming is a difficult topic that can't be explained so simply.
Ok, now I think I've given up all hope of finding solution to what should to be a simple problem. Basically, I'm creating a students' record system that stores students' details in an ArrayList. I first created a constructor in the Student class to specify what entries each student will have. I then created an instance of the Student class in the main class (i.e. class with the main method) and then added the student object to the studentList ArrayList.
By the way, instead of hard-coding the student details, my initial aim was to let the user enter the details and then I'll use a Scanner or BufferedReader object to get the details stored in the Student object, and then to the ArrayList but I'm having trouble with that as well; so I'll probably tackle that problem as soon as I'm done with this one.
Anyway, I'm expecting the output to print out the students' details but instead I get a memory location (i.e. [studentrecordsys.Student#15c7850]). I'm aware that I need to override the toString method but how exactly this is done is what I can't seem to get. I get syntax errors everywhere as soon as I enter the #Override code block for the toString method. Here's what I've tried:
import java.util.*;
class Student {
private String studentID;
private String studentName;
private String studentAddress;
private String studentMajor;
private int studentAge;
private double studentGPA;
Student (String studentID, String studentName, String studentAddress, String
studentMajor, int studentAge, double studentGPA){
this.studentID=studentID;
this.studentName=studentName;
this.studentAddress=studentAddress;
this.studentMajor=studentMajor;
this.studentAge=studentAge;
this.studentGPA=studentGPA;
}
}
public static void main(String[] args) {
Student ali = new Student("A0123", "Ali", "13 Bond Street", "BSc Software Engineering", 22, 3.79);
List<Student> studentList = new ArrayList<>();
studentList.add(ali);
#Override
String toString() {
StringBuilder builder = new StringBuilder();
builder.append(ali).append(studentList);
return builder.toString();
}
System.out.println(builder);
}
You need to implement the toString() on the Student object.
public class Student {
...
Your existing code
...
#Override
public String toString() {
return studentID + ", " + studentName + ", " + //The remaining fields
}
}
then in your main method, call
for (Student student : studentList) {
System.out.println(student.toString());
}
You to override toString method because it is going to give you clear information about the object in readable format that you can understand.
The merit about overriding toString:
Help the programmer for logging and debugging of Java program
Since toString is defined in java.lang.Object and does not give valuable information, so it is
good practice to override it for subclasses.
Source and Read more about overriding toString
public String toString() {
return "Studnet ID: " + this.studentID + ", Student Name:"
+ this.studentName+ ", Studnet Address: " + this.studentAddress
+ "Major" + this.studentMajor + "Age" + this.studentAge
+ GPA" + this.studentGPA ;
}
You get errors because you have to Override the toString method inside the class you want to use it for. i.e you have to put the method, with the #Override inside your Student class.
And you can call it like this:
System.out.println(studentA.toString());
System.out.println(studentB.toString());
or in a loop:
for(Student x : studentList)
System.out.println(x.toString());
and so on..
Also, in your code you create a method inside your main method. Of course you will get errors.