Difference between revisions of "Documentation/DevGuide/ProUNO/CLI/The Override Problem"

From Apache OpenOffice Wiki
Jump to: navigation, search
m
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{Documentation/DevGuide/ProUNOTOC/Zh
+
{{Documentation/DevGuide/ProUNOTOC
 
|ProUNO2c=block
 
|ProUNO2c=block
 
|CLIBinding=block
 
|CLIBinding=block
 
|ClientProg=block
 
|ClientProg=block
 
|ShowPrevNext=block
 
|ShowPrevNext=block
|PrevPage=Zh/Documentation/DevGuide/ProUNO/CLI/Writing Client Programs
+
|PrevPage=Documentation/DevGuide/ProUNO/CLI/Writing Client Programs
|NextPage=Zh/Documentation/DevGuide/ProUNO/CLI/Important Interfaces and Implementations
+
|NextPage=Documentation/DevGuide/ProUNO/CLI/Important Interfaces and Implementations
 
}}
 
}}
[[en:Documentation/DevGuide/ProUNO/CLI/The Override Problem]]
+
{{Documentation/DevGuideLanguages|Documentation/DevGuide/ProUNO/CLI/{{SUBPAGENAME}}}}
{{DISPLAYTITLE:重载问题}}
+
{{DISPLAYTITLE:The Override Problem}}
 +
The term “override problem” describes a problem that occurs when a virtual function of a base object becomes unreachable because an interface method overrides the implementation of the base class. For example, all CLI objects derive from <code>System.Object</code>. If an interface has a method that has the same signature as one of <code>System.Object</code>'s methods, then the respective method of System.Object is unreachable if the interface method is virtual.
  
术语 “override problem” 描述的是由于接口方法重载基类的实现,从而不能存取基对象的虚拟函数
+
For example, consider the following declaration of the interface <code>XFoo</code> and its implementing class :
时将会发生的问题。例如,所有 CLI 对象都是由 <code>System.Object</code> 派生的。当接口中方法的签名与 <code>System.Object</code> 的其中一个方法相同时,如果接口方法是虚拟的,则不能存取相应的 <code>System.Object</code> 方法。
+
 
+
 
+
例如,请考虑接口 <code>XFoo</code> 的以下声明极其实现类:
+
  
 
   using namespace System;
 
   using namespace System;
Line 33: Line 30:
 
   };
 
   };
  
 
+
If the method <code>ToString</code> of an instance is called, then the implementation of the interface method is invoked. For example:
如果调用实例的方法 <code>ToString</code>,则将调用接口方法的实现。例如:
+
  
 
   int main(void)
 
   int main(void)
Line 46: Line 42:
 
   }
 
   }
  
 +
This may not be intended, because the interface method likely has a different semantic than its namesake of <code>System.Object</code>.
  
由于接口方法可能具有与 <code>System.Object</code> 的名称不同的语义,因此可能不是有意如此。
+
A solution is to prevent the interface method from overriding the method of <code>System.Object</code> without making the interface method non-virtual. The CLI provides a remedy by way of the “<code>newslot</code>” flag, which is attached to the method header in the IL code. CLI languages may have different means for denoting a method with “<code>newslot</code>.
 
+
解决方案可防止接口方法重载 <code>System.Object</code> 的方法,而无需将接口方法设为非虚拟。CLI 通过 “newslot” 标志提供一种补救措施,可将该标志附加到 IL 代码的方法头中。在使用 “newslot” 表示方法时,CLI 语言可能具有不同的含义。
+
 
+
 
+
以下示例说明用不同语言实现 <code>XFoo</code> 的方法,这样仍然可以调用 <code>Object.ToString</code>。
+
  
 +
The following examples show ways of implementing <code>XFoo</code> in different languages, so that <code>Object.ToString</code> can still be called.
 +
<syntaxhighlight lang="cpp">
 
   //C++
 
   //C++
 
   //interface methods should be qualified with the interface they belong to
 
   //interface methods should be qualified with the interface they belong to
Line 65: Line 59:
 
           }
 
           }
 
   };
 
   };
 +
</syntaxhighlight>
  
 +
{{Note|Although <tt>XFoo::ToString</tt> is virtual, it cannot be overridden in an inheriting class, because the CLI method header contains the final attribute. In an inheriting class one can, however, derive again from <tt>XFoo</tt> and provide an implementation.}}
  
{{Documentation/Note|尽管 XFoo::ToString 是虚拟的,但由于 CLI 方法头包含 final 属性,因此在继承类中无法将其重载。但是,在继承类中,可以再次由 XFoo 派生并提供实现。}}
+
In C# there are different ways provide an implementation:
 
+
<syntaxhighlight lang="csharp">
 
+
C# 中,提供实现有不同的方法:
+
 
+
 
   // IL contains: newslot final virtual
 
   // IL contains: newslot final virtual
 
   public new string ToString()
 
   public new string ToString()
 
   {
 
   {
 
   }
 
   }
 
+
</syntaxhighlight>
关键字 new newslot 属性插入到 CLI 方法头中:在继承类中,无法重载此实现。
+
The keyword new inserts the <code>newslot</code> attribute in the CLI method header. This implementation cannot be overridden in an inheriting class.
 
+
<syntaxhighlight lang="csharp">
 
   //IL contains: newslot virtual
 
   //IL contains: newslot virtual
 
   public new virtual string ToString()
 
   public new virtual string ToString()
 
   {
 
   {
 
   }
 
   }
 
+
</syntaxhighlight>
 
+
This method can be overridden in a derived class.
在派生类中,可以重载此方法。
+
  
 
   // Using a qualified method name for the implementation. The virtual  
 
   // Using a qualified method name for the implementation. The virtual  
Line 94: Line 86:
 
   }
 
   }
  
 
+
This implementation cannot be overridden in a derived class. An instance of the implementing class must be cast to <code>XFoo</code> before the method can be called.
在派生类中,无法重载此实现。调用方法前,必须先将实现类的实例转换成 XFoo。
+
<syntaxhighlight lang="vb">
 
+
 
   'VB .NET
 
   'VB .NET
 
   Public Shadows Function ToString() As String Implements XFoo.ToString
 
   Public Shadows Function ToString() As String Implements XFoo.ToString
 
           Console.WriteLine("Foo.toString")
 
           Console.WriteLine("Foo.toString")
 
   End Function
 
   End Function
 
+
</syntaxhighlight>
 
+
This implementation cannot be overridden in a derived class.
在派生类中,无法重载此实现。
+
<syntaxhighlight lang="vb">
 
+
 
   Public Overridable Shadows Function ToString() As String _
 
   Public Overridable Shadows Function ToString() As String _
 
   Implements XFoo.ToString
 
   Implements XFoo.ToString
           Console.WriteLine("Foo.toString"
+
           Console.WriteLine("Foo.toString")
 
   End Function
 
   End Function
 
+
</syntaxhighlight>
可以重载此方法。
+
This method can be overridden.
  
 
{{PDL1}}
 
{{PDL1}}
  
[[Category:文档/开发者指南/专业 UNO]]
+
[[Category:Documentation/Developer's Guide/Professional UNO]]

Latest revision as of 16:04, 23 December 2020



The term “override problem” describes a problem that occurs when a virtual function of a base object becomes unreachable because an interface method overrides the implementation of the base class. For example, all CLI objects derive from System.Object. If an interface has a method that has the same signature as one of System.Object's methods, then the respective method of System.Object is unreachable if the interface method is virtual.

For example, consider the following declaration of the interface XFoo and its implementing class :

 using namespace System;
 
 public __gc __interface XFoo
 {
 public:
         virtual String* ToString();
 };
 
 public __gc class Foo : public XFoo
 {
 public:
         virtual String * ToString()
         {
                  return NULL;
         }
 };

If the method ToString of an instance is called, then the implementation of the interface method is invoked. For example:

 int main(void)
 {
         Foo * f = new Foo();
         Object * o = f;
         f->ToString(); // calls Foo.ToString
         o->ToString(); // calls Foo.ToString
 
     return 0;
 }

This may not be intended, because the interface method likely has a different semantic than its namesake of System.Object.

A solution is to prevent the interface method from overriding the method of System.Object without making the interface method non-virtual. The CLI provides a remedy by way of the “newslot” flag, which is attached to the method header in the IL code. CLI languages may have different means for denoting a method with “newslot”.

The following examples show ways of implementing XFoo in different languages, so that Object.ToString can still be called.

  //C++
  //interface methods should be qualified with the interface they belong to
  public __gc class A: public XFoo
  {
  public:
          virtual String* XFoo::ToString()
          {
                   Console::WriteLine("A::foo");
                   return NULL;
          }
  };
Documentation note.png Although XFoo::ToString is virtual, it cannot be overridden in an inheriting class, because the CLI method header contains the final attribute. In an inheriting class one can, however, derive again from XFoo and provide an implementation.

In C# there are different ways provide an implementation:

  // IL contains: newslot final virtual
  public new string ToString()
  {
  }

The keyword new inserts the newslot attribute in the CLI method header. This implementation cannot be overridden in an inheriting class.

  //IL contains: newslot virtual
  public new virtual string ToString()
  {
  }

This method can be overridden in a derived class.

 // Using a qualified method name for the implementation. The virtual 
 //modifier is not allowed
 string XFoo.ToString()
 {
                   return null;
 }

This implementation cannot be overridden in a derived class. An instance of the implementing class must be cast to XFoo before the method can be called.

  'VB .NET
  Public Shadows Function ToString() As String Implements XFoo.ToString
           Console.WriteLine("Foo.toString")
  End Function

This implementation cannot be overridden in a derived class.

  Public Overridable Shadows Function ToString() As String _
  Implements XFoo.ToString
          Console.WriteLine("Foo.toString")
  End Function

This method can be overridden.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages