2016-01-07 2 views
4

Сотрудник классаИспользование полиморфизма?

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; 
} 



} 

Механика Класс

public class Mechanic extends Employee{ 


public Mechanic(String name,String jobsheetnumber){ 
super(name,jobsheetnumber); 
} 
} 

Супервизор Класс

public class Supervisor extends Employee{ 


public Supervisor(String name){ 
super(name); 
} 
} 

Компания Класс [фрагмент]

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); 




} 

Сотрудник Cla ss - суперкласс класса Mechanic и Supervisor .. прямо сейчас я использую атрибуты Employee, т. е. имя и номер рабочего места в подклассах. Класс механики и супервизора

код работает нормально .. но что делать, если я хочу добавить расширенный функциональность в механике и супервизоре? то я не могу получить доступ к этим переменным, потому что ссылка на объект типа Employee.

Это правильное использование полиморфизма? что мы должны использовать super() в качестве конструктора каждый раз, когда мы создаем ссылку Супервизора/Механического объекта? мы не можем использовать расширенную функциональность внутри класса Supervisor и Mechanic?

+1

Вы можете привести ссылку, например: Supervisor superRef = (Supervisor) company.supervisor; затем получить доступ к специализированным свойствам на superRef – axlj

+1

Это не полиморфизм, это просто наследование. Полиморфизм будет иметь абстрактный метод у сотрудника и реализовать его по-разному для Механика и Супервизора. То, что вы не можете получить доступ к свойствам Supervisor и Mechanic через экземпляр вашей компании, - это только потому, что вы объявили своих членов как Employee. Вы должны объявить их соответственно Супервизором и Механиком. –

ответ

3

Если вы хотите вызвать конструктор non-zero-arg суперкласса, то да, вы должны его явно называть. Если конструктор суперкласса не имеет аргументов, вызов будет вставлен для вас.

Точка полиморфизма заключается в том, что объекты могут сами по себе заботиться о том, чтобы все остальные программы не управляли ими, поэтому внешняя программа ссылается на них посредством ссылки с типом интерфейса или суперкласса без чтобы узнать конкретный конкретный тип. Например, у всех сотрудников может быть метод работы, где эта работа имеет другую форму для супервизора, чем для механика; метод работы будет переопределен конкретными подклассами и может вызывать конкретные методы в подклассах. Таким образом, компания может перебирать всех сотрудников и работать над каждым из них, а работа определяется по-разному для разных подклассов сотрудника.

(На практике использование подклассов для описания ролей слишком негибкое для работы, поскольку у сотрудника может быть несколько ролей, или эти роли могут меняться со временем. Обычно лучше использовать композицию, назначая объекты Role для Employee.)

1

Лучшим использованием полиморфизма будет тот же интерфейс (методы) для различных реализаций. Поэтому вы можете решить, какая реализация будет использоваться во время выполнения.

Чтобы объяснить свою точку зрения, я приведу пример использования ваших классов.

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) 
     } 
    } 
} 

Используя пример:

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); 
} 

Если во многих местах в вашем коде вы пытаетесь выяснить, какой объект вы имеете дело с, вероятно, вы делаете это неправильно.

Я использовал ваши классы в своих примерах, чтобы облегчить ваше понимание, но, как предложил Натан Хьюз в этом случае, лучше использовать композицию вместо наследования.

1

Я рассмотрю описанный выше сценарий двумя способами.

Решение 1: (интерфейс как роли)

  1. Вы можете иметь "состояние" в Employee объекта и вы можете реализовать роль в качестве интерфейса.
  2. Employee будет иметь все общие атрибуты & методов. Вы можете переопределить метод базового класса, напримерdoWork() в соответствующих реализациях Employee.
  3. Вы можете добавить определенное поведение Mechanic, Supvervisor с использованием интерфейсов.

    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(){ 
    
        } 
    } 
    

Решение 2: (Украсьте роль)

Реализовать Decorator шаблон для Employee играть несколько ролей. Mechanic и Supervisor будут украшать поведение Employee. См. Этот пример для лучшего понимания шаблона Decorator.

Пример кода можно найти @

When to Use the Decorator Pattern?

Смежные вопросы