使用多态?

时间:2016-01-07 03:38:47

标签: java oop polymorphism

员工类

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




}

Employee Class是Mechanic和Supervisor类的超类。现在我使用Employee的属性,即子类Mechanic和Supervisor Class中的name和jobsheetnumber

代码工作得很好..但是如果我想在Mechanic和Supervisor中添加扩展功能呢?然后我无法访问这些变量,因为引用是Employee类型对象。

这是正确使用多态吗?我们每次创建Supervisor / Mechanic对象的引用时都必须使用super()作为构造函数? 我们不能在Supervisor和Mechanic Class中使用扩展功能吗?

3 个答案:

答案 0 :(得分:3)

如果要调用超类非零arg构造函数然后是,则必须显式调用它。如果超类构造函数没有参数,那么将为您插入调用。

多态性的观点是,对象可以自己处理,而不必让程序的其余部分对它们进行微管理,因此外部程序通过引用具有接口或超类的类型来引用它们而不必要知道确切的具体类型。例如,所有员工可能都有一种工作方法,其中该工作采用与主管不同的形式,而不是机械师;工作方法将被特定的子类覆盖,并可能调用子类上的特定方法。因此,公司可以遍历所有员工并调用每个员工的工作,而不同员工的子类对工作的定义也不同。

(实际上,使用子类来描述角色的工作太不灵活,因为员工可能有多个角色,或者这些角色可能会随着时间的推移而发生变化。使用组合通常会更好。这里将角色对象分配给雇员。)

答案 1 :(得分: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);
}

如果您的代码中的许多地方都试图找出您正在处理的对象,那么您可能做错了。

我在我的示例中使用了您的类来促进您的理解,但正如Nathan Hughes在这种情况下建议使用组合而不是继承更好。

答案 2 :(得分:1)

我将以两种方式处理上述情况。

解决方案1 ​​:(作为角色的界面)

  1. 您可以在Employee对象中拥有“状态”,并且可以将角色实现为接口。
  2. Employee将拥有所有常见属性&amp;方法。 您可以在各自的Employee实现中覆盖基类方法,如 doWork()
  3. 您可以使用接口添加MechanicSupvervisor的特定行为。

    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(){
    
        }
    }
    
  4. 解决方案2 :(装饰角色)

    Employee实施Decorator模式以扮演多个角色。 MechanicSupervisor会修饰Employee行为。请参阅此示例以更好地理解Decorator模式。

    示例代码可以在@

    找到

    When to Use the Decorator Pattern?