How to use a variable of one class, in another in Java? - java

I'm just working through a few things as practice for an exam I have coming up, but one thing I cannot get my head round, is using a variable that belongs to one class, in a different class.
I have a Course class and a Student class. Class course stores all the different courses and what I simply want to be able to do is use the name of the course, in class Student.
Here is my Course class:
public class Course extends Student
{
// instance variables - replace the example below with your own
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
And here is Student:
public class Student
{
// instance variables - replace the example below with your own
private int studentNumber;
private String studentName;
private int studentPhone;
private String studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = courseTitle;
}
}
Am I correct in using 'extends' within Course? Or is this unnecessary?
In my constructor for Student, I am trying to assign 'courseTitle' from class Course, to the variable 'studentCourse'. But I simply cannot figure how to do this!
Thank you in advance for your help, I look forward to hearing from you!
Thanks!

Am I correct in using 'extends' within Course? Or is this unnecessary?
Unfortunately not, if you want to know whether your inheritance is correct or not, replace extends with is-a. A course is a student? The answer is no. Which means your Course should not extend Student
A student can attend a Course, hence the Student class can have a member variable of type Course. You can define a list of courses if your model specifies that (a student can attend several courses).
Here is a sample code:
public class Student{
//....
private Course course;
//...
public void attendCourse(Course course){
this.course = course;
}
public Course getCourse(){
return course;
}
}
Now, you can have the following:
Student bob = new Student(...);
Course course = new Course(...);
bob.attendCourse(course);

I assume a Course is not a Student, so inheritance between those classes is probably a bad idea.

You have to declare them public.
A better way is the keep them private, and code a public getter for that variable. for example:
public Award getCourseAward(){
return this.courseAward;
}

Course should not extend Student. If you want to access the courseTitle field of Course, you need to pass a reference to a Course object to the Student and then do course.CourseTitle.

You cannot access private attributes of a class from another, this is one of the main principles of OOP: encapsulation. You have to provide access method to those attribute, you want to publish outside the class. The common approach is setter/getters - getters only, if you want to have your class immutable. Look here: http://en.wikipedia.org/wiki/Mutator_method#Java_example

It does not make sense to arbitrarily extend classes. Student is not a Course or vice versa, so you cannot extend them like that.
What you need to do is:
create a Course first:
Course aCourse = new Course(..);
create a Student:
Student aStudent = new Student(..);
assign the Course to the Student:
aStudent.setCourse(aCourse.title);

Extending Student with Couse because they are not of the same kind. Extending one class with another happens when specializing a more general (in a sense) one.
The solution would be to pass courseTitle as an argument of the Student constructor

There should be 3 separate objects here, a Course, a Student, and an Enrollment. An enrollment connects a Student to a Course, a Course has many Students, and a Student can enroll in many courses. None of them should extend each other.

First,
You are extending Student class in Course class, which means, student class gets all the coruse class properties. So, the student class does not have the courseTitle property.
Second, yes, it is unnesessary - you need to do the following:
public class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
public class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
// This is where you keep the course object associated to student
public Course studentCourse;
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
}
Example usage would be something like this:
Course course = new Course("ASD", "TITLE", null, "ME", 50, true);
Student student = new Student(1, "JOHN", "5551234", course);
And then, get the course information you need from student via, i.e.:
student.studentCourse.courseTitle;
Since now student.studentCourse will be a course object with all of its properties.
Cheers,

Maybe you do not need to add the course name to student. What I would do is add Students to some datastructure in Course. This is cleaner and reduces the coupling between Course and Student. This would also allow you to have Students being in more than one course. For example:
public class Course extends Student{
private Award courseAward;
private String courseCode;
public String courseTitle;
private Student courseLeader;//change to a student Object
private int courseDuration;
private boolean courseSandwich;
private Set<Student> students;//have course hold a collection of students
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, Student leader, int duration, boolean sandwich){
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
this.students=new HashSet<Student>();
}
public boolean addStudent(Student student){
return students.add(student);
}
public Set<Student> getStudents(){
return students;
}
}

As mentioned, stay away from the "extends" for this. In general, you shouldn't use it unless the "is-a" relationship makes sense.
You should probably provide getters for the methods on the Course class:
public class Course {
...
public String getTitle() {
return title;
}
}
And then if the Student class needs that, it would somehow get a hold of the course (which is up to you in your design), and call the getter:
public class Student {
private Set<Course> courses = new HashSet<Course>();
public void attendCourse(Course course) {
courses.add(course);
}
public void printCourses(PrintStream stream) {
for (Course course : courses) {
stream.println(course.getTitle());
}
}
}

Here below find out the solution of your problem and if you want to check below code on your machine then create a file named Test.java and paste the below codes:
package com;
class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseAward = award;
courseCode = code;
courseTitle = title;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
public Award getCourseAward() {
return courseAward;
}
public void setCourseAward(Award courseAward) {
this.courseAward = courseAward;
}
public String getCourseCode() {
return courseCode;
}
public void setCourseCode(String courseCode) {
this.courseCode = courseCode;
}
public String getCourseTitle() {
return courseTitle;
}
public void setCourseTitle(String courseTitle) {
this.courseTitle = courseTitle;
}
public String getCourseLeader() {
return courseLeader;
}
public void setCourseLeader(String courseLeader) {
this.courseLeader = courseLeader;
}
public int getCourseDuration() {
return courseDuration;
}
public void setCourseDuration(int courseDuration) {
this.courseDuration = courseDuration;
}
public boolean isCourseSandwich() {
return courseSandwich;
}
public void setCourseSandwich(boolean courseSandwich) {
this.courseSandwich = courseSandwich;
}
}
class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
private Course studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentPhone() {
return studentPhone;
}
public void setStudentPhone(int studentPhone) {
this.studentPhone = studentPhone;
}
public Course getStudentCourse() {
return studentCourse;
}
public void setStudentCourse(Course studentCourse) {
this.studentCourse = studentCourse;
}
}
class Award{
private long awardId;
private String awardName;
Award(long awardId, String awardName){
this.awardId = awardId;
this.awardName = awardName;
}
public long getAwardId() {
return awardId;
}
public void setAwardId(long awardId) {
this.awardId = awardId;
}
public String getAwardName() {
return awardName;
}
public void setAwardName(String awardName) {
this.awardName = awardName;
}
}
public class Test{
public static void main(String ar[]){
// use your all classes here
}
}

Related

Refactoring in Java: Duplicated attributes

I am supposed to refactor duplicated attributes in Student class. I have Student and Professor classes as below. I am really confused about how to do refactoring with attributes. Should I add a new class, or made modifications in one of the classes. If so, how? I could not understand how to proceed with this to-do.
private final String matrNr;
private final String name;
private final int age;
private int semester;
private final String email;
public Student(String name, int age, String email, String matrNr, int semester) {
this.matrNr = matrNr;
this.name = name;
this.age = age;
this.semester = semester;
this.email = email;
}
public String getEmail() {
return email;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getSemester() {
return semester;
}
public String getMatrNr() {
return matrNr;
}
public void increaseSemester(){
semester = semester + 1;
}
}
And the professor is a like:
private final String persNr;
private final String name;
private final int age;
private final String email;
public Professor(String name, int age, String email, String persNr) {
this.persNr = persNr;
this.name = name;
this.age = age;
this.email = email;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getPersNr() {
return persNr;
}
}
Thanks for any kind of helps!
Your goal is to refactor duplicated attributes in the Student and Professor classes. The way to do this is to create a parent class which defines the common attributes (like "name"), and modify Student and Professor classes to extend the common parent class. In this way, both Students and Professors can have a "name", even though you have defined "name" only once in the common parent.
Below shows how you could do this with a common "Human" parent class, how the constructors would work, and how you could define a Student-only attribute (semester).
Here is a simple version a common Human class:
common "Human" class
each Human has a "name"
the name is set in the constructor (so when you're creating an object) and cannot be changed later ("name" is final; also no "setHuman()")
class Human {
private final String name;
public Human(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Here's a simple Professor class:
by definition, a Professor is a Human (Professor extends Human)
when creating a Professor, you must specify the "name" (which is then passed to the Human constructor)
once you have a Professor, you can call getName() (which is defined on the Human class)
class Professor extends Human {
public Professor(String name) {
super(name);
}
}
Here's a simple Student class:
Student is a little different - in addition to a name, it also has a "semester"
when creating a Student, the constructor requires a name and semester, and the Student class itself keeps track of "semester" – so it's fine to have semester defined on Student, and name defined on Human.
you can call getName() (defined on Human)
you can call getSemester() (defined on Student)
class Student extends Human {
private final int semester;
public Student(String name, int semester) {
super(name);
this.semester = semester;
}
public int getSemester() {
return semester;
}
}

Why can't I inherit a specific variable from a specific class?

I want to inherit the variable "remark" from the Student class to put into the Course Class. So I basically done the "extends" keyword and the super(remark), but it's still not working. Is is possible to inherit only 1 specific variable or is there another way?
public class Course extends Student {
private String[] courseName;
private String[] courseNo;
private int courseCredit;
Course(String[] courseNo,String[] courseName,int courseCredit,char[] remark) {
super(remark);
this.courseNo = courseNo;
this.courseName = courseName;
this.courseCredit = courseCredit;
}
public void setCourseInfo(String[] courseNo,String[] courseName, int courseCredit) {
this.courseNo = courseNo;
this.courseName = courseName;
this.courseCredit = courseCredit;
}
public void setcourseName(String[] courseName) {
this.courseName = courseName;
}
public void setcourseNo(String[] courseNo) {
this.courseNo = courseNo;
}
public void setcourseCredit(int courseCredit) {
this.courseCredit = courseCredit;
}
public String[] getcourseName() {
return courseName;
}
public String[] getcourseNo() {
return courseNo;
}
public int getcourseCredit() {
return courseCredit;
}
public class Student extends Person {
private int sid;
private int numberOfCourse;
private boolean isTuitionPaid;
private String[] course;
private char[] remark;
Student(String fname,String lname,int sid,int numberOfCourse,boolean isTuitionPaid,String[] course,char[] remark) {
super (fname,lname);
this.sid = sid;
this.numberOfCourse = numberOfCourse;
this.isTuitionPaid = isTuitionPaid;
this.course = course;
this.remark = remark;
}
public void setInfo(String fname,String lname,int sid,int numberOfCourse,boolean isTuitionPaid,String[] course,char[] remark) {
this.getfname();
this.getlname();
this.sid = sid;
this.numberOfCourse = numberOfCourse;
this.isTuitionPaid = isTuitionPaid;
this.course = course;
this.remark = remark;
}
public void setRemark(char[] remark) {
this.remark = remark;
}
public char[] getRemark() {
return remark;
}
public void setStudentID(int sid) {
this.sid = sid;
}
public void setIsTuitionPaid(boolean isTuitionPaid) {
this.isTuitionPaid = isTuitionPaid;
}
public void setNumberOfCourses(int numberOfCourse) {
this.numberOfCourse = numberOfCourse;
}
public void setCoursesEnrolled(String[] courses,char[] remark) {
this.course = courses;
this.remark = remark;
}
public int getStudentID() {
return sid;
}
public int getNumberOfCourses() {
return numberOfCourse;
}
If I understand your question, you'd want to restructure your code.
Here is one (traditional) way to do it with pseudocode to help you along but leave the learning to you.
The key concept to understand is inheritance. The typical question you would ask is using "is a." Is a Course a Student? Is a Student a Course? No. Then don't extend.
public class Course {
//add getters and setters
private String name; //multiple names may make your life harder, think it through
private String[] number;
private String description;
private int credit; //are you sure this is an int??
private Student[] enrolledStudents;
}
public class Student extends Person { //not sure whether Person is really needed, but that's based on your requirements. Interfaces and composition are preferred.
//add getters and setters
private Course[] enrolledCourses;
//other properties
}
You would also need to get clearer on the Remark and the relationship to each class. Are remarks written about each student for each course? Do you need to see the remarks for all courses? Do you need to see all remarks for all students?
If the application is involved and uses say, a database, you could have a service class with something like:
public String getRemarks(Student student, Course course) {
//some implementation. A Remark could also be a class (bean) depending on your needs
}
Having a separate variable for numberOfCourses is likely not needed. You can just count the size of the enrolledCourses array.
Using Java's List will also make your life easier in many cases depending on what you need to do.
I will leave the functional style as a learning exercise, but that is where the industry has shifted toward in practice. Features of newer Java versions (e.g. records) can apply here too.

Construct object with highest ID + 1

I want to make a counter for the ID, and construct a new Person object with that ID.
My lombok class:
package nl.SBDeveloper.Persons.Lombok;
import lombok.Data;
#Data
public class Person {
private int id;
private String name;
}
My code:
Person person = new Person();
What is the best way to create this?
Define a static field. #Data creates a constructor using only the required arguments. ID is not required since it's already assigned, so you get a constructor which just takes a name.
#Data
public class Person {
private static final AtomicInteger currentId = new AtomicInteger();
private final int id = currentId.incrementAndGet();
private final String name;
}
Usage:
Person bob = new Person("Bob");
Define your data class:
public class Person {
private int id;
private String name;
Person(int id, String name) {
this.id = id;
this.name = name;
}
public String getName() {
return this.name;
}
public int getId() {
return this.id;
}
}
You can keep track of how many Person objects you create by defining a PeopleFactory object, and giving it a static personCount field. To make sure this counter is thread-safe, you would need to synchronize the field, or synchronize the method in charge of Person creation.
public class PersonFactory {
private static int personCount = 0;
public PersonFactory() {
}
public synchronized Person getPerson(String name) {
personCount++;
return new Person(personCount, name);
}
}
Testing our implementation:
public class Main {
public static void main(String[] args) {
PersonFactory personFactory = new PersonFactory();
Person bill = personFactory.getPerson("Bill");
System.out.println("ID: " + bill.getId() + ", Name: " + bill.getName());
}
}
ID: 1, Name: Bill

Java ,import not resolved,inheritance,inner class

Begging java programming recently, run into an error. please help
Have two classes , PersonTest.java:
public class PersonTest {
public static void main(String[] args) {
Person person1=new Person("dummy","sdymmt","20","male","washington");
System.out.println("Name: "+person1.getName());
System.out.println("Surname: "+person1.getSurname());
System.out.println("Age: "+person1.getAge());
System.out.println("Gender:" +person1.getGender());
System.out.println("Birthplace: "+person1.getBirthplace());
Person person2= new Person(400);
System.out.println("Income:"+person2.getX()+" mije leke");
System.out.println("Tax:"+person2.Taksat()+" mije leke");
Student student1= new Student("adsd","zedsdsadza");
System.out.println("emri"+student1.getEmer());
}
}
and also Person.java :
public class Person {
private String Name;
private String Surname;
private String Age;
private String Gender;
private String Birthplace;
private double x;
public Person()
{
}
public Person(String Name, String Surname, String Age, String Gender, String Birthplace) {
this.Name = Name;
this.Surname = Surname;
this.Age = Age;
this.Gender = Gender;
this.Birthplace = Birthplace;
}
public String getName() {
return Name;
}
public String getSurname() {
return Surname;
}
public String getAge() {
return Age;
}
public String getGender() {
return Gender;
}
public String getBirthplace() {
return Birthplace;
}
public Person(double x) {
this.x = x;
}
public double getX() {
return x;
}
double Taksat() {
return (0.1 * x);
}
public class Student extends Person {
private String University;
private String Faculty;
public Student(String Universiteti, String Fakulteti) {
super(Name, Surname, Age, Gender, Birthplace);
this.Faculty = Fakulteti;
this.University = Universiteti;
}
public String getFaculty() {
return Faculty;
}
public String getUniversity() {
return University;
}
}
}
Two classes are in the same default package. How to fix the fact that the test class doesn't recognize the inner class student as a class.
Nested non static class are called Inner Classes those classes cannot live without the Outer class (which wrapped them).
Java docs
An instance of InnerClass can exist only within an instance of
OuterClass and has direct access to the methods and fields of its
enclosing instance.
To instantiate an inner class, you must first instantiate the outer
class. Then, create the inner object within the outer object with this
syntax:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Try using:
Person.Student student = person1.new Student(PARAMETERS);
Important Mark:
Of course, you should highly consider that this is not a good design, because you may want this classes to be visible outside of the Person class but also because Person.Student inherits from Person, which it's already contains the Student class, which usually looks like a loop or a circle relationship, which usually not a good idea for the first place.
Because there is no Student class. Since it nested, it's Person.Student

From UML to Java, Simple association

This is the Image that I'm going to transfer from UML to Java, I don't know how to lock them together and i don't know how to make one bankAccount locked to only one person.
How do i connect the 2 classes??
Here is my code so far
My main method
public class Upp5 {
public static void main(String[] args) {
Person2 david = new Person2();
BankAccount acc1 = new BankAccount();
BankAccount acc2 = new BankAccount();
david.setName("David");
david.setPnr("551012-8978");
acc1.setBnr("37");
acc2.setBnr("38");
System.out.println("Namn: " + david.getName() + " \nPersonnummer:" + david.getPnr());
System.out.println(acc1.getBnr() + "\n" + acc2.getBnr());
}
}
BankAccount.java:
public class BankAccount {
private String bnr;
private double balance;
public void credit() {
}
public void withdraw(){
}
public String getBnr(){
return bnr;
}
public void setBnr(String newAccount){
bnr = newAccount;
}
public void createAccount(String newNbr){
bnr = newNbr;
}
}
and Person2.java
public class Person2 {
private String pnr;
private String name;
//Koppla konto till pnr
public void addAccount(BankAccount a){
}
//Skapa Pnr och Namn
public void setPnr(String newPnr) {
pnr = newPnr;
}
public void setName(String newName){
name = newName;
}
// Hämta Pnr och Namn
public String getPnr(){
return pnr;
}
public String getName(){
return name;
}
}
You need to define a List<BankAccount> to your Person2 entity:
public class Person2 {
private String pnr;
private String name;
// list of bank accounts (from 0 to n) the Person can have.
private List<BankAccount> accounts;
//Koppla konto till pnr
public void addAccount(BankAccount a){
if (accounts = null) accounts = new ArrayList<BankAccount>();
accounts.add(a);
}
//Skapa Pnr och Namn
public void setPnr(String newPnr) {
pnr = newPnr;
}
public void setName(String newName){
name = newName;
}
// Hämta Pnr och Namn
public String getPnr(){
return pnr;
}
public String getName(){
return name;
}
// include getters setters
}
EDIT1: as suggested by #NathanCastlehow if you want double relationship, BankAccount.java must have a Person2 attibute
public class BankAccount {
private String bnr;
private double balance;
// one bank account can only be owned by a single Person
private Person2 person;
public void credit() {
}
public void withdraw(){
}
public String getBnr(){
return bnr;
}
public void setBnr(String newAccount){
bnr = newAccount;
}
// generate getters setters
public Person2 getPerson(){
......
}
}
You didn't put any arrows in your diagram, so we don't know if the bankaccount knows the person it is linked to. The most logical thing to do is; let the Person have a List which you always initiate in the Person's constructor.
If you want the bankaccount to know the person that owns him (which seems logical to me), let the Bankaccount have the property "Person owner" and let the constructor be require a Person to exist. I don't understand why you have made a Person2 instead of a Person class.
Tips for you: Never (!!!) use parameters like; 'a' or properties like 'nBr' because other people wanna see in an instance what they are instead of guessing. :-) And try to make some security rules (that's why I put booleans in the classes).
Solution:
Person:
public class Person {
List<BankAccount> bankAccounts;
private String name;
private String pNbr;
public Person(String name, String pNbr) {
this.name = name;
this.pNbr = pNbr;
}
public void addAccount(BankAccount newAccount){
bankAccounts.Add(newAccount);
}
}
Bankaccount:
public class BankAccount {
private String nBr; //maybe make this final?
private double balance;
private Person owner;
public BankAccount(String nbr, Person owner) {
this(nbr, 0, owner); // If you also want to support new empty accounts
}
public BankAccount(String nbr, double balance, Person owner) {
this.name = name;
this.pNbr = pNbr;
this.owner = owner;
}
public boolean Credit(double amount)
{ // TODO: write code
boolean result = false;
return result;
}
public boolean Withdraw(double amount)
{ // TODO: write code
boolean result = false;
return result;
}
}
So generally when this is done in models such as a relational model you would have an association class. So a class that has like an ID from a bank account and an ID of the person. You can lock variables using the final keyword in front of them which forces them to only be initialized once.
The easiest way to "link" classes in java is to add one of said classes as an attribute. For example:
// Make it private to maintain encapsulation
private BankAccount myBankAccount;
But this only works if you have a 1..1 (One to one) relationship.
Your UML diagram indicates a 1..n (One to many) relationship between Person and BankAccount classes. In other words,
A Person may have multiple BankAccounts.
This means you'll a have to use a structure to "keep" multiple BankAccounts in a single Person. Java already provides you with some handy classes:
ArrayList: Easy, quick, insertion-ordered list. Allows as many itens as you need.
Hashmap: Hash implementation of the Map interface. Provides a way to find itens using a "key" (Ex: An account's number). Very efficient.
A suggest reading some of those classes documentation. And you can always look for some neat examples on the internet ;)

Categories

Resources