我有一个界面:
public interface IUser {
public boolean login();
}
和两个实现此接口的类:
public class UserA implements IUser{
public boolean login() {
System.out.println("login");
}
public void update() {
System.out.println("update");
}
}
public class UserB implements IUser {
public boolean login() {
System.out.println("login");
}
public void delete() {
System.out.println("delete");
}
}
我的问题是我是否创建了一个用户:
IUser user = new UserA();
用户对象无法访问 update()但是建议使用界面创建对象,我想知道是否有最佳做法或我可以使用的设计模式(而不是铸造它)?
答案 0 :(得分:4)
优良作法是对界面进行编码"。
但是,只有当该界面具有您需要的所有方法时才有效。
如果没有,您需要使用具体类而不是接口(这不一定是坏的,这取决于具体情况),或者重新考虑接口的设计方式。
答案 1 :(得分:1)
当代码只需要接口类型才能工作时,最好在接口上编程。如果代码需要类型UserA
的对象才能工作,那么您应该将变量声明为UserA:
UserA user = new UserA();
...
// this methods does something applicable to all kinds of IUser
public void doSomething(IUser user) {
...
}
// this methods does something applicable only to UserA
public void doSomethingElse(UserA user) {
...
}
答案 2 :(得分:1)
如果您知道需要使用update
方法,请更改
IUser user = new UserA();
到:
UserA user = new UserA();
如果您的应用程序需要使用仅由类提供的方法,"接口" 建议的代码将不适用。
如果由于其他原因(例如,对于多态性)需要将变量的类型声明为IUser
,那么类型转换是唯一真正的选项。但请注意,您的代码需要处理IUser
不是UserA
的情况。
实际上,还有另一种方法。您可以将update
和delete
添加到IUser
,如果它们没有意义,请将它们实施为:
throw new UnsupportedOperationException("...");
然而,这只是将一个问题(类型转换异常)替换为另一个问题(类型转换异常)(不支持的操作异常)...还有一个额外的缺点,就是在你需要进行调用以在语法上指示那里时没有任何东西是一个潜在的问题。
如果您对"更好的方式感兴趣"要做到这一点,请看一下Ceylon通过使用switch
语句来切换对象类型来避免类型转换异常问题的方式。
答案 3 :(得分:1)
这取决于代码的上下文。如果您的变量user
始终指向UserA
对象并且您需要这些操作,我认为将变量声明为UserA
是可以的。如果情况并非如此,我会重构以确保在变量的范围内只使用其中一种具体类型(类似于JB在他的回答中所写的内容)。
此外,您还可以引入两个扩展UpdatableUser
的{{1}}和DeleteableUser
接口。
答案 4 :(得分:0)
通常你应该'代码到接口'。但是你可以在你的方法中使用以下语句:
UserA user = new UserA();
并且您具有UserA
类的完整功能。只要您使用方法,就将其用作。一旦你的方法结束或你调用另一个方法,只传递IUser
而不是具体的实现。
答案 5 :(得分:0)
如果方法update()和delete()是其他对象应该使用的方法,也许你应该重新考虑。
如果他们不会被他人使用,则update()和delete()应该是私有方法。所以你不应该修改IUser。
如果在其他地方调用update()和delete(),则可以创建两个可更新和可删除的接口。然后在您想要调用的位置,您应该将IUser转换为接口可更新或可删除。