Java的扩展替代方案

3

我正在尝试制作我们大学课程管理系统的模型(针对课程)。我遇到了一个小问题,就是extends的限制,即某个类无法扩展两个类。以下是该模型:

                     Professor
                    /                  
             Staff
          /          \                       
    Person            Tutor            
           \         /      
             Student            

所以我将员工和学生扩展为人,教授扩展为员工。现在我有一个小问题,涉及到导师类,他基本上是一个学生(具有学生ID),但在某种意义上也是大学雇员(组织集体讲座,负责某个项目等)。由于我不能使用两个扩展,还有其他的替代方案吗?如果可能的话,能否给出一个非常简单的实现示例?我已经看到了一个接口的示例,但我不确定如何在我的程序中使用它,因为学生不是一个接口。


你能否至少发布一个有效的模型,使用像UML这样的东西?你的代码行代表什么?我希望它们不是指“扩展”,因为在那种情况下,你的“教授”、“职员”和“导师”不是“人”。上次我检查时,我们在大学里有人而不是机器人来教学生...等等,我应该从左到右阅读模型吗?从上到下? - WarrenFaith
4
这是一个基础问题,但并不差劲。不要抱怨或投反对票,写一篇带有教程链接的回答。Stackoverflow是为了帮助人们解决问题的。 - Jens Schauder
必须使用Java吗?如果不是的话,像Scala或Ruby这样具有mixins的语言更适合您的目的。由于Scala编译为Java字节码,因此向您的导师/上级提出这个要求应该不会太过分。 - G_H
这不是一个“小”限制,这是人们讨论已久的限制 :) - Joeri Hendrickx
5个回答

8
不要使用继承,而是使用组合:每个人都是一个“Person”,但具有一个或多个角色:学生、导师、教授、员工。
或者选择将员工和学生分开,并允许他们拥有角色。这些角色会决定他们能够或不能够做什么。

4
你可以像这样做。
interface Person { ... }

interface Staff extends Person { ... }

interface Student extends Person { ... }

class Tutor implements Staff, Student { ... }

class Professor implements Staff { ... }

很遗憾,你不能在StaffStudent中都放置逻辑(即字段或非抽象方法),因为它们都需要成为类,而Java类不能扩展两个类。

你可以使StudentStaff(但不能同时)成为抽象类,以便在其中添加逻辑。虽然这样做有点不太优雅,因为没有概念上的理由要将其中一个作为抽象类,而将另一个作为接口。理想情况下,它们应该都是抽象类,但为此你需要切换到具备多重继承功能的语言。

interface Person { ... }

interface Staff extends Person { ... }

abstract class Student implements Person {
    long studentID;
    ...
}

class Tutor extends Student implements Staff { ... }

class Professor implements Staff { ... }

4

Tutor 实现 StudentStaff 接口。

Student 将声明一个 getStudentId() 方法,而 Staff 将声明 getLectures()getProjects() 等方法。


我不能将学生(Student)变成接口(Interface),它必须保持为类(Class)。然而,对于职员(Staff)类没有这样的限制。如果我可以将职员(Staff)变成接口(Interface),那就没问题了,但是又有一个问题我不知道该如何解决。如果我将职员(Staff)转换为接口(Interface),那么它就失去了继承(extends),那么导师(Tutor)和教授(Professor)怎么继承人(Person)的firstName和lastName呢? - vedran
针对您的学生问题,请创建一个IStudent接口,并在当前的Student类中实现getStudentId()方法。对于另一个问题,请尝试为Person和Tutor也使用接口。然后,您可以使接口相互扩展。 - kgautron

2
制作人员、员工和学生界面。如果需要通用功能,请使用封装。

0

正如其他人所指出的,在Java中要实现这个功能,你需要定义接口而不是超类。Java不允许多重继承。

但是,除了继承之外,可能还有更好的选择。在这种情况下,以及几乎任何我发现自己想要让子类扩展多个超类的情况下,我会尝试找到一种使用委托而不是继承来模拟情况的方法。

创建一个包含一组Role对象的Person类,其中Role是一个接口,StudentStaff实现了Role。然后一个人可以拥有多个角色,而不是“成为”多种类型的人。


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