Java object extensions - java

So i'm in the process of building a movie hiring system and have come to conclusion that I want to have a class of movies (which have specific movie data stored) and then another class which will have objects which extend the specific movies (eg, copies of Star wars: the new Hope) each with their own unique ID.
How do I setup my classes so that the information for each unique movie is inherited by the copy objects? (will extending my movieCopy class by my movies class achieve what I'm trying to do? Because I was thinking that would just extend the variables of the movie class, rather than the specific attributes of each object of the movie class.
Sorry in advance for any communication errors. Please feel free to ask if you need me to clarify something.
Structure I'm trying to achieve:
Movie (class)
MovieCopy(class)
MovieCopy <- attributes of the specific movie are inherited in each copy of the movie

Your MovieCopy class (DVD, Bluray, ...) could just contain a member variable storing the associated Movie instance (actual film with title, description, ...). That way you have access to all the meta data without any awkward inheritance.
class Movie {
private long id;
private String title;
private LocalDate release;
private String contentDescription;
Movie(long id, String title) {
this.id = id;
this.title = title;
}
...
}
class MovieCopy {
private long copyId;
private Movie movie;
private LocalDate lastHired;
private LocalDate latestReturn;
MovieCopy(long id, Movie movie) {
this.copyId = id;
this.move = movie;
}
...
}
EDIT - You would populate your collection of movies like this:
Movie starWars4 = new Movie(1, "Star Wars 4");
MovieCopy starWarsDvd1 = new MovieCopy(1, starWars4);
MovieCopy starWarsDvd2 = new MovieCopy(2, starWars4);
MovieCopy starWarsDvd3 = new MovieCopy(3, starWars4);
As a result you have three copies of the same Movie.

In your case, inheritance is not very suitable. What you are trying to do is create objects. You don't even need a MovieCopy class. You store the specific details of each movie in the movie objects.
Let's assume that your movie class has a name and a durationInMinutes fields and they both have getters and setters. If you want to create a new movie copy, you can do this:
Movie movie = new Movie ();
movie.setName("Star Wars");
movie.setDurationInMinutes (150);
And then you can refer to Star Wars using the variable name --- movie.
You might have other fields in your Movie class but you get the idea, right?
Let me show you when to use inheritance: if you have a kind of movie that has some attributes that ordinary movies don't have, which I can't give you an example because there is only one kind of movie.

Related

Abstract object in constructor java

For a computer science project I have a Movie class that implements Comparable with Comedy, Action, and MovieTrilogy extending it. The problem I am having is that MovieTrilogy takes 3 Movie objects in the constructor. The MovieTrilogy class needs to have the Movie objects as instance variables which means I need to declare an abstract object. I belive what my teacher would want is to declare the MovieTrilogy object with Comedy and Action objects, but I would still need to store them as instance variables. How would I do this? The movie constructor as well as the MovieTrilogy class are atatched below.
public class MovieTrilogy extends Movie{
private Movie movie1;
private Movie movie3;
private Movie movie2;
public MovieTrilogy(Movie Movie1, Movie Movie2, Movie Movie3){
movie1 = Movie1;
movie2 = Movie2;
movie3 = Movie3;
}
And this is the movie class.
public abstract class Movie implements Comparable<Movie>{
private int Score;
private String Title;
public Movie(String title, int score){
Title = title;
Score = score;
}
public int getScore(){ return Score; }
public String getTitle(){ return Title; }
public int compareTo(Movie movie){
return this.compareTo(movie);
}
public String getGenre(){
return null;
}
public String toString(){
return Title + " with a score of " + Score;
}
}
The code below is the error it gives me trying to compile MovieTrilogy.
MovieTrilogy.java:5: error: constructor Movie in class Movie cannot be applied to given types;
public MovieTrilogy(Movie Movie1, Movie Movie2, Movie Movie3){
^
required: String,int
found: no arguments
Okay so first let me address your specific error. In order for MovieTrilogy to extend Movie it has to satisfy the constructor that you enforced in the Movie class. So in order to construct a Movie (and consequently a MovieTrilogy) you have to provide a title and a score via a super method in the constructor.
So something like this:
public MovieTrilogy(Movie Movie1, Movie Movie2, Movie Movie3) {
super("Trilogy title", 0);
movie1 = Movie1;
movie2 = Movie2;
movie3 = Movie3;
}
However I wonder whether it is a good idea for MovieTrilogy to extend a Movie, as a trilogy doesn't really represent a specific movie, so can't be expected to have the same properties a movie does. I would recommend researching into inheritance as a programming concept to get some more clarity on how you should be thinking about it.
From the fact your constructor takes title and score it seems like you might be trying to represent some form of media that is rated so maybe you could have a structure like this:
class RatedTitle(String title, int score);
class Movie(String title, int score) extends RatedTitle(title, score);
class MovieTrilogy(String title, int score, Movie[] movies) extends RatedTitle(title, score);
(I hope you can think of a much better name than RatedTitle)
Edit
As #JohnHenly pointed out and said so eloquently,
Movie#compareTo(Movie movie) is looking a little infinite.
You seem to have a misunderstanding of implementing the Comparable interface and at the moment using the comparison method will result in a StackOverflowException. By returning this.compareTo(movie) you are trying to call the compareTo method defined in Movie which will then attempt to return this.compareTo(movie) again and again until the JVM can't take it anymore.
There are many articles that explain how to override toCompare properly but you might want to read this one because of the amazing title: Add the Comparable flavor, and taste the feeling.

Updating ArrayLists that contains each other?

Apologies if there have been similar questions, I'm honestly not sure how to call this concept to search for questions.
So I need to create a database with 3 classes like below:
public class Actor {
private String name;
private ArrayList<Movie> movies; //all movies the actor has been in
}
public class Movie {
private String name;
private ArrayList<Actor> actors;
}
public class MovieDatabase {
private ArrayList<Movie> movieList;
private ArrayList<Actor> actorList; //all actors in the movie
}
I have to create a method to add a movie and an actor to the database.
The final goals is that the new movie needs to be of the Movie class, and contains all the actors that are in it, same for the new actor.
What I cannot figure out is that, since the Movie class contains an array of Actor objects, and the Actor class contains an array of Movie list, how do you update so that in the end, the new Movie added contains a complete list of Actors in it, with each Actor in the list having their movie lists updated with the new Movie object?
Is recursion the right concept to apply in this case?
Suppose a new Movie gets added
Movie movie = new Movies();
movie.setActors(listOfActors)
Now for each actor you need to update the movie list
listOfActors.forEach(actor -> addMovieToActor(movie,actor));
public addMovieToActor(Movie movie,Actor actor){
List<Movies> existingMovies =actor.getMovies();
existingMovies.add(movie);
}
Depending on your needs, you may need to take care of synchronization between updates.
I don't think recursion is appropriate here, although you could use it. The databases have a circular dependency so you just need to synchronize after updates. In other words, make sure that after you add a new entry, both databases are updated with the missing information. Synchronization can be made easier by swapping ArrayList out for a HashMap, you may need to refactor your classes to do this. I left out the lists for simplicity, you can add them in as a parameter:
void update(String movieName, String actorName) {
if (movies.get(movieName) == null) {
movies.put(movieName);
}
if (actors.get(actorName) == null) {
actors.put(actorName);
}
}
Use as:
HashMap<String> actors = new HashMap<>();
HashMap<String> movies = new HashMap<>();
actors.put("foo");
movies.put("bar");
// Update happened, synchronize with what you just added
update("foo", "bar");

Differentiating Composition and Aggregation programmatically

I was going through below link to figure out differentiation between Composition and Aggregation.
https://www.geeksforgeeks.org/association-composition-aggregation-java/
I am able to understand that Composition implies a relationship where the child cannot exist independent of the parent while Aggregation implies a relationship where the child can exist independently of the parent. But not able to understand how can i differentiate that programmatically . Below is an example of Aggregation and Composition as given in link.In both cases the classes are same in structure except that Student and Department class has an extra variable "name" .As in Composition "child cannot exist independent of the parent ",but here I can create a separate object of Book and use it without adding it to Library.
Aggregation
// student class
class Student
{
String name;
int id ;
String dept;
Student(String name, int id, String dept)
{
this.name = name;
this.id = id;
this.dept = dept;
}
}
/* Department class contains list of student
Objects. It is associated with student
class through its Object(s). */
class Department
{
String name;
private List<Student> students;
Department(String name, List<Student> students)
{
this.name = name;
this.students = students;
}
public List<Student> getStudents()
{
return students;
}
}
Composition
class Book
{
public String title;
public String author;
Book(String title, String author)
{
this.title = title;
this.author = author;
}
}
// Libary class contains
// list of books.
class Library
{
// reference to refer to list of books.
private final List<Book> books;
Library (List<Book> books)
{
this.books = books;
}
public List<Book> getTotalBooksInLibrary()
{
return books;
}
}
As far as I can tell (and maybe somebody else can give a better answer), you can't evaluate if the relationship is aggregation or composition just by looking at Java code. It's the other way around.
First you create a conceptual model of the world. Libraries have books, and cars have wheels. Then you think - does it make sense for a book to exist without a library, or for a wheel to exist without a car, in the context I'm working in. So for example if you are writing a car racing game, you will have no use of wheels outside of cars. But if you are writing some auto-repair application, you will deal with wheels independently of some particular car.
So first you decide if you need aggregation or composition, and then implement it in your code. The implementation could be that object Car has List<Wheel> but you can't tell if it's composition or aggregation just from that. The key is that you interpret the code (implementation) based on your conceptual model and then use it according to that.
If it's composition, the usage it might have some restrictions:
No object other than Car will hold a reference to Wheel.
Wheel might even be a private or package-private class.
If Car is saved in database, when you delete it, you also automatically delete all of its Wheels.
But it's up to you to enforce these restrictions if you decide it's composition.
In the real world, a book can indeed exist in its own right without being owned by a library. But what if, instead, you had a LibraryBook class with fields like dateAcquired and currentBorrower? Using your design, you would still be able to create a LibraryBook instance without a library.
This is where languages like C++ can be more explicit about composition: in C++, an object can hold its parts by value. In Java, every object is handled by a pointer (OK, Java people don't call them pointers; they call them references instead.) This makes it more difficult to differentiate between composition and aggregation. In Java, you do it using careful design.
For example, we can make the LibraryBook class only instantiable through a method of Library:
class Library {
class LibraryBook {
private LibraryBook() {/*private constructor prevents independent instantiation*/}
}
LibraryBook createBook(String title, etc...);
}
Furthermore, if we make LibraryBook's mutator methods only accessible to the Library class, we can ensure that the book remains part of its owning library.

Individual information in the DTO for the logged-in user

My controller returns the DTO of the Movie object
public class Movie {
private final String title;
private final MovieType type;
private final List<LanguageType> languages;
private final List<CountryType> countries;
...
}
This is the standard movie object I'm returning after calling / movies / {id}. However, I would like to return the rating of the logged in user along with this video. As is the case with, for example, other services like IMDB. When you enter the movie site, this is only a general rating, but if you log in to your account and rate the video, your rating will be given on the video page. So I thought to add to the DTO Movie object the box yourRating where your rating will be given if you are logged in and rated the video. It would look like this way
public class Movie {
private final String title;
private final MovieType type;
private final List<LanguageType> languages;
private final List<CountryType> countries;
private final Float yourRating; \\ Twoja ocena
...
}
I created a thread about it on SO and the user there suggested to create a new UserMovie object inheriting from Movie and having only one additional field of yourRating.
I wanted to ask you if this is how it should look like, that the offline user / movies / {id} returns DTO Movie, and the currently logged DTO UserMovie object (inherits all Movie fields + yourRating field). Is it necessary to separate in such a way individual data for the logged in user.

How to design objects for simple school application [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I want to create simple school application that provides grades,notes,presence,etc. for students,teachers and parents. I'm trying to design objects for this problem and I'm little bit confused - because I'm not very experienced in class designing. Some of my present objects are :
class PersonalData() {
private String name;
private String surename;
private Calendar dateOfBirth;
[...]
}
class Person {
private PersonalData personalData;
}
class User extends Person {
private String login;
private char[] password;
}
class Student extends Person {
private ArrayList<Counselor> counselors = new ArrayList<>();
}
class Counselor extends Person {
private ArrayList<Student> children = new ArrayList<>();
}
class Teacher extends Person {
private ArrayList<ChoolClass> schoolClasses = new ArrayList<>();
private ArrayList<Subject> subjects = new ArrayList<>();
}
This is of course a general idea. But I'm sure it's not the best way. For example I want that one person could be a Teacher and also a Parent(Counselor) and present approach makes me to have two Person objects. I want that user after successful logging in get all roles that it has (Student or Teacher or (Teacher & Parent) ). I think I should make and use some interfaces but I'm not sure how to do this right. Maybe like this:
interface Role {
}
interface TeacherRole implements Role {
void addGrade( Student student, Grade grade, [...] );
}
class Teacher implements TeacherRole {
private Person person;
[...]
}
class User extends Person{
ArrayList<Role> roles = new ArrayList<>();
}
Please if anyone could help me to make this right or maybe just point me to some literature/article that covers practical objects design.
In a system like this, it seems like you can create a User class that has all the personal properties as well as account information in it:
public class User
{
// personal properties
private String name;
private String surname;
private Calendar dateOfBirth;
// account properties;
private String login;
private String password; // note that string may be more convenient than char[]
// role properties
public ArrayList<Role> roles;
...
public bool hasRole(Role role) // or isInRole(Role role)
{ // implementation here. }
}
Then you have your Role object:
public class Role
{
private String name;
private String description;
}
Note that there is only one role class that could be any of teacher, student, parent, etc. Since the Role class is generic, we do not have functions in it such as addGrade(), since that is specific to a teacher.
When the user logs in with proper credentials, such a system would already know the roles associated with the user. Usually, role-specific tabs, links, and other UI elements would show (or not show) depending on the role. This is where you check to see if the user logged in is in a particular role (user.hasRole(...)). For each UI element whose visibility is determined by the role, you would have to have an if (user.hasRole(...)).
In regard to the composition issues, this system is one that heavily relies on relationship between objects. Let's consider the relationship between students and counselors - a counselor has students assigned to him/her. Likewise, any given student has many counselors. You've got a many-many relationship which calls for a structure that keeps track of the combination of unique student-counselor pairs:
public class StudentCounselor
{
public User student;
public User counselor;
}
And who keeps track of all of this? Most likely the system itself, not another user.
public class SystemAdministration
{
public static ArrayList<StudentCounselor> studentCounselors = new ArrayList<StudentCounselor>();
public static void addStudentCounselor(User student, User counselor)
{
// Check to see first that the student-counselor combo doesn't exist
studentCounselors.addItem(student, counselor);
// addItem may not be the precise name of the function in ArrayList.
}
// function to obtain all students of a counselor
public static ArrayList<User> getStudentsOfCounselor(User counselor)
{
// iterate through the studentCounselors ArrayList and pick only
// the Student-Counselor whose counselor is the same counselor
// as the one passed into this function.
// Then extract the student property out of the fitting
// Student-Counselor.
// Return the list of students.
}
public static ArrayList<User> getCounselorsOfStudent(User student)
{
// Similar as above, but the other way around.
}
}
You would do similar for your other relationships - parent-student, teacher-sections, etc. The SystemAdministration class is NOT a role, but the entity responsible for providing you with all the data.
As a suggestion, consider the Section object:
public class Section
{
public User teacher; // who teaches it
public Course course; // what is the subject, because > 1 teacher might teach the same one.
public TimeBlock timeBlock; // when is this section administered?
public Venue venue; // what room or what facility
}
You would have to create the TimeBlock and Venue classes. This structure, when put in an ArrayList will be able to answer the questions: "As a teacher, what sections will I teach?" and that answers the question "what subjects, when, and where will I teach them?"
As for the student, you'll need the StudentSection "combo" class:
public class StudentSection
{
public Section section;
public User student;
}
When put in an ArrayList of the SystemAdministrator class, now you can iterate through the list to extract what sections are assigned to a student (aka, the student's schedule), and likewise, who are the students of a given section.
Note that we don't have a list of related items in the User class except roles. To obtain any data, info about the logged-in user and his/her roles should be sufficient as long as you have all the data and access functions in a global (in this case SystemAdministration) structure.
There is no "right" design; it all depends on how you plan to interact with these classes/interfaces. Try to sketch the methods you intend to call, in the most natural possible way, and work from those to understand what a good layout for your classes could be. If you feel brave, try learning the Test Driven Development methodology; writing actual unit tests before the "real" code can help make your mind on the class structures.
As a general suggestion, try to avoid inheritance, and favor composition instead. Having an array of Role elements is a step towards that direction; try to understand you plan to interact with these roles, and add methods accordingly.

Categories

Resources