Java:使用instanceof公开不同的对象方法

发布于 2025-01-03 23:57:31 字数 816 浏览 1 评论 0原文

我读过这篇文章 http://www.javapractices.com/topic/TopicAction .do?Id=31,它表示使用 instanceof 事先检查我的对象是什么是一种不好的做法。

但在这种情况下我不知道该怎么做:我有一个返回项目列表的 API。此项目列表返回用户和管理员

如果我投射像 (User)item 这样的项目,一旦它击中管理员,我就会遇到 ClassCastException

for(Item item : items){                     
                if (item instanceof User){
                    ((User)item).getName());
                    ((User)item).getEmail());
                }
                else if (item instanceof Admin){
                    ((Admin)item).getName());
                    ((Admin)item).getEmailList().getPrimary());
                }                           
            }

因为它是一个 API,所以我无法修改项目,项目没有孩子的方法,和电子邮件检索方法不同。我还有别的选择吗?

I've read this article http://www.javapractices.com/topic/TopicAction.do?Id=31, which says using instanceof to check what my object is beforehand is a bad practice.

But I don't know how to do it otherwise in this case: I have an API that returns a List of Items. This list of Items returns both Users and Admins

If I cast an item like (User)item, I'll have a ClassCastException as soon as it hits an Admin

for(Item item : items){                     
                if (item instanceof User){
                    ((User)item).getName());
                    ((User)item).getEmail());
                }
                else if (item instanceof Admin){
                    ((Admin)item).getName());
                    ((Admin)item).getEmailList().getPrimary());
                }                           
            }

Since it is an API I can't modify Item, Item do not have the methods on the childs, and the email retrieve method is different. Do I have another choice?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

慵挽 2025-01-10 23:57:31

定义一个包含所有常用方法的接口,让 User 和 Admin 类实现该接口,并在这些情况下仅使用该接口来访问您的对象。

编辑(因为您无法更改 API)

替代选项是:

  1. 坚持使用当前的解决方案。这似乎是最好的交易。

  2. 定义一个接口,创建两个实现该接口的包装类并包装原始对象。从 OOP 的角度来看,这更干净,但我认为这对于您的情况来说有点过大,但这实际上取决于。

  3. 理论(!):您也可以使用反射,但不要这样做 - 它会使代码变得更糟 - 特别是当只有两个不同的编译时已知项时子类型

Define an interface with all common methods, let User and Admin classes implementat that and use only that interface for accessing your objects in these cases.

EDIT (because you cannot change the API)

The alternative options are:

  1. Stick to your current solution. This seems to be the best trade.

  2. Define an interface, create two wrapper classes which implement this interface and wrap the original objects. From an OOP perspective this is more clean, but I think this is a little bit oversized in your case, but it really depends.

  3. Theoretical(!): you could also use reflection, but don't do this - it would make the code even more worse - especially not when there are only two different compile-time known Item subtypes

メ斷腸人バ 2025-01-10 23:57:31

理想情况下,您将更改 Item 的接口,以便它公开方法,这样无论您在代码中处理用户还是管理员都没有关系 - 这样 Item 定义了 getName() 和 getEmail() 以及 User 和管理员酌情实施这些方法。

但是,由于您无法控制正在使用的 API,因此您别无选择,只能按照现在的方式编写代码。

因此,引用的文章提出的观点很好,但它假设您可以更改正在使用的类。

Ideally you would change the interface to Item so that it exposed methods such that it didn't matter if you were dealing with a User or an Admin in your code -- so that Item defines both getName() and getEmail() and User and Admin implement these methods as appropriate.

However, since you don't control the API you are using then you have little choice but to write your code as you have it now.

So, the point made by the referenced article is a good one, but it assumes that you can change the classes you are working with.

扛起拖把扫天下 2025-01-10 23:57:31

首先,你的代码没有任何效果。您在没有任何赋值的情况下调用 getter,因此实际上没有使用 getter 的返回值。

其次,收集不同类型的元素是一种不好的做法。在您的案例中,用户和管理员。

第三,如果您甚至需要这样的集合,您可以使用其他模式来执行您需要的操作。例如,访问者模式看起来是铸造的一个很好的替代方案。

First, your code does not have any effect. You are calling getters without any assignment, so you actually do not use the getter's return value.

Second, it is a bad practice to have collection with elements of different types. In your ccase User and Admin.

Third, if you even need such collection you can use other patterns to perform what you need. For example Visitor pattern looks like a good alternative to casting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文