The same is true of the invocation of an interface method and the rules that take access to an index indicator as in a class. If the name of the underlying member is the same as the high-level member inherited, the underlying member overwrites the top-level member with the same name. However, because the interface supports multiple inheritance, in multiple inheritance, if two parent interfaces contain members of the same name, this yields two semantics (which is one of the reasons why C # removes multiple inheritance mechanisms for classes) and requires explicit declarations.
Program Listing 15-2:
Using System;
Interface isequence
{
int count{get;set;}}
Interface iring
{
void count (int i);
}
Interface iringsequence:isequence,iring{}
class C
{
void Test (Iringsequense rs) {
//rs. Count (1); Error, Count has two semantic
//rs. Count=1; Error, Count has two semantic
((isequence) RS). Count=1; Correct
((iring) RS). Count (1); Correct call to iring Count
}
}
In the example above, the first two statements x. Count (1) and X. Count=1 generates two semantics, resulting in compile-time errors, so you must explicitly assign the parent interface type to x, which does not incur additional overhead at run time.
Look at the following example:
Program Listing 15-3:
Using System;
Interface Iinteger
{
void Add (int i);
}
Interface idouble
{
void Add (double d);
}
Interface inumber:iinteger,idouble{}
class C
{
void Test (inumber n) {
//n.add (1); Error
N.add ( 1.0); Correct
((Iinteger) n). ADD (1); Correct
((idouble) n). ADD (1); Correct
}
}
Call N. ADD (1) produces two semantics because the parameter types of the candidate overloaded methods apply. However, call N. ADD (1.0) is allowed because 1.0 is a floating-point number and the parameter type is inconsistent with the parameter type of the method Iinteger.add (), at which point only idouble.add is applicable. However, as long as the explicit assignment is added, no two semantics will be generated.
Problems with multiple inheritance of interfaces can also result in member access issues.
Interface IBase
{
void F (int i);
}
Interface Ileft:ibase
{
new void F (int i);
}
Interface Iright:ibase
{
void G ();
}
Interface iderived:ileft,iright{}
class A
{
void Test (iderived d) {
D.F (1); Call ILeft.F
((ibase) d). F (1); Call IBase.F
((ileft) d). F (1); Call ILeft.F
((iright) d). F (1); Call IBase.F
}
}
In the example above, method IBase.F is overridden by the ILeft member method F in the derived interface ILeft. So to D. The call to F (1) actually called. Although from the IBase----iright---iderived This inheritance path, the ILeft.F method is not overwritten.
We just have to keep this in mind: once a member is overwritten, all accesses to it are blocked by the member after it has been overwritten.