一个人有一个ID。 学生有学生证。 司机有驾照。
- 一个人上学并成为学生。
- 一名学生毕业并成为普通人。
- 一个人获得驾驶执照并成为一名司机。
- 学生获得驾照并成为司机。
那些东西只是像下面例子中的状态变化吗:
class Person {
ID id;
StudentID stId;
DriverLicense license;
void drive() {
if(license == null) //illegal state exception
//drive
}
//bla bla
}
还是有继承?由于一个对象是数据+行为,新数据和能够做新事情应该保证一个新对象
class Student extends Person {
//
}
class Driver extends Person {
//
}
//things get messy here, in Java you can't extend multiple class
//what if there's a rule that, student drivers can request/get a tax reduction?
class DriverStudent extends Person, Driver {
//
}
另外,更重要的是,一个如何成为另一个?通过方法或构造函数或第 3 类(如服务或聚合)?
class Person {
Driver getADriversLicense() {
//create and return a Driver
//this person still exists but now there's a driver with this person's data
}
}
or:
class Driver extends Person {
public Driver(Person p) {
//constructor
}
}
or:
class Aggregate {
Driver giveDriversLicense(Person p) {
// access internal state of both objects(ditch encapsulation) and return a driver?
// put aggregate in same package with Driver and Person and use package private methods to provide encapsulation?
}
}
最佳答案
查看这种关系的更好方法是通过角色,即一个人可以扮演多个角色。
一个人可以是司机和学生,也可以是员工的场景怎么样?
所以 IMO 最好的表示如下 -
class Person{
List<Role> currentRoles ;
List<Role> getCurrentRoles(){
return currentRoles ;
}
public void addRole(Role role){
currentRoles.add(role) ; // so on
}
}
使用泛型和类型安全转换,您可以轻松检索特定角色并对其调用相关操作。
public interface DriverRole implements Role {
License getDriversLicense() ;
}
编辑:进一步全面回答您的问题,它很容易解决人员获得或失去角色的情况,即添加或删除角色。正如此处的评论中所指出的,这种关系最好通过具有 <0..M> 关系然后是 IS - 一种关系来表示。
编辑 1 相比之下,当您使用装饰器模式时,您的来源会被包裹起来,过多的装饰器会创建一个聚合链,这在我看来不是一个理想的场景,否则它会导致装饰器继承链这不是我喜欢的。
话虽如此,根据特定场景,一种特定模式可能比另一种模式更适合,但在您给出的示例中,我认为角色的简单聚合是最好的。
关于java - OOP - 一个类(class)如何变成另一个类(class)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35343783/