I'm creating a web-based scholar system for students to look up their scores, view their schedule, etc. However, I'm having a problem on architecting this system, as in I can't find a suitable way to associate the data.
There's a student, which is in a (school) class. The student has a scoreboard. The (school) class has a list of the "assignments" the students had for each subject, but it only has informations such as name, maximum score, weight. The actual score sits on the student's scoreboard.
Many students are in the same class.
Only one instance of an assignment should exist at any time, and it should live in the SchoolClass object, because it's then applied to the whole class instead of per-student.
A student, then, should only hold it's own score, and reference the rest of the assignment data from outside.
How do i reference the specific homework from the student?
That was kind of confusing. This is what I currently have:
class Student extends Person {
private SchoolClass schoolClass;
private Scorecard scorecard;
}
class Subject {
private String name; /// "Compilers II", "Data Structures", etc.
}
class SchoolClass {
private Course course; // "Computer Science", "Administration", etc.
private List<Assignment> assignments;
class Assignment {
private Subject subject;
private int maxScore;
private int weight;
private String name; // "Test about material resistance II"
}
}
class Scorecard {
// How to reference each assignment from each subject in this student's class cleanly?
}
Is my design going on a good direction or should I just erase this and begin again? Thanks!
This is looking pretty good, but there are a couple things I would like to point out.
Is the Person classs abstract? If so then well done! If not it probably should be because person is a general term. For more information about when to make a class abstract check out my answer to this question.
Well done using Assignment as a nested class! It directly relates to SchoolClass so it should be nested, but how about the Subject class? That seems to be directly connected to SchoolClass as well therefore it would not be a bad idea to make Subject a nested class also.
As for referencing a single homework assignment, this depends on how you want to get it by. If you want to get it by index then use a getter. To do this you could simply put this code in SchoolClass:
public Assignment getAssignment(int index)
{
return assignments.get(index);
}
However if you want to use reference it by name instead it is a little more tricky, but still pretty strait-forward. You would add a getter to your Assignment class like this:
public String getName()
{
return name;
}
Then you would simply have to write another getter for SchoolClass like this:
public Assignment getAssignmentByName(String name)
{
for (Assignment assignment : assignments)
{
if (assignment.getName().equals(name))
return assignment;
}
System.out.println("No assignment found by the name of " + name);
return null;
}
Hope that helps! If you have any questions don't hesitate to ask!
Edit:
In order to let your assignment objects describe themselves they should override Object.toString(). The following code should be put in your assignment class.
// I noticed that you only have a maxScore variable, I think that a score variable is needed
private int score;
#Override
public String toString()
{
return "The score for this assignment is: " + score;
}
Related
its my first question and I am already nervous. I may start with "Its for my homework" and it is but i try to get to the problem:
I have to realise a simple ticket selling program, that contains two classes:
a class ticket which contains the following fields:
public class Ticket
{
//Fields
private int ticketID;
private boolean sold;
private Category category;
//Constructor
public Ticket(int ticketID, Category category)
{
this.ticketID = ticketID;
this.category = category;
this.sold = false;
}
}
and a class named Category which should look like this:
public class Category
{
char category;
double sellPrice;
Ticket[] tickets;
private Random rnd;
public Category(char category, double sellPrice, int amount)
{
this.category = category;
this.sellPrice = sellPrice;
//from here on my difficulties start!
rnd = new Random(System.nanoTime());
tickets = new Ticket[amount];
for(int i = 0; i < tickets.length; i++)
{
tickets[i] = new Ticket(generateRandom(100000, 1000000), this);
//especially this line worries me!
}
}
For simplicity I stripped the code down to bare mimimum. Now my problem is that I should create an array of Category which will contain the arrays of Tickets, but when I do that I create an infinite loop by referencing each ticket to the Category object by passing it the "this" for the category parameter of its constructor. Whel debugging my project I really create an "infinite" loop because I can always go deeper into the combination of Category->tickets[]->category->tickets[]->... and so on. The Assignment says I have to use the Category class in Ticket but is there another way to create a system without these "loops"?
How can I prevent infinite recursion when declaring two object each containing the other?
In your given example, there won't be any problems of so called infinite recursion. That will only happen if you have something like this:
class Ticket{
public Ticket(){
new Category();
}
}
class Category{
public Category(){
new Ticket();
}
}
Won't it just reference itself forever?
If you are merely creating a variable, for example:
Ticket ticket;
The constructor will not be invoked. The constructor will only be invoked when you instantiate the object, i.e.: new Ticket();
You are right in that you can always go deeper into the combination of Category->tickets[]->category->tickets[]->, etc., and if you do, it's indeed a problem, but you have not shown us any code where you are actually doing it.
References are not instantiations. So in our example, Category instantiates a bunch of Tickets, which does take a lot of space; but Ticket does not instantiate a Category and instead merely refers to it. Which is typically just 64 extra bits per Ticket.
Think about it this way. Instantiations (by calling new) is like giving birth. References is like pointing at someone. Two people can point at each other, or many can point at you, and it won't cost much.
It's when you visit person A who points at person B, and then decide to visit A again, then B again, etc., you may get into an infinite loop. The fact they are pointing at each other does not cause any such problem.
I am new to java and programming overall, today I encountered a problem with these 3 relations. Unfortunately from my materials I can't understand how to implement them. I hope somebody can make this clear for me.
1) Association
For example I have 2 classes. Student and School, this is association with multiplicity 1:1, I understand that in each class, I'll have atribute that refers to the other class. But my question is, if In constructor do I declare these reference variable? Do I also create set and get methods for them? What if that association is with multiplicity 1:N ? I have reference variable, that refers to list, do i declare that somehow in constructor too? Do i create set and get methods for that array list?
2) Aggregation
From what I understand, in terms of implementation in Java aggregation is nothing but one-way association. So the reference variable is only in one class. Is my hypothesis true?
3) Composition
I know that composition is special type of aggregation. So what I think, in terms of implementation in Java, that it'll be one way association too, so the implementation will be same and the only thing that differs is how we recognize this relation outside of programming.
If anybody could help me I would really appreciate it
Sorry that I didn't show any example, true is that It would help me to describe my thoughts.
Lets say we have class, student
public class Student {
private String name;
private School school;
}
public Student(String namei, School school) {
this.name = name;
this.school = school;
}
If class school, would have an atribute private Student student, it would be an association. But if not, and the only reference atribute would be in class Student, Am I right if I would say that the relation between those classes is Aggregation ?
What if we change it up a little bit and we say, that school, needs to have students. So the only thing we change would be the context, how we think about the subject and nothing else, if we would do that, Would I be right if I would say that the relation would be Composition?
School definitely needs a student but it cannot be composition because in composition the container (School in this case) and content (Student in this case) are such that destruction of the one means destruction of the other,,Even when you leave your school for higher studies (Content is gone) the content should still remain,
I would consider the relation between the school and student as aggregation
Aggregation : Here there exists a relationship between the two objects in such a way that one uses other,the contained object (student) is initialized in the main function
Here School is Container and Student is content,it is aggregation because as and when the student is born he is not enrolled to school(it would be so if you would have used Composition),so we need to initialize the student in the main function and pass it as the parameter to the school in the constructor
Aggregation :
class Student
{
String Name;
int grade;
Student() {}
Student(String Name,int grade)
{
this.Name=Name;
this.grade=grade;
}
public String toString()
{
return(this.Name + " : "+this.grade);
}
}
class School
{
Student student;
String SchoolName;
School(Student student,String SchoolName)
{
this.student=student;
this.SchoolName=SchoolName;
}
public String toString()
{
return(this.student + " : "+this.SchoolName);
}
}
class Aggregation
{
public static void main(String[] args)
{
Student student = new Student("Sourabh",4);
School school = new School(student,"SBI");
System.out.println(school);
}
}
If you want to implement it as the composition relation initialize the object student in the constructor of school
I recently started learning java this year in my school. We've gotten to a short chapter where we are creating a class that calls multiple methods from inside the class or outside the class. Our teacher gave us a demo showing us an class using methods from another class. This is the code from his example of this and called the class Dog. He then creates another class called DogDriver. We then received a coding project. Here's what is must include. It's a program for a bank that must allow the owner to enter the bank account owner's name, money balance, and the amount the depositor would like withdrawn from their account. It will also need to allow the depositor to deposit and withdraw funds, and give error when the withdrawal exceeds the accounts balance. It needs 2 or more methods to call the program
I referenced back to the example he gave me and am having a hard time understanding the example so I can make the program. I think I get what it does, but when ever I try and code it myself, I seem to always get the “invalid method declaration; return type required”. I know I am doing something wrong but I would like to understand the way the program code I linked above works and how it can be used.
Any help is appreciated, Thank You
Here's my code. I was trying to understand the example program he created so I had taken it and edited it.
//January 27, 2015
public class Testing1{
private double Balance;
private String Name, Middle, Last;
public AccountBalance(){
Name = "Phillip";
Middle = "J.";
Last = "Fry";
Blance = 300;
}
public accountBalance(String FirstName, String MiddleName, String LastName, double InitialBal){
Name = FirstName;
Middle = MiddleName;
Last = LastName;
Balance = InitialBal;
}
public String Name(){
return Name;
}
public void SetBalance(double InitialBal){
Balance = InitialBal;
}
public double GetBalance(){
return Balance;
}
}
public AccountBalance(){...}
//and
public accountBalance(String FirstName, String MiddleName, String LastName, double InitialBal){...}
are (I assume you want them to be) constructors, therefore, they need to be the same name as the class name (here it is Testing1), and they are CASE SENSITIVE meaning AccountBalance does not equal accountbalance, eith change your constructors to match the class name :
public Testing(){...}
or refractor your class name to be AccountBalance
The error is because java thinks they are methods, which need return types.
Oh and, Balance = 300 is spelt wrong in your first constructor
First of all, if you would like to call a method from a different class, it must be public class. Then you can call those methods from your main method.
Dog myDog = new Dog();
myDog.colour("White");
Java Method Calling
For example, say I have the 3 classes Person, Student and Teacher. The Person class would have general details about the people (name, age, email etc) which both the Student and Teacher class will extend. On top of this though, these classes will also have their own unique fields (e.g. wage & courseTaught (or "tought"?) for Teacher and schoolYear & classNumber for Student). If I just show the initial code I've got, maybe someone could point me in the right direction. Because Person doesn't have a courseTaught field, currently I'm just getting the output "Josh (null)" rather than "Josh (Computer Science)". Any help would be appreciated :)
public class Main {
public static void main(String args[]){
Teacher t = new Teacher("Josh", "Computer Science");
System.out.println(t.name + " (" + t.courseTaught + ")");
}
}
public class Person {
String name;
public Person(String pName){
name = pName;
}
}
public class Teacher extends Person{
String courseTaught;
public Teacher(String tName, String tCourseTaught){
super(tName);
}
}
The problem is simpler than you think. You're on the right track but you forgot to assign courseTaught in your Teacher constructor. The initial value of courseTaught is null and it stays that way because you never assign it to anything.
You'd want something like this:
public Teacher(String tName, String tCourseTaught){
super(tName); // <- takes care of Persons's field
courseTaught = tCourseTaught; // <- but don't forget to set the new field, too.
}
And yes, "taught" is the correct word.
As an aside, since you did tag your question "oop", you may want to check out this article on encapsulation for some information about the use of "getters" and "setters".
I'm battling at the moment in trying to understand how to approach this issue in an object-oriented way.
With a many-to-many relationship such as Students-Subjects, where each student gets a mark for a certain subject, assuming the following:
I want to be able to display all the marks for a given student.
I want to display all the marks from different students for a given subject
I want to be able to change any student's mark for a given subject.
I have trouble with this last one, I can't seem to think of a way to relate the classes to each other so that the marks will remain congruent when changed...
Here's what I was thinking about doing in pseudocode. Pretend we have 3 students each involved in 3 subjects (9 marks total):
Make a class for Student (String name, int studNumber)
Make a class for Subject (String name, int subNumber)
Make a class for Result(int percentageScore String grade(calculated based on
percentageScore))
Then have an array of arrays of Result objects, eg. [1][2] in the array will
give the score for the student with studNumber 2 in the subject with subNumber 1.
I feel like this isn't object-oriented? There should be some kind of acknoledgement of the relationship within the class design for subject and students. If that is indeed right, could anyone point me in the right direction? How does one do this in an object-oriented way?
Thanks a lot.
Why go with such complex class structures. You can have a simple Student class.
class Student{
String stuName;
long rollNo;
public Student(String stuName, long rollNo){
this.stuName=stuName;
this.rollNo=rollNo;
}
.
.
.
}
And a Subject class. Each subject has certain students enrolled and the marks that each student has scored in that subject. Which can be represented as:-
class Subject{
String subName;
HashMap<Integer,Student> Result;
public Subject(String subName){
this.subName=subName;
Result=new HashMap<Integer,Student>();
}
//add methods to add students,modify marks, etc
public void addStudent(String name,long roll, int marks){
Result.put(marks,new Student(name,roll));
}
public int giveMarksForSubject(long roll){
//iterate Results , and check for student objects to match roll no. return key of matching student
.
.
.
}
.
.
}
For the part where you mentioned you want to change marks for students for certain subject. You can search the Subject object by String name in your Main method's class and then change Student's marks according to name/rollNo. You can provide methods in Subject class for implementing such functionality.
Both subjects and grades have a limited number of values, so I suggest using enums:
public class Example {
public static void main(String[] args) throws IOException {
Student s1 = new Student("John Doe");
s1.setGrade(Subject.MATHS, Grade.B);
s1.setGrade(Subject.PHYSICS, Grade.A);
s1.setGrade(Subject.ENGLISH, Grade.E);
Student s2 = new Student("Jane Smith");
s2.setGrade(Subject.MATHS, Grade.C);
s2.setGrade(Subject.PHYSICS, Grade.C);
s2.setGrade(Subject.ENGLISH, Grade.A);
// print students and their grades:
s1.printAllGrades();
s2.printAllGrades();
// print every subject and its grades:
for(Subject s : Subject.values()){
s.printAllGrades();
}
}
}
enum Subject{
MATHS, PHYSICS, ENGLISH;
private Map<Student, Grade> grades = new HashMap<Student, Grade>();
public void setGrade(Student student, Grade grade){
grades.put(student, grade);
}
public void printAllGrades(){
System.out.println(this);
for(Student s : grades.keySet()){
System.out.println(s.getName() + " : " + grades.get(s));
}
}
}
enum Grade{
A, B, C, D, E, F
}
class Student{
private String name;
private Map<Subject, Grade> grades = new HashMap<Subject, Grade>();
public Student(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setGrade(Subject subject, Grade grade){
grades.put(subject, grade);
subject.setGrade(this, grade);
}
public Grade getGrade(Subject subject){
return grades.get(subject);
}
public void printAllGrades(){
System.out.println("Grades of " + name + ":");
for(Subject s : grades.keySet()){
System.out.println(s + " : " + grades.get(s));
}
}
}
Using the enum type is suitable to list both subjects and grades. It guarantees that only suitable values can be passed as an argument and is easily extensible - you can add a method to an enum if you wish. A simple HashMap for every student is enough to hold the mappings between subjects and grades.
You may want to read more on enums in java.
I think the approach should be same like with database tables. You should implement some sort of a "joining class" between these 2. That class should be singleton and you should reference it in both, students and subjects. The class should have some sort of a list or a map, or something with that structure, which would contain properties: student, subject, mark. That way you could iterate through that collection by any of those properties, which should do what you need. This example How to make SQL many-to-many same-type relationship table is for databases, but I think it should give you some helpful insight.
This article makes a very compelling case for including the following structures in your design:
Student (incl an array of Result pointers)
Subject (incl an array of Result pointers)
Result (with all the attributes that belong to the relationship)
Though the original post was a long time ago, hope this helps someone else.