【问题标题】:Example for Objects calling each other’s methods recursively对象递归调用彼此方法的示例
【发布时间】:2016-04-23 14:15:15
【问题描述】:

我正在做博士研究,在一次讨论中我提到在 OOP 中,两个对象可能会递归地相互调用。然后我的朋友问我是否有这样的例子,这种情况发生在更真实的例子(不是人造的例子)中。

我想不出一个。

不显示构造函数的人工示例的伪代码:

class A
  private B b;
  void a1() {  b.b1(); }
  void a2() { print “finished”; }

class B
  private A a;
  void b1() { a.a2(); }

方法线性化是:

A.a1()  ---->  B.b1()  ----> A.a2()

有没有更真实的例子可以调用两个不同对象的方法?

【问题讨论】:

  • 我认为这将是一个糟糕的设计......应该是 A.a1()--> B.b1() A.a1()-->A.a2()跨度>
  • 请原谅我的评论,如果它没有出现,但递归不是从自身内部调用方法吗?在此示例中,您只需依次调用 a1() ---> b1() ---> a2() 输出:完成。
  • 你是说双重调度和访客模式吗?
  • 看一些网络示例。令牌环将有对象相互调用。由于只有一个令牌,因此不会存在冲突。一个
  • @IoannisStefanou 有递归和相互递归。两个(或三个或 n 个)相互调用的方法是相互递归的。在这种情况下,它们是不同的方法。

标签: java c# oop smalltalk pharo


【解决方案1】:

看看 Smalltalk 如何通过双重调度处理强制。

在吱吱声图像中:

Float>>+ aNumber
   "Primitive. Answer the sum of the receiver and aNumber. Essential.
    Fail if the argument is not a Float. See Object documentation
    whatIsAPrimitive."

   <primitive: 41>
   ^ aNumber adaptToFloat: self andSend: #+

Integer>>adaptToFloat: rcvr andSend: selector 
   "If I am involved in arithmetic with a Float, convert me to a Float."
   ^ rcvr perform: selector with: self asFloat

因此,如果您执行1.5 + 3,则将+ 发送到1.5(浮点数),1.5 将adaptToFloat:andSend: 发送到3(整数),然后3 再次将+ 发送到1.5(第二次使用@ 987654326@ 而不是 3)。

不会只用两个步骤将其称为递归,但它与您的示例很接近。

注意:Float&gt;&gt;+ 中的原语失败,执行后的 Smalltalk 代码。

【讨论】:

    【解决方案2】:

    您同意@Sanjeev 的观点,在实际示例中根本不应该发生这种情况,因为它在很多层面上都是错误的,但让我们假设一个糟糕的设计师犯了这个错误;它可以在很多情况下完成。例如:一个银行系统,其中余额计算功能在帐户对象中完成,但是因为客户可能拥有多个帐户(并且该帐户可以由多个客户拥有)。设计师认为能够从任何帐户对象计算所有帐户的客户余额是一个好主意,并且应该通过与客户的关系来完成。使用您的代码示例:

    class BankAccount
      private Customer cust;
      void TotalBalance() {  cust.Balance(); }
      void OwnersBalance() { print “finished”; }
    
    class Customer
      private Account acc;
      void Balance() { acc.OwnersBalance(); }
    

    【讨论】:

      【解决方案3】:

      希望我正确理解您的需求,这是一个可能的现实生活示例。

      想象一下经理收到需要交付的项目的情况。 经理将项目交给员工,员工完成交付给客户的项目。

      public class StackOverFlow {
      
          public static void main(String[] args) {
              Employee emploeyee = new Employee();
              ProjectManager projectManager = new ProjectManager(emploeyee);
      
              projectManager.initiateProject();
          }
      
          public static class ProjectManager {
              Employee emploeyee;
      
              public ProjectManager(Employee emploeyee) {
                  this.emploeyee = emploeyee;
              }
      
              public void initiateProject() {
                  System.out.println("Manager Starts project...");
                  this.emploeyee.finishProject(this);
              }
      
              public void deliverProjectToClient() {
                  System.out.println("Manager delivers finished project to client");
              }
          }
      
          public static class Employee {
      
              public Employee() {
      
              }
      
              public void finishProject(ProjectManager projectManager) {
                  System.out.println("Employee delivers finished project to manager");
                  projectManager.deliverProjectToClient();
              }
          }
      }
      

      输出:

      Manager Starts project... 
      Employee delivers finished project to manager
      Manager delivers finished project to client
      

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-19
        • 2018-04-17
        • 1970-01-01
        • 2023-04-10
        相关资源
        最近更新 更多