如何将此多重继承转换为Java中的接口?

Posted

技术标签:

【中文标题】如何将此多重继承转换为Java中的接口?【英文标题】:how to convert this multiple inheritance to interfaces in Java? 【发布时间】:2014-06-01 21:38:20 【问题描述】:

我想实现下面的多重继承案例:

(取自http://www.learncpp.com/cpp-tutorial/117-multiple-inheritance/)

Person           Employee
   |_________________|
              |
           Nurse

最后我想打印员工和护士的工资。在 C++ 中,使用多重继承很容易做到,但我在使用 Java 时遇到了问题。

我有以下代码:

public class Person
    protected String name;
    protected int age;
    public Person(String name,int age)
        this.name=name;
        this.age=age;
    

和界面:

public interface Employee
    public double getSalary();

和护士班:

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;
    

但我不知道如何让 Employee 打印其薪水,因为它是一个接口。我不想使用其他名为 Employee 的抽象类。如何解决这个问题?

谢谢

【问题讨论】:

Java不支持多重继承,还是...??? 没有,但可以用接口模拟 Java 允许一个类扩展到另一个类。基本上,不可能有多重继承。 您不能“让员工打印其薪水”,因为正如您所说,它是Interface。接口仅仅定义了一个 API 契约,它们没有指定该 API 的任何类型的实现。你永远不能只拥有一个Employee,只有表现得像 Employee 的东西会说它们会。但是,我认为您的继承树一开始就不正确。为什么Employee 不是Person?我真的不明白你为什么需要多重继承。 看那个示例教程,它是多重继承的一个可怕的例子。它设计了一个玩具示例来简单地表明它可以完成,但没有出于任何实际原因这样做。 Employee 并不特别需要独立于 Person 存在。仅仅因为 C++ 允许您做某事,并不意味着您应该这样做。其实教程的结尾基本就这么结束了。 【参考方案1】:

假设所有员工都是人(除非你雇用猴子!!),你能不能不把课程串起来?

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 

【讨论】:

我从来没有得到 Oracle 允许扩展或扩展类的决定,以使定义完全不包含任何内容,而只是类型或标签说明符。 @Casey 实际上对Exception 类很有用,可以让你的try/catch 块更详细,并且不必解析错误消息。我同意在大多数其他情况下,如果定义为空,您实际上并不需要额外的类。在具有多重继承的语言中它会更有意义,因此您可以使用 mixins 构建一个类。 abstract 类也很有意义,因为您基本上只是在构建一些基础 API 集。【参考方案2】:

Java 只允许接口的多重继承,因此为了实现这一点,您必须为每个要组合的类定义一个接口,并将它们组合到一个类中,方法是将从部分接口派生的所有方法委托给它们的实施。

人机界面 - 正如你所定义的那样

PersonImpl 类

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 类

public final class EmployeeImpl implements Employee 
    private final double salary;

    public EmployeeImpl(double salary) 
        this.salary = salary;
    

    @Override
    public double getSalary() 
        return salary;
    

护士类 - 由其他类组成并将功能委托给它们:

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

建议为您编写的每个类定义一个接口,以便将来能够使用这种方法。

【讨论】:

不,请不要这样做。这不是继承,因为您必须在使用它的每个类中提供每个方法的定义。继承的全部意义在于类型 X 的实例“是”类型 Y 的实例,因此无需重新定义即可获得类型 Y 的所有方法。

以上是关于如何将此多重继承转换为Java中的接口?的主要内容,如果未能解决你的问题,请参考以下文章

当有现有类时,接口如何取代对多重继承的需求

Java中的多重继承

Java复习笔记4--实现多重继承

Java 8 是不是支持多重继承? [复制]

vb.net:接口中的多重继承

为啥要使用接口,多重继承与接口,接口的好处?