What makes the difference between the two examples below? - java

What makes composition different from aggregation they are both declared as private, is it in composition example we are creating an object of Address class in constructor of Person, if it's then how this makes the Person object control/own the Address object.
public class Person {
private String firstName;
private String lastName;
private Address address;
//Composition example
public Person() {
address = new Address();
}
public Address getAddress() {
return address;
}
}
Employee Class
public class Employee {
private String firstName;
private String lastName;
private int age;
//Aggregation Java example
private Address address;
public void setAddress(Address address) {
this.address = address;
}
public Address getAddress() {
return address;
}
}

Well, let me first start by explaining the differences between Aggregation and Composition.
Aggregation:
1. A child in an Aggregation relationship can exist independently of the parent
2. Aggregation can be read as "HAS A"
Example: If we have a class Wheel, the relationship between the class Wheel and Car is an Aggregation: "A car has four wheels". A Wheel can exist out of the context of a car.
Composition:
1. A child in an Composition relationship cannot exist independently of the parent. In other words, there's no sense of for the child class to exist if it cannot be hosted into the parent class.
2. Composition can be read as IS PART OF
Example: If we have a class Human, the relationship between the class Heart and Human is composition. You never seen a heart hanging out by itself, don't you? Hence, the need for Composition.
In Java we represent the Composition relationship using private final
class Human { private final Heart heart; }
While Aggregation would be just:
class Wheel { ... }
class Car { private List<Wheel> wheels; }
Now let's say, we would like to remove an object of class Human (taking into account he is not an organ donor) completely, the Composition relationship forces us to destroy the instance of the heart related to that human being. In Aggregation it is not the case, the wheels can be used by another car if the instance of the car they used to belong to got wrecked.
I hope this helps.

Related

Why is this class better suited to be abstract instead of concrete?

Why is this Student class (a class which creates new student objects and assigns them unique ID's) better suited to be an abstract class rather than a concrete class? Each student object created is assigned it's own unique ID right, so why not just have the implementation for the graduate() method inside the class itself rather than implemented by an inherited class?
public abstract class Student {
protected int id;
private static int lastID = 0;
protected String firstName;
protected String familyName;
public Student(String firstName, String familyName) {
id = Student.nextID();
this.firstName = firstName;
this.familyName = familyName;
}
private static int nextID() {
return ++lastID;
}
public String toString() {
return firstName + " " + familyName;
}
// Generate string containing graduation information
public abstract String graduate();
}
The point would be: if you have various sub classes of Student, each one coming with a distinct differentiating attribute, say "major class".
Thus: this model would only allow students with a distinct "major class", therefore it would be meaningful to prevent creating "raw" Student objects that lack the corresponding "attribute".
But you have to understand: the reasons that determine how exactly you build your object model (which classes are abstract, and which ones are not) are coming out of what you intend to model.
In other words: the person writing this abstract Student class deemed that doing it exactly like this would be the best fit to the underlying requirements. In a different context, Student might very will be not abstract.
Generally a student class is written as abstract because of the types of students that you will have. i.e, high school, college, etc.
Some students have information that others don't. For instance, a college student may have a dorm number where a high school student wouldn't. The abstract class allows you to have more flexibility and not lock in a singular definition for student.

Java use 2 different object types as a field in a class

I have a class that can take different objects as a field to serve a similar purpose as below;
public class Project {
private int id;
private String title;
private String description;
private Implementer implementer;
.....
}
The implementer can be an individual (with fields such as firstName, lastName etc) or a company (with fields like companyName, industry etc). How do I make the implementer reference these two types (Individual and company). Note I do not want them to extend a common base class as they have no common fields.
Thanks
Create a marker interface:
public interface Implementor {
}
Change classes to implement this interface:
public class Company implements Implementor {
...
}
public class Individual implements Implementor {
...
}
Now both of the following assignments are valid:
Implementor implementor;
...
implementor = new Company();
implementor = new Individual();

Can we use extends with Has a relationship

We use extends keyword for using is-a relationship in Java using OOP. But on the other side, we also have has-a relationship and we use reference of the first class in 2nd class for has-a relationship. My question is, if we have a has-a relationship, can we use extends keyword in implementation?
Suppose we have the example here:
A “university” has several “departments”. Without the existence of
“university”, there is no chance for the “departments” to exist.
Can we write it as (just a rough example for understanding)
class University extends Department
{
Department d = new Department();
University(String name, Department d)
{
this.Name=name;
this.Department = d;
}
}
or when we make an entity of one class in another we can not use word extends?
You cant do it with extends, but you could use an interface, as follows:
interface HasDepartments {
public Set<Departments> getDepartments();
}
class University implements HasDepartments {
private final String name;
private final Set<Department> departments = new HashSet<Department>();
University(String name, Collection<Department departments) {
this.name=name;
this.departments = departments;
}
public Set<Departments> getDepartments() {
return departments;
}
}
However, unless there were other things that could have departments, I wouldn't bother. Just University having a getDepartments() method is enough.
I suggest you to see this link, to understand difference between is-a and has-a relationship
What is the difference between IS -A relationship and HAS-A relationship? Java
also search for composition, aggregation, association in java (has-a relationship types)
to answer your question, There is no obstacle to use it but you need a good reason to inherit University from Department.

Use Of polymorphism?

Employee Class
public class Employee {
protected String name;
protected String jobsheetnumber;
public Employee(String n,String j){
this.name = n;
this.jobsheetnumber = j;
}
public Employee(String name)
{
this.name = name;
}
public String getName() {
return name;
}
public String getJobsheetnumber() {
return jobsheetnumber;
}
public void setName(String name) {
this.name = name;
}
public void setJobsheetnumber(String jobsheetnumber) {
this.jobsheetnumber = jobsheetnumber;
}
}
Mechanic Class
public class Mechanic extends Employee{
public Mechanic(String name,String jobsheetnumber){
super(name,jobsheetnumber);
}
}
Supervisor Class
public class Supervisor extends Employee{
public Supervisor(String name){
super(name);
}
}
Company Class [snippet]
public class Company {
private String companyname;
private String companyaddress;
private String postalcode;
private String city;
private String country;
private String telephonenumber;
private String faxnumber;
private String province;
private Employee supervisor;
private Employee mechanic;
public Company(String companyname,String companyaddress,String postalcode,String city,String country,String telephonenumber,String faxnumber,String province,String supervisorname,String jobsheetnumber,String mechanicname)
{
this.companyname = companyname;
this.companyaddress=companyaddress;
this.postalcode = postalcode;
this.city=city;
this.country=country;
this.telephonenumber=telephonenumber;
this.faxnumber=faxnumber;
this.province=province;
supervisor = new Supervisor(supervisorname);
mechanic = new Mechanic(mechanicname,jobsheetnumber);
}
Employee Class is the superclass of both Mechanic and Supervisor class .. right now i am using the attributes of Employee i.e name and jobsheetnumber in the subclasses Mechanic and Supervisor Class
the code works fine .. but what if i want to add extended functionality in Mechanic and Supervisor ? then i cannot access those variables because the reference is to the Employee type object.
is this the correct use Of Polymorphism ? that we have to use super() as the constructor each time we create a reference of Supervisor/Mechanic Object ?
can we not use extended functionality inside Supervisor and Mechanic Class ?
If you want to call a superclass non-zero-arg constructor then yes, you have to call it explicitly. If the superclass constructor has no arguments then the call will be inserted for you.
The point of polymorphism is so that objects can take care of themselves without having to have the rest of the program micro-manage them, so the outside program refers to them by a reference with the type of an interface or superclass without having to know the exact concrete type. For instance all employees might have a work method, where that work takes a different form for a supervisor than it does for a mechanic; the work method would be overridden by the specific subclasses, and might call the specific methods on the subclasses. So the company can iterate through all the employees and call work on each of them, while work is defined differently for different subclasses of employee.
(In practice using subclasses to describe roles is too inflexible to work, since an employee could have multiple roles, or those roles can change over time. It's usually better to use composition, here assigning Role objects to an Employee.)
A better use of polymorphism would be the same interface (methods) for different implementations. So you can decide which implementation will be used in runtime.
To explain my point i will give a example using your classes.
public class Employee{
public void work(int hours){ doNothing();}
}
public class Supervisor extends Employee{
private Object pen;
private Object note;
#Override
public void work(int hours){
observations = superviseWorkers();
note.write(observations, pen);
}
}
public class Mechanic extends Employee{
private Tool tool;
private TaskBoard taskBoard;
#Override
public void work(int hours){
task = taskBoard.getPendent()
if(task.canSolveWithTool(tool))
{
solveTask(task, tool)
}
}
}
Using example:
employees = new List<Employee>();
employees.add(new Supervisor("foo"));
employees.add(new Mechanic("bar"));
foreach(employee in employees){
//you don't need to know which kind of employee you are treating here because you are only calling a behavior that all employees have.
employee.work(8);
}
If in many places in your code you are trying to figure out which object you are dealing with probably you are doing it wrong.
I used your classes in my examples to facilitate your understanding but as Nathan Hughes suggested in this case would be better to use composition instead of inheritance.
I will handle above scenario in two ways.
Solution 1: ( Interface as roles)
You can have "state" in Employee object and you can implement role as interface.
Employee will have all common attributes & methods. You can override base class method like doWork() in respective Employee implementations.
You can add specific behaviour of Mechanic, Supvervisor with use of interfaces.
public interface ISupervise{
public void doSupervise();
}
public class Supervisor extends Employee implements ISupervise{
public void doSupervise(){
}
}
public interface IMechanic{
public void doMechanicWork();
}
public class Mechanic extends Employee implements IMechanic{
public void doMechanicWork(){
}
}
Solution 2: (Decorate role)
Implement Decorator pattern for Employee to play multiple roles. Mechanic and Supervisor will decorate Employee behaviour. Refer to this example for better understanding of Decorator pattern.
Sample code can be found #
When to Use the Decorator Pattern?

Best Approch of Returning Value from 'getter' Method

'Making the class field/property private' - is one of the best practice in OOP. To access the private field/property we can use public getter method. But only writing the getter method may not enough according to this blog(Please see Quote 2). It suggests returning a clone of the field/property (if it is a reference type) from the getter method. By following this approach we can make the field/property unmodifiable. Please see the code below -
public class Department{
Employee admin;
...
...
...
public Employee getAdmin(){
return admin.clone();
}
}
So from now the 'admin' is unmodifiable by the outer world if we don't use any setter. This approach looks pretty nice. But I hardly found any code which implements this approach. Is there any drawbacks of using this approach which may defeats the benefit of using this approach?
Thanks in advance.
The main drawback to this approach is the need to make a clone every time you get an object, which is not ideal, because ideally you prefer your getter to be lightweight.
There are two approaches that achieve similar effect without cloning:
Making Employee immutable, and
Giving Employee an immutable interface
The first approach is self-explanatory and is very efficient, but it is not always practical, especially in situations when your object represents state that needs to be shared in place.
The second approach is simple, too: rather than making Employee a class, make it an interface with only getters, make a class EmployeeImpl that implements Employee, and has getters and setters, and use the class when you need mutability.
public interface Employee {
String getFirstName();
String getLastName();
}
public class EmployeeImpl implements Employee {
private String firstName;
private String lastName;
public String getFirstName() {return firstName;}
public String getLastName() {return lastName;}
public void setFirstName(String name) {firstName = name;}
public void setLastName(String name) {lastName = name;}
}
This approach can be defeated by casting to a class, but most of the time it is OK.
If you are in a hostile environment where any modification to the actual object would be extremely harmful - say, you are exposing some API for your service that everyone could download and use, you would have to go for the full clone approach that you have described. However, situations like this are relatively rare.
Note: I changed this answer since it was first posted. The first solution I suggested had problems with inheritance which are now solved.
Cloning the objects returned is, generally, a very bad option. Unless the objects are very simple, or unless your application is not very complex, all this cloning will very likely introduce a significant overhead.
An alternative for your specific case is to have an interface called Employee that only offers getters. You can then also define the MutableEmployee class that implements Employee and also offers setters.
interface Employee {
public String getName();
public float getSalary();
}
class MutableEmployee implements Employee {
private String name;
private float salary;
#Override
public String getName() {
return name;
}
#Override
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
super.salary = salary;
}
public void setName(String name) {
super.name = name;
}
}
Your Department class would then modified like this:
class Department {
private MutableEmployee admin;
public Employee getAdmin() {
return (Employee) admin;
}
public MutableEmployee getMutableAdmin() {
return admin;
}
}
Defining subclasses of MutableEmployee
When you want to create a subclass of MutableEmployee, like MutableGraphicDesigner, you will need to define the following:
interface GraphicDesigner extends Employee
class MutableGraphicDesigner extends MutableEmployee implements GraphicDesigner

Categories

Resources