Solution: Interface or abstract class
To implement the problem, my choice was to extend an abstract superclass Employee:
UML class diagram: inheritage of abstract class
The reason for not to choose the implementation of an interface is, that the abstract class Employee has a lot of attributes and methods which can be reused in both subclasses. The code is more compact:
1 public abstract class Employee { // abstract class 2 3 private static int cntID = 1000; // reuseable code 4 5 protected int ID; 6 protected String name; 7 protected String occupation; 8 protected String workPlace; 9 10 Employee(String name, String occupation, String workplace) 11 { 12 ID = ++cntID; 13 this.name = name; 14 this.occupation = occupation; 15 this.workPlace = workplace; 16 } 17 public int getID() { 18 return ID; 19 } 20 public String getName() { 21 return name; 22 } 23 public String getOccupation() { 24 return occupation; 25 } 26 27 abstract protected String determineWorkPlace(); // only this has to be implemented by subclasses 28 }
The concrete subclass FulltimeEmployee takes over every attribute and member, only the abstract method determineWorkPlace() of superclass Employee has to be defined:
1 public class FulltimeEmployee extends Employee { 2 3 FulltimeEmployee(String name, String occupation, String workplace) { 4 super(name, occupation, workplace); 5 } 6 7 public String determineWorkPlace() { // Method has to be implemented by subclass 8 return workPlace; 9 } 10 }
The second concrete subclass Apprentice has to define the method determineWorkPlace() too. The method getOccupation() is overridden for demonstration purposes:
1 import java.text.SimpleDateFormat; 2 import java.util.ArrayList; 3 import java.util.Date; 4 5 public class Apprentice extends Employee { 6 private ArrayList<String> daysOfVocationalSchoolInstruction; // apprentice visits vocational school 7 8 Apprentice(String name, String occupation, String workplace, ArrayList<String> daysOfVocationalSchoolInstruction) { 9 super(name, occupation, workplace); 10 this.daysOfVocationalSchoolInstruction = daysOfVocationalSchoolInstruction; 11 } 12 13 @Override // method is overridden for demonstration purposes 14 public String getOccupation() { 15 return "apprentice " + occupation; 16 } 17 18 public String determineWorkPlace() { // has to be implemented by subclass 19 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("u"); // Day number of week (1 = Monday, ..., 7 = Sunday) 20 Date date = new Date(); 21 if(daysOfVocationalSchoolInstruction.contains(simpleDateFormat.format(date))) 22 return "vocational school"; 23 else 24 return workPlace; 25 } 26 }
For avoiding code dublication the two objects of subclasses of Employee are assigned to an ArrayList of type Employee. It can be iterated by a foreach loop:
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 8 Apprentice apprentice = new Apprentice("apprentice", "developer","E203", 9 new ArrayList<String>(Arrays.asList("1","2"))); // Day number of week (1 = Monday, ..., 7 = Sunday) 10 11 FulltimeEmployee fulltimeEmployee = new FulltimeEmployee("full-time employee", "developer", "E203"); 12 13 // no repeating of code by the use of a loop 14 ArrayList<Employee> employees = new ArrayList(Arrays.asList(apprentice, fulltimeEmployee)); 15 for (Employee employee : employees) { 16 System.out.println("ID: " + employee.getID() 17 + "\tName: " + employee.getName() 18 + "\tOccupation: " + employee.getOccupation() 19 + "\tWorkplace: " 20 + employee.determineWorkPlace() 21 ); 22 } 23 } 24 }
The output on monday and thuesday will be:
ID: 1001 Name: apprentice Occupation: apprentice developer Workplace: vocational school
ID: 1002 Name: full-time employee Occupation: developer Workplace: E203