java 当使用组合而不是继承时,数组应该存储什么类型?

9lowa7mx  于 2024-01-05  发布在  Java
关注(0)|答案(5)|浏览(97)

当使用继承时,你可以创建两个类AB,它们继承自类C。然后你可以创建一个C数组来存储这两个类中的任何一个--C[]
但是,当使用组合时,数组必须是什么类型才能存储这两种类型中的任何一种?

  1. class Entity {
  2. public int id;
  3. public Entity() {
  4. this.id = 0;
  5. }
  6. }
  7. class Player extends Entity {
  8. public Player() {
  9. this.id = 1;
  10. }
  11. }
  12. class Monster extends Entity {
  13. public Monster() {
  14. this.id = 2;
  15. }
  16. }
  17. public class Main {
  18. public static void main(String[] args) {
  19. Entity[] entities = new Entity[2];
  20. entities[0] = new Player(); // id == 1
  21. entities[1] = new Monster(); // id == 2
  22. }
  23. }

字符串
当使用复合时,你必须将Entity存储为字段:

  1. class Entity {
  2. public int id;
  3. public Entity() {
  4. this.id = 0;
  5. }
  6. }
  7. class Player {
  8. Entity entity;
  9. public Player() {
  10. this.entity = new Entity();
  11. this.entity.id = 1;
  12. }
  13. }
  14. class Monster {
  15. Entity entity;
  16. public Monster() {
  17. this.entity = new Entity();
  18. this.entity.id = 2;
  19. }
  20. }
  21. public class Main {
  22. public static void main(String[] args) {
  23. Player player = new Player();
  24. Monster monster = new Monster();
  25. Entity[] entities = new Entity[2];
  26. // TODO: won't work! what type?
  27. entities[0] = player;
  28. entities[1] = monster;
  29. }
  30. }

kd3sttzy

kd3sttzy1#

你只能在这里存储实体。所以只需要添加player.entity/monster.entity或其他什么。

8fsztsew

8fsztsew2#

当使用组合时,通常必须直接存储特定类类型的对象,而不是公共基类的数组。在您的示例中,您有由Entity对象组成的Player和Monster类,但您不能直接将它们存储在Entity数组中,因为Player和Monster不继承Entity。

  1. public static void main(String[] args) {
  2. Player player = new Player();
  3. Monster monster = new Monster();
  4. Entity[] entities = new Entity[2];
  5. entities[0] = player.entity;
  6. entities[1] = monster.entity;
  7. }

字符串

jtjikinw

jtjikinw3#

在你的例子中,你使用了强制转换。强制转换只适用于“is a”或“inheritance”关系。并不总是推荐使用组合。“favorite composition over inheritance”语句意味着不要在任何情况下都过度使用继承。但是当你想对一个像你的例子这样的真实的“is a”关系使用多态性这样的继承特性时,毫无疑问,不要后悔地使用它。错误继承关系的一个例子是这样的:
Animal“是一个”MoveableEntity => Animal“具有”MovingBehavior

sqougxex

sqougxex4#

如果C的接口足以满足您对这些项所需的所有操作,请使用C[]。
如果你只想存储A或B,不想存储其他任何东西,并且对它们进行不同的处理,而不是通过它们自己的方法,那么使用某种复合类型(例如OneOf<T1,T2>)是有意义的。这种类型包含A和B的字段,并且只使用其中一个,并且通常有(在其他方法中)方法:

  1. T Match<T>(Function<A,T>,Function<B,T>)

字符串
其允许穷举处理包含在该复合中的所有可能类型。

92vpleto

92vpleto5#

答案已经作为问题的注解给出了;您需要使用一个公共超类,在本例中是Object。

相关问题