Can we use extends with Has a relationship - java

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.

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.

What makes the difference between the two examples below?

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.

Using composition as a workaround for inheritance in realm (android)?

In my app, I am using realm as a database platform. Realm has been great thus far- super easy to use, make queries, etc.-though, I have two qualms with it that I am trying to work around.
1) Realm does not support inheritance in model object classes which extend RealmObject.
- I am wondering if any developers out there have used composition as a workaround to the inheritance issue and if its worked for them.
- In other words, say I have a class "car" which extends RealmObject and then I have other classes such as "honda", "toyota", etc. Does it make sense to make separate car objects for each of these which contain either a honda, toyota, etc.?
2) Realm only supports getters and setters in model object classes
- My current workaround for this is by creating static methods within the model object classes.
- In other words, say I want to modify a honda's color, I would call something such as, Honda.updateColor(honda, blue).
- ^ Is this sloppy, or is this essentially the only way to handle such methods.
Really any feedback would be great!
A workaround I've used (in a nutshell)
Composition + Interface inheritance would allow you to get some polymorphism benefits back to your realmObjects.
Some code demonstration
interface IPerson {
String getName();
}
class Person extends RealmObject implements IPerson {
String name;
#Override
public String getName() {
return name;
}
}
interface IWorker extends IPerson {
int getSalary();
}
class Worker extends RealmObject implements IWorker {
Person person;
int salary;
#Override
public String getName() {
return person.getName();
}
#Override
public int getSalary() {
return salary;
}
}
Note
PrimaryKeys unfortunately have to be duplicated.
Check this answer of mine to get more details about this workaround.

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?

how to not inherit some or all parent persistence attributes

As shown below, i have the object Car with 2 persistence attributes:
public class Car {
#Column(name = "COLOR")
protected String color;
#Column(name = "BRAND")
protected String brand;
}
All objects that extends from Car use the 2 attributes, but in some the them, i want to exclude one or all attributes.
For example:
public class SpecialCar extends Car{
//how to tell here that i don't want to have Brand column
}
Thx for help
If you do not want it in SpecialCar then, to me, it means, it should not be in Car at all. Can't you simply remove it from Car?
I think that this is answered allready here:
Disabling inherited method on derived class
I also think that is not possible, but they give you a nice trick

Categories

Resources