项目中有一个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
,何时不使用。
答案 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)
这实际上取决于您的要求 - 在这些情况下没有内在的“更好或更差”。
在我的脑海中,这里有一些注意事项:
继承的优点(第一种情况):
授权的优点(第二种情况):
对于此场景中的委派,您还可以考虑使用一个通用的超级界面,这通常会为您提供两全其美的优势。
答案 5 :(得分:0)
我同意@Narendra Pathai的回答,但我们建议您始终更喜欢合成继承 ,除非 您已经< / em>在你的代码中有一种情况,即以多态方式访问某些对象会更有意义 - 比如说让我们绘制所有这些形状而不是预编码多态( is-a < / em> 关系)对于一些未知的未来案例。