How to model this relation using Java OOP concepts - java

I have this condition (property rent system, rent is counted per night)
Owner has one or more property. Property has description, price, and isOccupied attribute.
The property can be: hotel (with 3 room types), flat/apartment, and house for homestay.
Through a registry function, a customer can order one or more property available at certain date.
Here are the pre-defined conditions for registry function:
There are 2 registered owners and customers in the system.
Owner 1 has 10 hotel rooms (standard type) for US$30 per night and 3 hotel rooms (suite type) for US$60 per night.
Owner 2 has 3 apartments for US$70 per night and 5 homestay house for US$20 per night.
Customers can rent one or more owner's property for a certain date.
To model the property, I use inheritance concept. For now, it looks something like this.
Property.java
public class Property {
private String description;
private int propertyPrice;
private String ownerName; // should it be here? or should it be made in another class?
private boolean isOccupied;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getPropertyPrice() {
return propertyPrice;
}
public void setPropertyPrice(int propertyPrice) {
this.propertyPrice = propertyPrice;
}
}
Hotel.java
public class Hotel extends Property {
private String[] roomType;
private int[] roomCount;
public Hotel(){
this.roomType = new String[]{"Standard", "Deluxe", "Suite"};
this.roomCount = new int[]{0, 0, 0};
}
public String[] getRoomType() {
return roomType;
}
public void setRoomType(String[] roomType) {
this.roomType = roomType;
}
public int[] getRoomCount() {
return roomCount;
}
public void setRoomCount(int[] roomCount) {
this.roomCount = roomCount;
}
}
Apartment.java
public class Apartment extends Property {
private int roomCount;
public int getRoomCount() {
return roomCount;
}
public void setRoomCount(int roomCount) {
this.roomCount = roomCount;
}
}
Homestay.java
public class HomestayRoom extends Property {
private String parentName;
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
}
What makes me confused is, how can I define the pre-defined conditions for registry to model owner-property relation? Should I make the owner at another class? If so, how can I relate the properties and its owner?

Most of what you have done is correct, but you could also have a property type enum
public enum PropertyType{
HOTEL,APARTMENT,HOMESTAY
}
Now you're super class would be
public class Property {
private String description;
private int propertyPrice;
private String ownerName;
private boolean isOccupied;
private PropertyType pt;
....
}
A constructor for hotel would be
public Hotel(){
this.roomType = new String[]{"Standard", "Deluxe", "Suite"};
this.roomCount = new int[]{0, 0, 0};
super(PropertyType.HOTEL);
}
Similarly you could have constructors for Homestay and Apartment, with the extra line of super(PropertyType.HOMESTAY) and super(PropertyType.APARTMENT) respectively.

Related

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.

Merging multiple LiveData sources?

To make it easier to visualize my problem I drew the following:
I am using a RoomDatabase, a Repository, a Viewmodel and Livedata. Areas have a 1 to n relationship with Gateways and Gateways a 1 to n relationship with Items.
I created both an AreaWithGateways entity and a GatewayWithItems entity.
Items can move from a gateway to another, which is why I observe them with Livedata to keep track of which Gateway they're in. My problem now is that I found myself in need to also keep track of which Items are in which Areas and I can't figure out how to do that.
I've thought of merging the LiveData of each Gateway together and observing that using MediatorLiveData but I didn't really understand how to use it.
Or maybe it's possible to create an Entity AreaWithGatewayswithItems?
Any insight would be appreciated
Edit: I am adding some code to make the problem a bit clearer
This is the Area Entity
#Entity(tableName = "area_table")
public class Area {
#PrimaryKey(autoGenerate = false)
private int areaId;
private String areaName;
private float wertX;
private float wertY;
private Boolean isDrawn;
public int getAreaId() {
return areaId;
}
public void setAreaId(int areaId) {
this.areaId = areaId;
}
public String getAreaName() {
return areaName;
}
public float getWertX() {
return wertX;
}
public float getWertY() {
return wertY;
}
public Boolean getDrawn() {
return isDrawn;
}
public Area(int areaId, String areaName, float wertX, float wertY, Boolean isDrawn) {
this.areaId = areaId;
this.areaName = areaName;
this.wertX = wertX;
this.wertY = wertY;
this.isDrawn = isDrawn;
}
}
The Gateway Entity:
#Entity(tableName = "gateway_table")
public class Gateway {
private float temp;
private String title;
private int areaId;
#PrimaryKey(autoGenerate = false)
private int gatewayId;
public int getGatewayId() {
return gatewayId;
}
public void setGatewayId(int gatewayId) {
this.gatewayId = gatewayId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public float getTemp() {
return temp;
}
public void setTemp(float temp) {
this.temp = temp;
}
public int getAreaId() {
return areaId;
}
public Gateway(int areaId, int gatewayId, String title) {
this.title = title;
this.areaId = areaId;
this.gatewayId = gatewayId;
}
}
And the "Item" Entity:
#Entity(tableName = "cow_table")
public class Cow {
private int age;
private String sex;
private String name;
private boolean drawn;
private int gatewayId;
private String raceId;
#PrimaryKey(autoGenerate = false)
private int cowId;
public int getCowId() {
return cowId;
}
public void setCowId(int cowId) {
this.cowId = cowId;
}
public String getName() {
return name;
}
public boolean isDrawn() {
return drawn;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
public void setDrawn(boolean drawn) {
this.drawn = drawn;
}
public int getGatewayId() {
return gatewayId;
}
public String getRaceId() {
return raceId;
}
public Cow(int age, int cowId, int gatewayId,String name, String raceId, String sex, boolean drawn) {
this.age = age;
this.cowId = cowId;
this.sex= sex;
this.name = name;
this.drawn = drawn;
this.gatewayId = gatewayId;
this.raceId = raceId;
}
}
And this is the relation "AreaWithGateways":
public class AreaWithGateways {
#Embedded
private Area area;
#Relation(parentColumn = "areaId",
entityColumn = "areaId")
private List<Gateway> gatewayList;
public Area getArea() {
return area;
}
public List<Gateway> getGatewayList() {
return gatewayList;
}
public AreaWithGateways(Area area, List<Gateway> gatewayList) {
this.area = area;
this.gatewayList = gatewayList;
}
}
As well as GatewaysWithCows:
public class GatewayWithCows {
#Embedded
private Gateway gateway;
#Relation(parentColumn = "gatewayId",
entityColumn = "gatewayId")
private List<Cow> cowList;
public Gateway getGateway() {
return gateway;
}
public List<Cow> getCowList() {
return cowList;
}
public GatewayWithCows(Gateway gateway, List<Cow> cowList) {
this.gateway = gateway;
this.cowList = cowList;
}
}
I've been trying to find a way of getting all of the "items" in an Area as Livedata but still can't figure it out.
I feel like I should somehow use AreaWithGateways to add the LiveData items together but I can't reach the items through the gateways, it has to be the other way around.
Or maybe it's possible to create an Entity AreaWithGatewayswithItems?
Not an Entity as these are used to define tables BUT via POJO's using #Embedded and #Relation annotation (e.g. your GatewayWithCows is a POJO).
I feel like I should somehow use AreaWithGateways to add the LiveData items together but I can't reach the items through the gateways, it has to be the other way around.
You basically use a hierarchical approach but POJO's so as you have GatewayWithCows then relate to this from Area as per :-
class AreaWithGatewayWithCows {
#Embedded
Area area;
#Relation(entity = Gateway.class, parentColumn = "areaId",
entityColumn = "areaId")
List<GatewayWithCows> gatewayWithCowsList;
}
Note I missed the s after Gateway for the class name (and as such in the query below)
Note the use of entity = Gateway.class is required as the relationship is via the Gateway NOT via the GatewayWithCows (which isn't a table).
The Query Dao could be as simple as :-
#Query("SELECT * FROM area_table")
List<AreaWithGatewayWithCows> getAreaWithGatewaysWithCows();
amended accordingly for LiveData.
note that if you use JOINS in the query then the any clauses such as WHERE will only affect the Area's, not the underlying Gateways and Cows. That is irrespective of the query #Relation builds each Area with ALL Gateways related to that Area; and each Gateway gets ALL the Cows related to that Gateway.

Send array data from one class to another JAVA

(I'm a beginner so this may sound obvious/lack information.) I have an ArrayList of attributes for different pets including attributes such as their given-name, common-name, the price of the animal, sex, date bought and date sold. this information is generated from a separate class that adds an array of information to an array of arrays of the already existing list of animals. Essentially, I want to send the array to another class (called Pets) so it can then be added to the array of arrays. I understand this may sound confusing but this is the only way I can word it, I can clarify anything if needed. Any help would be great as I'm really stuck and can't work out how to send it. This is the code that generates my values in the array (using text-boxes to input the information).
public void actionPerformed(ActionEvent e) {
ArrayList<String> NewanimalArr = new ArrayList<>();
String givenName = txtGivenname.getText();
String commonName = txtCommonName.getText();
String priceOf = txtPrice_1.getText();
String sexOf = txtSex.getText();
String colourOf = txtMaincolour.getText();
String dateOfA = txtArrivaldate.getText();
String dateSold = txtSellingdate.getText();
NewanimalArr.add(givenName);
NewanimalArr.add(commonName);
NewanimalArr.add(priceOf);
NewanimalArr.add(sexOf);
NewanimalArr.add(colourOf);
NewanimalArr.add(dateOfA);
NewanimalArr.add(dateSold);
System.out.println(NewanimalArr);
}
});
this will then print information generated that is entered for example:
[alex, Dog, 40.50, Male, Brown, 14/04/2015, 14/12/2016]
how do I then send this data to another class
Option one Constructor Injection:
public class Foo {
List<String> actionPerformed(ActionEvent e) {
List<String> newanimalArr = new ArrayList<>();
.....
return newanimalArr
}
...
public class Pets {
private final List<String> array;
public Pets(final List<String> array) {
this.array = array;
}
void bar() {
System.out.println(this.array);
}
}
....
public static void main(String[] args) {
Foo foo = new Foo();
Pets pets = new Pets(foo.actionPerformed( new ActionEvent() ) );
pets.bar();
}
Option two Getter-Setter Injection:
public class Foo {
private final List<String> newanimalArr;
public Foo() {
this.newanimalArr = new ArrayList<>();
}
public void actionPerformed(ActionEvent e) {
.....
}
public List<String> getNewanimalArr() {
return new ArrayList<String>(newanimalArr);
}
}
...
public class Pets {
private List<String> array;
public Pets() {
this.array = Collections.<String>emptyList();
}
public void setArray(final List<String> array) {
this.array = array;
}
public void bar() {
System.out.println(this.array);
}
}
....
public static void main(String[] args) {
Foo foo = new Foo();
foo.actionPerformed( new ActionEvent() );
Pets pets = new Pets();
bar.setArray( foo.getNewanimalArr() );
pets.bar();
}
See also Dependency Injection Patterns
Create a class definition of Pet, using instance variables for the fields. In Java it is custom to create a setXyz and a getXyz for each xyz field. You can also create a constructor in which you pass all the values and assign them to the fields, this minimizes the risk of fields not being filled in.
The initial ArrayList you are creating doesn't add that much use, it is easier to create the Pet instances directly:
List<Pet> newArrivals = new ArrayList<>();
// get data from view fields and if necessary transform them to other objects such as:
LocalDate arrivedOn = LocalDate.parse(txtArrivaldate.getText(), DateTimeFormatter.ofLocalizedDate(FormatStyle.FormatStyle);
// create and add a new Pet object to the list
newArrivals.add(new Pet(.....));
public class Pet {
public enum Gender {
FEMALE, MALE
}
private String givenName;
private String commonName;
private double price;
private Gender gender;
private String color;
private LocalDate arrivedOn;
private LocalDate soldOn;
public Pet() {
}
public Pet(String givenName, String commonName, double price, Gender gender, String color, LocalDate arrivedOn,
LocalDate soldOn) {
super();
this.givenName = givenName;
this.commonName = commonName;
this.price = price;
this.gender = gender;
this.color = color;
this.arrivedOn = arrivedOn;
this.soldOn = soldOn;
}
public String getGivenName() {
return givenName;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public String getCommonName() {
return commonName;
}
public void setCommonName(String commonName) {
this.commonName = commonName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public LocalDate getArrivedOn() {
return arrivedOn;
}
public void setArrivedOn(LocalDate arrivedOn) {
this.arrivedOn = arrivedOn;
}
public LocalDate getSoldOn() {
return soldOn;
}
public void setSoldOn(LocalDate soldOn) {
this.soldOn = soldOn;
}
}

Why would you need to use more than one constructor?

I am learning Java as of right now and have just been learned what constructors are. I do not understand why you would need more than one constructor if you need to initialize all variables.
To put it simply, you use multiple constructors for convenience (1st example) or to allow completely different initialization methods or different source types (2nd example.
You might need multiple constructors to implement your class to simply allow omitting some of the parameters that are already setup:
//The functionality of the class is not important, just keep in mind parameters influence it.
class AirConditioner{
enum ConditionerMode{
Automatic, //Default
On,
Off
}
public ConditionerMode Mode; //will be on automatic by default.
public int MinTemperature = 18;
public int MaxTemperature = 20;
public AirConditioner(){ //Default constructor to use default settings or initialize manually.
//Nothing here or set Mode to Automatic.
}
//Mode
public AirConditioner(ConditionerMode mode){ //Setup mode, but leave the rest at default
Mode = mode;
}
//setup everything.
public AirConditioner(ConditionerMode mode, int MinTemp, int MaxTemp){
Mode = mode;
MinTemperature = MinTemp;
MaxTemperature = MaxTemp;
}
}
Another example is when different constructors follow different procedures to initialize the variables.
For instance you could have a data table that simply displays a table of text. The constructor could get the data from either database OR a file:
class DataTable{
public DataTable(){} //Again default one, in case you want to initialize manually
public DataTable(SQLConnection con, SQLCommand command){
//Code to connect to database get the data and fill the table
}
public DataTable(File file){
//Code to read data from a file and fill the table
}
}
A class can have multiple constructors, as long as their signature (the parameters they take) are not the same. You can define as many constructors as you need. When a Java class contains multiple constructors, we say that the constructor is overloaded (comes in multiple versions). This is what constructor overloading means, that a Java class contains multiple constructors.
Having said that, it is completely dependent upon your implementation whether or not you want to create more than one constructor in your class but having more than one constructor can ease your life in many instances. Suppose below class doesn't have a default constructor:
public class Employee {
private int age;
private String name;
Employee(int age, String name){
this.age=age;
this.name=name;
}
}
So, while creating object of this class user would not be able to do so until he has age and name parameters handy which restricts the true functionality of Java objects as Objects' state should be able to be modified and populated at any time once initialized.
Per constructor has specific purpose. Sometimes we need more than one constructor (special in Entity domain case, when use ORM)
For example:
Empty constructor (no arguments) for reflection,
Constructor has argument(s) for create new instance (A a = new A('foo', 'bar');).
These're overload method(s).
Reality example:
package sagan.blog;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Type;
import org.springframework.util.StringUtils;
import sagan.team.MemberProfile;
import javax.persistence.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
/**
* JPA Entity representing an individual blog post.
*/
#Entity
#SuppressWarnings("serial")
public class Post {
private static final SimpleDateFormat SLUG_DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(cascade = CascadeType.PERSIST, optional = false)
private MemberProfile author;
#Column(nullable = false)
private String title;
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private PostCategory category;
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private PostFormat format;
#Column(nullable = false)
#Type(type = "text")
private String rawContent;
#Column(nullable = false)
#Type(type = "text")
private String renderedContent;
#Column(nullable = false)
#Type(type = "text")
private String renderedSummary;
#Column(nullable = false)
private Date createdAt = new Date();
#Column(nullable = false)
private boolean draft = true;
#Column(nullable = false)
private boolean broadcast = false;
#Column(nullable = true)
private Date publishAt;
#Column(nullable = true)
private String publicSlug;
#ElementCollection
private Set<String> publicSlugAliases = new HashSet<>();
#SuppressWarnings("unused")
private Post() {
}
public Post(String title, String content, PostCategory category, PostFormat format) {
this.title = title;
this.rawContent = content;
this.category = category;
this.format = format;
}
/* For testing only */
public Post(Long id, String title, String content, PostCategory category, PostFormat format) {
this(title, content, category, format);
this.id = id;
}
public Long getId() {
return id;
}
public MemberProfile getAuthor() {
return author;
}
public void setAuthor(MemberProfile author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public PostCategory getCategory() {
return category;
}
public void setCategory(PostCategory category) {
this.category = category;
}
public PostFormat getFormat() {
return format;
}
public void setFormat(PostFormat format) {
this.format = format;
}
public String getRawContent() {
return rawContent;
}
public void setRawContent(String rawContent) {
this.rawContent = rawContent;
}
public String getRenderedContent() {
return renderedContent;
}
public void setRenderedContent(String renderedContent) {
this.renderedContent = renderedContent;
}
public String getRenderedSummary() {
return renderedSummary;
}
public void setRenderedSummary(String renderedSummary) {
this.renderedSummary = renderedSummary;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getPublishAt() {
return publishAt;
}
public void setPublishAt(Date publishAt) {
this.publishAt = publishAt;
publicSlug = publishAt == null ? null : generatePublicSlug();
}
public boolean isDraft() {
return draft;
}
public void setDraft(boolean draft) {
this.draft = draft;
}
public void setBroadcast(boolean isBroadcast) {
broadcast = isBroadcast;
}
public boolean isBroadcast() {
return broadcast;
}
#JsonIgnore
public boolean isScheduled() {
return publishAt == null;
}
#JsonIgnore
public boolean isLiveOn(Date date) {
return !(isDraft() || publishAt.after(date));
}
public String getPublicSlug() {
return publicSlug;
}
public void addPublicSlugAlias(String alias) {
if (alias != null) {
this.publicSlugAliases.add(alias);
}
}
#JsonIgnore
public String getAdminSlug() {
return String.format("%s-%s", getId(), getSlug());
}
private String generatePublicSlug() {
return String.format("%s/%s", SLUG_DATE_FORMAT.format(getPublishAt()), getSlug());
}
#JsonIgnore
private String getSlug() {
if (title == null) {
return "";
}
String cleanedTitle = title.toLowerCase().replace("\n", " ").replaceAll("[^a-z\\d\\s]", " ");
return StringUtils.arrayToDelimitedString(StringUtils.tokenizeToStringArray(cleanedTitle, " "), "-");
}
#Override
public String toString() {
return "Post{" + "id=" + id + ", title='" + title + '\'' + '}';
}
}
Class Post even has 3 constructors named Post(){...}
Source: https://github.com/spring-io/sagan/blob/master/sagan-common/src/main/java/sagan/blog/Post.java
So, recall that the purpose of the constructor is to initialize (give them values).
So think of this model:
public class Car{
private String model; //Objects are null
private int year; // year = 0
Car(String model, int year ){
this.model = model;
this.year = year;
}
}
The Car object you create needs values for the model and the year. It would be great if you could just create a dummy car with just default values for each field, or take a string that looks like this:
"Ford 2016 or "Ford" and "2016" and create a Car object.
So, just create two more constructors with different signatures that accomplish that task.
Also, imagine we have another String field called owner. The owner of a car may not be know at the creation of this object, but your program may be able to function without it. So, we can use the same constructor above and the Car object's owner field will be set to null.
That's the purpose for multiple constructors. To give the programmer flexibility on saying what an object can be created from and which variables need to be initialized in the first place.
You may also find this useful:

How to use a variable of one class, in another in 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
}
}

Categories

Resources