【问题标题】:Force a class in Java to call a method强制Java中的类调用方法
【发布时间】:2016-01-02 08:39:46
【问题描述】:

我有一个类包含一个私有成员(它本身就是一个对象)。我想以合法的方式访问该成员并修改其属性。我想这样做的方法是让类调用我的类的方法(我想在其中访问它)及其私有成员。

例如,我有一个类ClassA,它的属性为mItem。我想在ClassB 中获取mItem 的实例,以便稍后(当用户在UI 上更新某些内容时)调用mItem.update()。从ClassB,我想调用ClassA 的方法(比如passItem),它实际上调用ClassB 的某个方法(比如obtainItem(Item item))传递mItem。但是,我想强制执行此操作,以便passItem 实现要求使用mItem 调用ClassBobtainItem

有什么想法吗?

【问题讨论】:

  • 而 classA 没有该属性的 getter/setter? Mabye 这将是最常见的处理方式。一个真实的例子会对你有很大帮助。
  • 为什么不在 ClassA 中创建一个委托给 mItem 的更新方法?你为什么要打破封装?如果 ClassA 和 ClassB 如此依赖于彼此的内部结构,那么将它们作为不同的类有什么意义呢?对于第二种情况,ClassA 是否拥有 ClassB 的实例?它们是静态方法吗?同样,为什么它们如此依赖彼此的内部结构?举一个合适的例子来说明你想要达到的目标。基本上告诉问题而不是要求解决解决方案。
  • @Jan, @aseem-bansal 可以将ClassA 视为许多类的容器,例如ClassBClassCClassA 的实例持有mItem 的实例,ClassBClassC 的实例可以更新(通过调用mItem.update() 和其他一些方法)。这就是为什么我想要引用mItem
  • 没有吸气剂的容器对我来说似乎毫无用处。除非容器出于某种原因保护内部值。容器/classA 也是你的代码吗?
  • @jaibatrik 如果我们不必“考虑”这些类,而可以看到它们,那么理解您的意思并提出解决方案会容易得多。发布您的代码而不是描述它。

标签: java class design-patterns interface


【解决方案1】:

如果您可以访问ClassA 的源代码,那么访问私有成员的常用方法是为您感兴趣的成员属性选择性地添加delegate setter 和getter 方法。

但是,如果您无法访问其源代码,事情就会变得有点复杂。执行此操作的标准方法是使用Java reflection 检索对私有成员的引用。但是,这违反了 OOP 的一些原则,因为外部实体依赖于 ClassA 的实现。

【讨论】:

  • 感谢您提及委托模式。我会试一试。看起来很有希望。
【解决方案2】:

您可能可以使用命令模式来实现这一点。允许 A 和 B 来回传递命令来处理(根据它们内部存储的成员变量) 使成员变量既是接收者/调用者,又是类 A 和 B 作为“客户端”,使用一些“命令”集来回传递。


下面描述了使用 4 个不同的类,但是将其中的 2 个合并为 1 个就可以了。

来自https://en.wikipedia.org/wiki/Command_pattern

基本原理/用途:

使用命令对象可以更轻松地构建通用组件 需要一次委托、排序或执行方法调用 他们的选择不需要知道方法的类或 方法参数。

设计:

与命令模式相关的四个术语是命令, 接收者、调用者客户端。命令对象知道接收者 并调用接收者的方法。 参数的值 接收方法存储在命令中。接收器然后执行 工作。调用者对象知道如何执行命令,并且可以选择 对命令执行进行簿记。调用者不 对具体命令一无所知,它只知道命令 界面。一个调用者对象和几个命令对象都被持有 由客户对象。 客户端决定执行哪些命令 哪些点。要执行命令,它将命令对象传递给 调用者对象。

客户端不知道调用者或命令的内部工作原理。这就是它的好处。客户端可以将它们视为“原子”事件,它们可以随时启动(通过将命令传递给接收器)。

例如,如果我有一个电子游戏,我可以有一本魔法书(接收器),一些卷轴(命令),会有一个英雄/女主角作为(客户端),还有魔法小​​鬼(调用者) ) 获取卷轴的内容(命令)并知道如何将其转换为书籍(接收器)的“输入”(参数)


客户端不知道命令的详细信息,也不知道接收者的详细信息。 (也不是调用者)。它只有一组“命令”,可以将其分配给接收器方法的选择方式。无需了解任何其他 3 个类的内部构成。

【讨论】:

    【解决方案3】:

    我的另一个答案是当我没有意识到你想要使用活动/片段时。

    在这样做时有一套“最佳实践”。

    您创建一个您的 Activity 实现的 interfaceB 和 interfaceC(可以是完全相同的接口,但可以是独立的)。

    然后在你实例化你的片段之后,但在你附加它之前,你将this 传递给片段的设置器。

    片段内部会将其存储为instance(B|C) 的实例(取决于您所在的片段)。

    这允许您从 B 和 C 调用 A 的(接口)方法。

    (您也可以让活动存储对 B 和 C 的引用,并调用该方向的方法)

    这允许片段和底层 Activity 之间的双向通信。


    然后,您将通过 A(可行)或调用 B 和 C 上的设置器“路由”通信,一旦两者都被初始化,允许它们相互引用(现在相互之间直接对话)

    【讨论】:

      猜你喜欢
      • 2010-10-21
      • 1970-01-01
      • 2018-10-15
      • 2016-01-06
      • 2012-02-03
      • 2011-11-14
      • 2017-03-14
      • 1970-01-01
      • 2020-12-03
      相关资源
      最近更新 更多