我应该扩展服务类还是只使用它的实例?

时间:2013-11-26 07:18:23

标签: java extends

项目中有一个StoreService,它提供了一些读取和写入远程数据存储的方法。 e.g。

public class StoreService {
    public StoreService(String url, String username, String password) {}
    public void save(String category, String key, String value) {}
    public String read(String category, String key) {}
}

然后我看到另一个UserStoreService位于项目的子模块中,扩展了StoreService

public class UserStoreService extends StoreService {
    public UserStoreService(String url, String username, String password) {
        super(url, username, password);
    }
    public void saveUserName(String userId, String userName) {
        super.save("user", userId, userName);
    }
    public void getUserName(String userId, String userName) {
        return super.read("user", userId);
    }
}

你可以看到它只是添加了一些方法。在这里使用extends是否合适?

我可以在没有extends的情况下完成:

public class UserStoreService {
    private StoreService storeService;
    public UserStoreService(String url, String username, String password) {
        this.storeService = new StoreService(url, username, password);
    }
    public void saveUserName(String userId, String userName) {
        storeService.save("user", userId, userName);
    }
    public void getUserName(String userId, String userName) {
        return storeService.read("user", userId);
    }
}

但我不确定哪种解决方案更好,何时应该使用extends,何时不使用。

6 个答案:

答案 0 :(得分:3)

当您认为可以提取某些多态行为并且子类和超类之间确实存在 is-a 关系时,请使用继承。

否则在大多数情况下 更喜欢构图而不是继承 ,因为它还限制了UserStoreService将来能够扩展其他类的可能性。

答案 1 :(得分:2)

从我的代码中可以看出,UserStoreService与StoreService的界面完全不同。所以这是正确的方法不使用继承(extends)但使用组合。

答案 2 :(得分:1)

主要是我们使用extends关键字为开发视角提供继承和代码可用性。 here是一个示例,用于演示在java中实际使用extends关键字

答案 3 :(得分:1)

第二个显然更好。第一个使用继承来重用代码,而不是作为多态的方式。应该处理用户的UserStoreService实际上可以存储任何其他类别,因为超类方法仍然暴露。

这样的设计会导致像java.util.Properties这样的暴行,它应该只包含字符串作为键和值,但不能强制执行,因为它从Hashtable扩展而不是使用一个。

答案 4 :(得分:1)

这实际上取决于您的要求 - 在这些情况下没有内在的“更好或更差”。

在我的脑海中,这里有一些注意事项:

继承的优点(第一种情况):

  1. 您可以轻松地使用新的子类代替原始子类。
  2. 超类中的新方法会自动继承,保持功能和兼容性。
  3. 方法调用不需要遵循额外的指针,因此可以稍快一些。
  4. 授权的优点(第二种情况):

    1. 您可以根据需要轻松切换委托对象。
    2. 超类中的新方法不会自动继承,因此您将收到错误,警告您在子类中缺少功能。
    3. 超类中的新方法不会自动继承,因此您可以避免支持您不想支持的功能。
    4. 对于此场景中的委派,您还可以考虑使用一个通用的超级界面,这通常会为您提供两全其美的优势。

答案 5 :(得分:0)

我同意@Narendra Pathai的回答,但我们建议您始终更喜欢合成继承 ,除非 已经< / em>在你的代码中有一种情况,即以多态方式访问某些对象会更有意义 - 比如说让我们绘制所有这些形状而不是预编码多态( is-a < / em> 关系)对于一些未知的未来案例。