面向对象编程中的委派示例:需要澄清

时间:2016-01-30 05:41:05

标签: oop delegation

取自https://en.wikipedia.org/wiki/Delegation_(programming)

class A {
  void foo() {
    // "this" also known under the names "current", "me" and "self" in other languages
    this.bar();
  }

  void bar() {
    print("a.bar");
  }
};

class B {
  private delegate A a; // delegation link

  public B(A a) {
    this.a = a;
  }

  void foo() {
    a.foo(); // call foo() on the a-instance
  }

  void bar() {
    print("b.bar");
  }
};

a = new A();
b = new B(a); // establish delegation between two objects
  

调用b.foo()将导致b.bar被打印,因为this   指的是原始接收者对象b,在上下文中   a

有人可以在上面说明解释吗?我认为我理解基本原则,但我仍然不确定为什么它会从类foo()调用B方法。

2 个答案:

答案 0 :(得分:2)

维基百科文章(https://en.wikipedia.org/wiki/Delegation_(programming))正在谈论一个名为" delegation"的功能。这是我没有经历的事情。

引用您引用的维基百科文章中的#1: " 调用b.foo()将导致b.bar被打印,因为它指的是原始接收器对象b,在a。"

他们基本上压倒了这个"这个"在类A中,它碰巧指向类B的实例。我怀疑覆盖是临时的,可能会从调用更改为针对A类方法的调用。祝好运,如果同一个实例作为一个"委托"那么,确定A类的给定实例将会做什么。对于B类,C类和D类,所有的实现都是" bar()"。

我不想成为负责编写A类的程序员,如果"这个"在运行时会是一些任意的B类或(C类...... Z类);它感觉就像一个研究主题,对论文有益,但对于一天的工作编程可能没什么帮助。我有兴趣阅读stackexchange人群可以提供的任何示例,他们发现这种行为很有帮助。

引用您引用的维基百科文章中的#2: &#34; 一般编程语言不支持这种不寻常的授权形式作为一种语言概念,但有一些例外[引证需要] &#34; < / p>

我同意[引证需要],我很想听到任何真正支持这种语言的语言。

示例Java输出

请注意,Java并不像维基百科文章所描述的那样工作。 使用&#34; delegate&#34;这个词可能毫无意义。在源代码中,因为它具有误导性,至少在维基百科文章概念的意义上。但我把它留下来,以便更容易比较维基百科样本&#34;代码&#34;以下内容。

$ java B
> B(), adding delegateA@2a139a55
< B()
----- a.foo() ---
> A.foo(), calling this.bar()
A.bar(): hello from a.bar
< A.foo(), back from this.bar()
----- a.bar() ---
A.bar(): hello from a.bar
----- b.foo() ---
> B.foo(), calling a.foo()
> A.foo(), calling this.bar()
A.bar(): hello from a.bar
< A.foo(), back from this.bar()
< B.foo(), back from  a.foo()
----- b.bar() ---
B.bar(): hello from b.bar
$ 

现在......作为一个思想实验,如果java实现了那种“授权”#39;输出的最后一部分看起来(我认为)更像是这样:

//This isn't actual output from java at all,
//I just edited this trying to make it look like
//what I think the wikipedia-style "delegation" would do.
----- b.foo() ---
> B.foo(), calling a.foo()
> A.foo(), calling this.bar()
B.bar(): hello from b.bar  // Big difference here vs. actual java output above.
< A.foo(), back from this.bar()
< B.foo(), back from  a.foo()
----- b.bar() ---
B.bar(): hello from b.bar
$ 

A类

class A {
  void foo() {
    System.out.println("> A.foo(), calling this.bar()");
    this.bar();
    System.out.println("< A.foo(), back from this.bar()");
  }

  void bar() {
    System.out.println("A.bar(): hello from a.bar");
  }
}

B级

class B {
  // private delegate A a; // delegation link
  // above line doesn't compile in Java, "delegate" not a key word.
  private A a; // delegation link, without "delegate" key word.

  public B(A a) {
    System.out.println("> B(), adding delegate"+a+"");
    this.a = a;
    System.out.println("< B()" );
  }

  void foo() {
    System.out.println("> B.foo(), calling a.foo()");
    a.foo(); // call foo() on the a-instance
    System.out.println("< B.foo(), back from  a.foo()");
  }

  void bar() {
    System.out.println("B.bar(): hello from b.bar");
  }

   public static void main( String args[] ) {
      A a = new A();
      B b = new B(a);
      System.out.println("----- a.foo() ---");
      a.foo();
      System.out.println("----- a.bar() ---");
      a.bar();
      System.out.println("----- b.foo() ---");
      b.foo();
      System.out.println("----- b.bar() ---");
      b.bar();
   }
}

答案 1 :(得分:1)

  1. b.foo()来电this.a.foo()
  2. 由于b.a被声明为delegated,因此在this.a.foo()

    的上下文中调用b
    1. a.foo()来电this.bar()
    2. 由于在a.foo(),[{1}}引用b引用this内的a.foo()关键字的上下文中调用了b,而不是a。因此,this.bar()引用b.bar()