避免类型检查通常是最好的做事方式。不幸的是,您没有提供足够的上下文来说明您将如何使用您的类,因此我可以举例说明如何使用多态性并避免它。
添加类型检查将限制系统增长的能力,因为随着新类的添加,这些类型需要包含在类型检查中。有时这会导致错误,因为您的代码可以假设类的数量或其类型。这是一个例子:
注意:我只是为了说明目的而编造这个。这不是关于必须代表你的逻辑或类似的东西。
public void someMethod(Access access) {
if(access instance of InAccess) {
InAccess inAccess = (InAccess)access;
}
else {
OutAccess outAccess = (OutAccess)access;
}
}
当我们启动时,我们的系统有两个继承自Access
. 假设我们将另一个添加Access class
到我们的系统中。这段代码会在 else 上崩溃,因为我们可能会传递新的第三种访问类型并且强制转换不会成功。
当然,情况并非总是如此。有时,您拥有的课程数量不会增长太多。您可以预测所有类型。
当然,由于所有事情都可能发生在编程中,所以有时您确实需要知道您正在使用的对象的类型。
假设您的系统确实需要知道对象的类型。这里有两个解决方案:
- 添加一个将代表您拥有的所有类型的枚举。
public enum AccessType {
InAccessAllowed,
InAccessDenied,
OutAccessDenied,
// other types
}
public interface Access {
AccessType getType();
// other stuff
}
这样,您将使用enum AccessType
类型转换而不是类型转换。
- 使用接口。
不是使用类,而是为每种类型的Access
. 然后您将检查接口而不是类。这样,您的装饰器可以实现与它所装饰的类相同的接口。
public interface InAllowedAccess { }
public class InAllowedAccessImp implements InAllowedAccess { }
public class InAllowedAccessDecorator implements InAllowedAccess { }
我只是不想给出替代实现的示例。由于您的描述中缺少上下文,我将尝试猜测您将如何使用您的类并向它们添加行为。这只是一个想法,仅此而已。
假设您的系统授予用户访问权限。可以为用户提供 In 和 Out 访问权限,并且系统的某些部分需要询问是否授予或拒绝特定用户的访问权限,以便它可以执行特定的逻辑。
如果您没有任何与您相关的行为,Access classes
则可以将其用作描述符,该描述符将携带其他类完成工作所需的信息。
public enum PortType { In, Out }
public enum Permissions { Allowed, Denied }
public class Access {
private PortType mPortType;
private Permissions mPermissions;
public Access(PortType portType, Permissons permissions) {
mPortType = portType;
mPermissions = permissions;
}
public PortType getType() { return mPortType; }
public Permissions getPermissions() { return mPermissions; }
}
如果你确实有行为,那么你可以使用多态性。定义你的行为Access interface
并让实现这个接口的类定义行为。
假设我们有消息系统,用户可以接收(输入)和发送(输出)消息。这些消息通过一个渠道。这些通道将接受或拒绝消息。这是一种可以使用多态性而不是类型检查的方法。
public interface MessageChannel {
public bool canSendMessages(); // out
public bool canReceiveMessages(); // in
public void receiveMessage(Message m);
public void sendMessage(Message m);
}
public class InMessageChannel implements MessageChannel {
// out messaging is not allowed, cannot send
public bool canSendMessages() { return false; }
// In messaging allowed, can receive
public bool canReceiveMessages() { return true; }
public void sendMessage(Message m) {
throw new SendingMessagesIsNotAllowd();
}
public void receiveMessage(Message m); {
// do something with the mssage
}
}
public class OutMessageChannel implements MessageChannel {
// out messaging allowed
public bool canSendMessages() { return true; }
// In messaging not allowed
public bool canReceiveMessages() { return false; }
public void sendMessage(Message m) {
// send the message
}
public void receiveMessage(Message m); {
throw new ReceivingMessagesIsNotAllowd();
}
}
如您所见,每个MessageCahnnel
都有与之相关的行为。如果允许或不允许,它可以发送接收消息。这样其他使用 的类MessageChannel
就不必进行类型转换了。