3

I'm trying to make a model of our universities Course management system (for the course). I stumbled upon a small limitation of extends, that is, it's impossible for a certain class to extend two classes. Here's the model:

                     Professor
                    /                  
             Staff
          /          \                       
    Person            Tutor            
           \         /      
             Student            

So with that I get Staff and Student extending Person and Professor extending Staff. Now I have a small dilemma with class Tutor, who is basically a student (has studentID), but is in a sense University employee (holds Group lectures, responsible for a certain project, etc). Since I can't use two extends, what are other alternatives, and if possible could someone give a very simple example with implements? I've seen an example of interface of it, but I'm not exactly sure as how can I use it in my program, since Student is not an interface?

Rich
  • 15,602
  • 15
  • 79
  • 126
vedran
  • 2,167
  • 9
  • 29
  • 47
  • Could you at least post a valid model using something like UML? What does your lines represents? I hope not that they mean "extends" because in that case your `Professor`, `Staff` and `Tutor` aren't a `Person`. The last time I checked we have persons and not androids at the university to teach the students... wait, should I read the model from left to right? Up to down? – WarrenFaith Oct 26 '11 at 11:27
  • 4
    It is a basic question, but not a bad one. Write an answer with a link to a tutorial instead of complaining and downvoting. Stackoverflow is about helping. – Jens Schauder Oct 26 '11 at 11:28
  • Do you **have** to use Java? If not, a language that has [mixins](http://en.wikipedia.org/wiki/Mixin) like Scala or Ruby would be better suited for your purposes. Since Scala compiles to Java bytecode, it shouldn't be too much to ask of your tutors/superiors. – G_H Oct 26 '11 at 11:33
  • It's not a 'small' limitation, it's one that people have discussed about for ages :) – Joeri Hendrickx Oct 26 '11 at 13:34

5 Answers5

8

Don't use inheritance, use composition: everybody is a Person, but has one or more roles: Student, Tutor, Professor, Staff.

Or optionally make a division between Staff and Student and allow them to have the roles. The roles then dictate what they can or cannot do.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
4

Make Student and Staff interfaces implemented by Tutor.

Student will declare a getStudentId() method, and Staff will declare getLectures(), getProjects() etc..

kgautron
  • 7,915
  • 9
  • 39
  • 60
  • I can't make a student an Interface, it has to remain a class. However there are no such restrictions on class Staff. If I could make Staff an interface, that would work, but then there's another problem I don't know how to fix. If I turn Staff into an interface, it means it looses extends, how will then Tutor and Professor inherit person.firstName and person.lastName?? – vedran Oct 26 '11 at 11:50
  • For your student problem create an IStudent interface with the getStudentId() method, and make your current Student class implement it. For the other problem, try to use interfaces for Person and Tutor also. Then you can make interfaces extends each other. – kgautron Oct 26 '11 at 11:51
4

You can do something like this.

interface Person { ... }

interface Staff extends Person { ... }

interface Student extends Person { ... }

class Tutor implements Staff, Student { ... }

class Professor implements Staff { ... }

Unfortunately, you can't put logic (i.e., fields or non-abstract methods) in both Staff and Student because they would both need to be classes, and a Java class cannot extend two classes.

You could make Student or Staff (not both) an abstract class, allowing you to put logic in it. It would be kind of inelegant, though, since there's no conceptual reason why one should be an abstract class while one should be an interface. Ideally they should both be abstract classes, but for that you'd need to switch to a language with MI.

interface Person { ... }

interface Staff extends Person { ... }

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

class Tutor extends Student implements Staff { ... }

class Professor implements Staff { ... }
Daniel Lubarov
  • 7,796
  • 1
  • 37
  • 56
2

Make Person, Staff, and Student interfaces. If you need common functionality, use encapsulation.

John B
  • 32,493
  • 6
  • 77
  • 98
0

As others have noted, to do this in Java you need to define interfaces rather than superclasses. Java does not allow multiple extends.

But there may be a better alternative than inheritance. In this, and almost any situation where I find myself tempted to have a subclass extend multiple superclasses, I try to find a way to model the situation with delegation rather than inheritance.

Create a Person class that contains a set of Role objects where Role is an interface, and Student and Staff implement Role. Then a person can have multiple roles instead of "being" multiple types of person.

Don Roby
  • 40,677
  • 6
  • 91
  • 113