Java中多重继承的问题

3
我希望能在Java中建模以下类: enter image description here 我编写了下面的代码:
class Person
{
    private String name;
    private ing age;
    public Person(String name, int age){
        this.name=name;
        this.age=age;
    }
    //set and get methods
}

class Employee
{
    private String nameEmp;
    private double salary;
    public Employee(String nameEmp, double salary){
        this.nameEmp=nameEmp;
        this.salary=salary;
    }
    public double calcSalary(){}   //should this be an abstract method?
}

class Teacher extends Person implements Employee
{
    private String nameTeacher;
    private int ageTeacher;
    private String title;   //professor or lecturer
    public Teacher(String nameTeacher,int ageTeacher, String title){
        super(nameTeacher,ageTeacher);
        this.title=title;
    }
    public double calcSalary(){
        if (title.equals("Professor")) salary=salary*0,30;
        else if (title.equals("Lecturer")) salary=salary*0,10;
    }
}

我希望使用接口来建模,但我不太确定该如何实现。另外,在Employee中,calcSalary应该是一个抽象方法吗?如何在Java中使用接口实现它?谢谢。

1
你可以这样说: class Teacher implements Person, Employee - The Cat
3
我认为你的例子有点令人困惑。一个更好的例子可能是:老师雇员,而雇员又是 - Balázs Németh
到目前为止,没有人告诉他不能实现一个类吗? - Djon
1
老师是一个人,还是一个人在特定环境中扮演的角色,或者是员工的角色描述等? - Mark Rotteveel
@jma,你可以用Java写FORTRAN,但这不是一个好主意。当使用一种语言时,应该使用该语言的建模范式。Java没有多重继承,所以放弃那种思路。这样就只剩下了多层单一继承或接口,其他人已经向你建议过这些。如果你想要方法的实现,你需要前者,因为目前接口不提供实现。 - pjs
显示剩余6条评论
5个回答

4
不,你不能这样做,应该采取教师是 -> 员工是 -> 人员的方式。你不能在接口中实现任何东西!接口只能包含由类实现的方法。

3
你可以使用这个:

你可以拥有这个:

public interface Person{
    // Only abstract methods here
}

public interface Employee extends Person {
    // Only abstract methods here specific to Employee
}

public class Teacher implements Employee {
    //Implements the methods 
}

2

Java 8将允许您在接口中放置默认实现。在此之前,接口不能包含实现。


我不明白你怎么在接口中实现getter和setter。 - Luiggi Mendoza
1
我认为你真正想问的问题是“如何在Java中实现多重继承?”,而答案是,你不能。 - Anonymoose
不,那不是我的问题。我只是想知道,即使知道Java 8支持为方法提供默认实现,你如何为getter和setter创建默认实现以解决这个问题? - Luiggi Mendoza
顺便说一句,我支持Balázs Mária Németh的评论。一个“教师”应该继承自“雇员”,而“雇员”应该继承自“人”。 - Luiggi Mendoza
我并不是在争论或抱怨接口是否应该为方法提供默认实现。我只是想知道这如何解决 OP 目前的设计问题。 - Luiggi Mendoza
显示剩余2条评论

0
public interface Person {
    String getName();
    void setName(String name);
    int getAge();
    void setAge(int age);
}

public class PersonImpl implements Person {
    private String name;
    private int age;
    @override public String getName() { return this.name; }
    @override public void setName(String name) { this.name = name; }
    @override public int getAge() { return this.age; }
    @override public void setAge(int age) { this.age = age; }
}

public interface Employee extends Person {
    double getSalary();
    void setSalary(double salary);
    double calcSalary();
}

public abstract class EmployeeImpl extends PersonImpl implements Employee {
    private double salary;
    @override public double getSalary() { return this.salary; }
    @override public void setSalary(double salary) { this.salary = salary; }
}

public class Teacher extends EmployeeImpl
    @override public double calcSalary() { 
        if (title.equals("Professor")) salary=salary*0,30;
        else if (title.equals("Lecturer")) salary=salary*0,10;
    }
}

0

从Person开始。你在那里打了一个错字:

public class Person
{
    private String name;
    private int age;
    public Person(String name, int age){
        this.name=name;
        this.age=age;
    }
    // set and get methods, equals, hashCode, toString,
    // perhaps an id for database storage.
}

现在,一些“人”是“员工”,其他人是学生、家长、潜在学生等等。如果“员工”的任何方法有实现,它就不能是接口。而且,在任何情况下,拥有“nameEmp”是错误的,因为它会重复“Person”中的名称。你可以为“Employee”创建一个接口,将其混合到“Teacher”类中,或者从“Employee”继承。

要么:

public interface Employee {
    // Currency values should use BigDecimal or BigInteger, not double.
    BigDecimal salary();
    // Taxpayer Identification Number (SSN) in the USA, or the equivalent outside.
    String taxNumber();
}

或者:

public class Employee extends Person {

    private BigDecimal salary;
    private String taxNumber;
    public Employee(String name, int age, BigDecimal salary,
                    String taxNumber) {
        super(name, age);
        this.salary = salary;
        this.taxNumber = taxNumber;
        this.title = title;
    }
    // getters, setters, etc.
}

public class Teacher extends Employee {
    private Department department;
    private List<Course> courses = new ArrayList<>();
    // Constructors, getters, setters, etc.
}

如果教师的薪资方法需要有完全不同的实现,那么你应该只在教师类中包含薪资方法。你可能想在员工类中使用某种支付计算器类(策略模式)代替。这样你就可以处理适用的税款扣除、保险、养老金计划和加班费。我没有理解你原始示例中的乘数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接