I want to implement the following multiple inheritance case:
(took from http://www.learncpp.com/cpp-tutorial/117-multiple-inheritance/)
Person Employee
|_________________|
|
Nurse
at the end I want to print the salaries from Employee and Nurse. In C++ it is easy to be done by using multiple inheritance, but I have problems with Java.
I have the following codes:
public class Person{
protected String name;
protected int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
}
and the interface:
public interface Employee{
public double getSalary();
}
and the class Nurse:
public class Nurse extends Person implements Employee{
private double salary;
public Nurse(String name, int age, double salary){
super(name,age);
this.salary=salary;
}
#Override
public double getSalary(){
return salary;
}
}
but I do not have a clue how to make the Employee to print its salary, because it is an interface. I do not want to use other abstract class called Employee. How to fix this?
Thanks
Assuming that all employees are people (unless you are hiring monkeys!!), could you not chain the classes?
public class Person {
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
public class Employee extends Person {
private double salary;
public double getSalary(){
return salary;
}
}
public class Nurse extends Employee {
}
Java allows multiple inheritance of interfaces only, so in order to implement that you have to define an interface for every class you'd like to combine and compose them in a single class by delegating all methods derived from the partial interfaces to their implementation.
Person interface - as you've defined it
PersonImpl class:
public final class PersonImpl implements Person {
private final String name;
private final int age;
public PersonImpl(String name, int age) {
this.name = name;
this.age = age;
}
#Override
public String getName() {
return name;
}
#Override
public int getAge() {
return age;
}
}
EmployeeImpl class:
public final class EmployeeImpl implements Employee {
private final double salary;
public EmployeeImpl(double salary) {
this.salary = salary;
}
#Override
public double getSalary() {
return salary;
}
}
Nurse class - composed from to other classes and delegates the functionality to them:
public class Nurse implements Employee, Person {
private final Employee employee;
private final Person person;
public Nurse(String name, int age, double salary) {
person = new PersonImpl(name, age);
employee = new EmployeeImpl(salary);
}
#Override
public double getSalary() {
return employee.getSalary();
}
#Override
public String getName() {
return person.getName();
}
#Override
public int getAge() {
return person.getAge();
}
}
It's advisable to define an interface for every class you code in order to able that approach in the future.
Related
How can I create addWorker in interface? OfficeWorker inherits from Worker and now I want to make interface for few Workers. I don't know how to do it correct. void addWorker(Worker worker) and void addWorker(Worker worker) are wrong.
Interface
public interface TypeOfWorker {
void addWorker(Worker worker);
}
OfiiceWorker
public class OfiiceWorker extends Worker implements TypeOfWorker {
private int officeID;
private int intelectl;
private List<OfiiceWorker> ofiiceWorkers = new ArrayList<>();
public OfiiceWorker(String name, String surname, int age, int experience, String street, int building,
int local, String city, int officeID, int intelectl) {
super(name, surname, age, experience, street, building, local, city);
this.officeID = officeID;
this.intelectl = intelectl;
}
#Override
public void addWorker(OfiiceWorker ofiiceWorker) {
ofiiceWorkers.add(ofiiceWorker);
}
}
Worker
public abstract class Worker {
private int identifier;
private String name;
private String surname;
private int age;
private int experience;
private String street;
private int building;
private int local;
private String city;
public Worker() {
}
public Worker(String name, String surname, int age, int experience, String street, int building, int local,
String city) {
setIdentifier();
this.name = name;
this.surname = surname;
this.age = age;
this.experience = experience;
this.street = street;
this.building = building;
this.local = local;
this.city = city;
}
public void setIdentifier() {
this.identifier = (int) (System.currentTimeMillis() / 1000);
}
}
You should use generics to let compiler relax with your types. First make your interface generic:
public interface TypeOfWorker<T extends Worker> {
void addWorker(T worker);
}
Then declare the generic type of your class:
public class OfiiceWorke extends Worker implements TypeOfWorker<OfiiceWorke> {
With these modifications the below is fine:
#Override
public void addWorker(OfiiceWorke worker) {
I'm a beginner in Java and I need help with how I can declare a Manager class that inherits from the Employee class and adds a bonus instance variable to store a salary bonus. I have this code that I can work around and a test program that I can supply to test it. Any suggestions on how to implement the constructors and methods here
public class Demo {
class Employee {
int id;
public Employee() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
class Manager extends Employee {
double bonus;
public Manager() {
super();
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Manager m = new Manager();
m.setId(1);
m.setBonus(100);
System.out.println("Manger has an ID of " + m.getId() + " with a bonus of " + m.getBonus());
}
}
It will look like below. Study it, and see if you can understand it.
class Employee {
int id;
public Employee() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
class Manager extends Employee {
double bonus;
public Manager() {
super();
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
}
public class Demo {
public static void main(String[] args) {
Manager m = new Manager();
m.setId(1);
m.setBonus(100);
System.out.println("Manger has an ID of " + m.getId() + " with a bonus of " + m.getBonus());
}
}
Lets start with 3 fields id,name and Salary for Employee and manager gets an additional field bonus.The salary for Manager will have bonus component added to the salary.
For Employee class create an argument constructor and set all the fields.Create getters for the fields required.
public class Employee {
protected int id;
protected String Name;
protected double Salary;
public Employee(int id, String name, double salary) {
this.id = id;
this.Name = name;
this.Salary = salary;
}
public int getId() {
return id;
}
public String getName() {
return Name;
}
public double getSalary() {
return Salary;
}
}
The Manager class now will extend Employee class.Based on the requirement the only difference between employee and manager is the salary component.Since all the fields in Employee class is set as protected and we extend the Employee class the state of the field can be changed in the child class.
In the Constructor of Manager class the salary will be calculated as salary + bonus.
public class Manager extends Employee {
private double bonus;
public Manager(int id, String name, long salary,double bonus) {
super(id, name, salary);
this.bonus = bonus;
this.Salary = salary + this.bonus;
}
public static void main(String[] args)
{
Manager mng = new Manager(1,"Manager",10000,100);
Employee emp = new Employee(2,"Employer",10000);
System.out.println("MANAGER SALARY " + mng.getSalary()+" "+mng.getId());
System.out.println("EMPLOYER SALARY " + emp.getSalary()+" "+emp.getId());
}
}
This question already has answers here:
Why is each public class in a separate file?
(11 answers)
Closed 3 years ago.
I am using Eclipse to run this code program to test a Person class and its subclasses. In Eclipse it shows there are errors--that each child class must be defined in its own file.
I am learning Java, and would like to know if this is a must? Or can I make it work with parent and child classes all in one file? If I'm missing something, please point me in the right direction. Thank you!
Here is my code: [I put this is all in one file on Eclipse]
import java.util.*;
//Test program to test Person class and its subclasses
public class Test {
public static void main(String[] args) {
Person person = new Person("person");
Student student = new Student ("student");
Employee employee = new Employee("employee");
Faculty faculty = new Faculty("faculty");
Staff staff = new Staff("staff");
//invoke toString() methods
System.out.println(person.toString());
System.out.println(student.toString());
System.out.println(employee.toString());
System.out.println(faculty.toString());
System.out.println(staff.toString());
}
}
//Defining class Person
public class Person {
protected String name;
protected String address;
protected String phoneNum;
protected String email;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress () {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getEmail() {
return email;
}
public void setEmail (String email) {
this.email = email;
}
#Override
public String toString() {
return "Name:"+getName()+"Class:"+this.getClass().getName();
}
}
//Defines class Student extends Person
public class Student extends Person {
public static final String FRESHMAN = "freshman";
public static final String SOPHMORE = "sophmore";
public static final String JUNIOR = "junior";
public static final String SENIOR = "senior";
protected String classStatus;
public Student(String name) {
super(name);
}
public Student(String name, String classStatus) {
super(name);
this.classStatus = classStatus;
}
#Override
public String toString() {
return "Name:"+getName()+"Class:"+this.getClass().getName();
}
}
//Defines class Employee extends Person
public class Employee extends Person {
protected double salary;
protected String office;
protected MyDate dateHired;
public Employee(String name) {
this(name, 0, "none", new MyDate());
}
public Employee(String name, double salary, String office, MyDate dateHired) {
super(name);
this.salary = salary;
this.office = office;
this.dateHired - dateHired;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getOffice() {
return office;
}
public void setOffice (String office) {
this.office = office;
}
public MyDate getDateHired() {
return dateHired;
}
public void setDateHired(MyDate dateHired) {
this.dateHired = dateHired;
}
#Override
public String toString() {
return "Name:"+getName()+"Class:" + this.getClass().getName();
}
}
//Defines class Faculty extends Employee
public class Faculty extends Employee {
public static String LECTURER = "lecturer";
public static String ASSISTANT_PROFESSOR = "assistant professor";
public static String ASSOCIATE_PROFESSOR + "associate professor";
public static PROFESSOR = "professor";
protected String officeHours;
protected String rank;
public Faculty(String name) {
this(name, "9-5 PM", "Employee");
}
public Faculty(String name, String officeHours, String rank) {
super(name);
this.officeHours = officeHours;
this.rank = rank;
}
public String getOfficeHours() {
return officeHours;
}
public void setOfficeHours(String officeHours) {
this.officeHours = officeHours;
}
public String getRank() {
return rank;
}
public void setRank(String rank) {
this.rank=rank;
}
#Override
public String toString() {
return "Name:"+getName()+"Class:"+this.getClass().getName();
}
}
//Defines class Staff extends Employee
public class Staff extends Employee {
protected String title;
public Staff(String name) {
this(name, "none");
}
public Staff(String name, String title) {
super(name);
this.title=title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Override
public String toString() {
return "Name:"+getName()+"Class:"+this.getClass().getName();
}
}
//Define class MyDate
public class MyDate {
private int month, day, year;
public MyDate (int month, int day, int year) {
this.day=day;
this.month=month;
this.year=year;
}
}
Yes, there should be one class per file. Moreover, you are using the MyDate class in the Employee class, which you need to extend and you cannot extends more than one class, so it's better use the predefined Date class which is present java.util.Date. Import this in the Employee class.
import java.util.Date;
instead of this:
public Employee(String name, double salary, String office, MyDate dateHired)
use:
public Employee(String name, double salary, String office, Date dateHired)
There are some careless mistakes:
in Employee class
public static String ASSOCIATE_PROFESSOR + "associate professor";
change to:
public static String ASSOCIATE_PROFESSOR = "associate professor";
Similarly in faculty class
public static String ASSOCIATE_PROFESSOR + "associate professor";
put = instead of +.
Now this code will work.
Yes it is a must. One class per file. Class can have inner classes. You can define subclasses as inner classes. But I recommend putting them in separate files and don't use inner classes.
I have an abstract class which contains a variable 'name' that I want my child classes to initialize. Which of these would be the best way to do so.
Option 1. Use superclass constructor for initialization
#Getter
abstract class A {
private final String name;
protected A(String name) {
this.name = name;
}
}
class B extends A {
private static final NAME = "Raylan";
private final int age;
public B(int age) {
super(NAME);
this.age = age;
}
}
Option 2. Use a getter method.
abstract class A {
private final String name;
public abstract String getName();
}
class B extends A {
private static final NAME = "Raylan";
private final int age;
public B(int age) {
this.age = age;
}
#Override
public String getName() {
return NAME;
}
}
Having a private name in A without a way to access it is useless. Assuming a fully functional getName() in A, consider multiple constructors in B:
class B extends A {
private static final String NAME = "Raylan";
private final int age;
public B(String name, int age) {
super(name);
this.age = age;
}
public B(int age) {
this(NAME, age);
}
public int getAge() {
return age;
}
}
This allows re-use of A, otherwise there doesn't seem much point in B extending A. Composition, instead of inheritance, could be another option.
I have following classes :
Emp.java
final public class Emp {
private Integer id;
private String name;
private Department department;
public Emp(Integer id, String name, Department department) {
this.id = id;
this.name = name;
this.department = department;
}
public Department getDepartment() {
return department;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
Department.java
public class Department {
private Integer id;
private String name;
public Department(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
EmployeeTest.java
public class EmployeeTest {
public static void main(String args[]) {
Department dept1 = new Department(1, "dept1");
Emp emp = new Emp(1, "emp1", dept1);
emp.getDepartment().setName("dept2");
System.out.println("emp = "+emp);
}
}
Here Emp class is not purely an immutable class because somehow I am able to change the values of Department (as shown in the example).
What are the best possible changes which will make Emp class a pure Immutable class ?
In getters for non-primitive field, use this structure
public class Line {
private final Point start;
private final Point end;
public Line(final Point start, final Point end) {
this.start = new Point(start);
this.end = new Point(end);
}
public Point getStart() {
return new Point(start);
}
public Point getEnd() {
return new Point(end);
}
}
So, simply create new instance of department that is equals to previous
P.S. In my example you can see pure immutable class
EDIT:
Also you can add to Department class copy-contructor
public Department(final Department dep)
{ ... }
And to Employer
getDepartment()
{
return new Department(department);
}
See Efffective Java:
Item 15: Minimize mutability – 5 rules to follow.
Don’t provide any methods that modify the object’s state
Ensure that the class can’t be extended
Make all fields final
Make all fields private
Ensure exclusive acess to any mutable components
If you don't like removing setters and do initialization in a constructor, you can think about returning immutable (from the point of view of the Emp class) objects, which will web objects' copies, in getters (see https://stackoverflow.com/a/128712/1579085).
final public class Emp {
private Integer id;
private String name;
private Department department;
public Emp(Integer id, String name, Department department) {
this.id = id;
this.name = name;
this.department = (Department) department.clone();
}
public Department getDepartment() {
return (Department) department.clone();
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
And implement the method clone() in Department (which will implement the interface Cloneable) of course.
This approach is suitable, if you need to be able to modify Department, but the objects of the Emp class should be safe from those outer modifications.
make all attributes final, and remove all setters
Implement clone() in Department and make Emp return a clone of department in getDepartment().
If references to Department used in constructing Emp are available after construction, then Emp's constructor should clone given Department.