Difference between revisions of "Documentation/DevGuide/ProUNO/CLI/The Override Problem"
Line 1: | Line 1: | ||
− | {{Documentation/DevGuide/ProUNOTOC | + | {{Documentation/DevGuide/ProUNOTOC |
|ProUNO2c=block | |ProUNO2c=block | ||
|CLIBinding=block | |CLIBinding=block | ||
|ClientProg=block | |ClientProg=block | ||
|ShowPrevNext=block | |ShowPrevNext=block | ||
− | |PrevPage= | + | |PrevPage=Documentation/DevGuide/ProUNO/CLI/Writing Client Programs |
− | |NextPage= | + | |NextPage=Documentation/DevGuide/ProUNO/CLI/Important Interfaces and Implementations |
}} | }} | ||
− | + | {{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. | |
− | + | For example, consider the following declaration of the interface <code>XFoo</code> and its implementing class : | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
using namespace System; | using namespace System; | ||
Line 33: | Line 29: | ||
}; | }; | ||
− | + | If the method <code>ToString</code> of an instance is called, then the implementation of the interface method is invoked. For example: | |
− | + | ||
int main(void) | int main(void) | ||
Line 46: | Line 41: | ||
} | } | ||
+ | This may not be intended, because the interface method likely has a different semantic than its namesake of <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>”. | |
− | + | The following examples show ways of implementing <code>XFoo</code> in different languages, so that <code>Object.ToString</code> can still be called. | |
− | + | ||
− | + | ||
− | + | ||
//C++ | //C++ | ||
Line 67: | Line 60: | ||
− | {{Documentation/Note| | + | {{Documentation/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.}} |
− | + | In C# there are different ways provide an implementation: | |
− | + | ||
// IL contains: newslot final virtual | // IL contains: newslot final virtual | ||
Line 77: | Line 69: | ||
} | } | ||
− | + | The keyword new inserts the <code>newslot</code> attribute in the CLI method header. This implementation cannot be overridden in an inheriting class. | |
− | + | ||
//IL contains: newslot virtual | //IL contains: newslot virtual | ||
Line 85: | Line 76: | ||
} | } | ||
− | + | 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 95: | Line 85: | ||
} | } | ||
− | + | 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. | |
− | + | ||
'VB .NET | 'VB .NET | ||
Line 103: | Line 92: | ||
End Function | End Function | ||
− | + | This implementation cannot be overridden in a derived class. | |
− | + | ||
Public Overridable Shadows Function ToString() As String _ | Public Overridable Shadows Function ToString() As String _ | ||
Line 111: | Line 99: | ||
End Function | End Function | ||
− | + | This method can be overridden. | |
{{PDL1}} | {{PDL1}} | ||
− | [[Category: | + | [[Category:Documentation/Developer's Guide/Professional UNO]] |
Revision as of 06:17, 18 July 2008
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; } };
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). |