Objective C # Principle 20: differences between interface implementation and overload of virtual functions)

Source: Internet
Author: User

Objective C # Principle 20: differences between interface implementation and virtual function Overloading
Item 20: distinguish between implementing interfaces and overriding virtual functions

After a rough look, we feel that the implementation interface and the virtual function overload are the same. You have defined some objects, but these objects are declared in another type. You are cheated by the first thought, and the Implementation interface and the virtual function overload are completely different. By default, the Members defined in the interface do not have actual content at all.

A derived class cannot overload interface members in a base class. Interfaces can be implicitly implemented by hiding them from the public interfaces of the class. They have different concepts and are used differently.

However, you can implement this interface so that your derived class can modify your implementation. You only need to create a hook for the derived class. I believe that I have written C ++ProgramPeople will know what hook means, and I really can't think of the hook into anything better, so I just directly use the original word hook, just like a bug .)

To demonstrate their differences, try to make a simple interface and implement it in a class:

Interface imsg
{
Void message ();
}

Public class myclass: imsg
{
Public void message ()
{
Console. writeline ("myclass ");
}
}

The message () method is a public interface of myclass, and the message can also be accessed using an interface pointer imsg. Now let's add a derived class:

Public class myderivedclass: myclass
{
Public new void message ()
{
Console. writeline ("myderivedclass ");
}
}

Note that I added a keyword new on the message method to distinguish the previous message (see Principle 29 ). Myclass. Message () is not a virtual function. The derived class does not provide an overloaded version. The myderived class creates a new message method, but this method does not overload myclass. Message: It hides the original method. In addition, myclass. Message can still be accessed through imsg reference:

Myderivedclass d = new myderivedclass ();
D. Message (); // prints "myderivedclass ".
Imsg M = D as imsg;
M. Message (); // prints "myclass"

The interface method is not virtual. When you implement an interface, you must declare the specific implementation content in the detailed related types.

However, you may want to create interfaces, implement these interfaces in the base class, and modify their behavior in the derived class. This can be achieved. You have two options. If you do not access the base class, you can re-implement this interface in the derived class:

Public class myderivedclass: myclass, imsg
{
Public new void message ()
{
Console. writeline ("myderivedclass ");
}
}

The added imsg changes the behavior of your derived class, And imsg. Message is currently used on the derived class:

Myderivedclass d = new myderivedclass ();
D. Message (); // prints "myderivedclass ".
Imsg M = D as imsg;
M. Message (); // prints "myderivedclass"

The new keyword must be added to the myderivedclass. Message () method in the derived class. This poses a hidden risk (see Principle 29 ). The base class can still be accessed through interface reference:

Myderivedclass d = new myderivedclass ();
D. Message (); // prints "myderivedclass ".
Imsg M = D as imsg;
M. Message (); // prints "myderivedclass"
Myclass B = D;
B. Message (); // prints "myclass"

The only way to solve this problem is to modify the base class and change the interface declaration to a virtual function:

Public class myclass: imsg
{
Public Virtual void message ()
{
Console. writeline ("myclass ");
}
}

Public class myderivedclass: myclass
{
Public override void message ()
{
Console. writeline ("myderivedclass ");
}
}

Myderivedclass and all other classes derived from myclass can declare their own message () methods. This overloaded version is called every time: it is referenced through the myderivedclass, through the imsg interface, or directly through the myclass reference.

If you do not like the mixed concept of virtual functions, make a small modification to the definition of myclass:

Public abstract class myclass, imsg
{
Public abstract void message ();
}

Yes, you can use an abstract method to implement an interface. By declaring an abstract method in an interface, you can enable all your derivation to implement this interface. Now, the imsg interface is an integral part of myclass, and each of your derived classes must implement it.

Implicit interface implementation allows you to hide common interface member methods on a class, and also implements this interface. It loops around the implementation interface and virtual function overload. When there are multiple suitable function versions, you can use the implementation of the implicit interface to limit user encoding. Icomparable habits mentioned in principle 26 will discuss this in detail.

Implementing interfaces gives us more options for creating and reloading virtual functions. You can create hidden implementations, virtual implementations, or abstract associations to derived classes. You can accurately determine how and when your derived class modifies the default Implementation of the interface. The interface method is not a virtual method, but an independent convention!
====================================

Item 20: distinguish between implementing interfaces and overriding virtual functions
At first glance, implementing an interface seems to be the same as overriding avirtual function. you provide a definition for a member that has been declared in another type. that first glance is very deceiving. implementing an interface is very different from overriding a virtual function. members declared in interfaces are not virtualat least, not by default.

Derived classes cannot override an interface member implemented in a base class. interfaces can be explicitly implemented, which hides them from a class's public interface. They are different concepts with different uses.

But you can implement interfaces in such a manner that derived classes can modify your implementation. You just have to create hooks for derived classes.

To restrict strate the differences, examine a simple interface and implementation of it in one class:

Interface imsg
{
Void message ();
}

Public class myclass: imsg
{
Public void message ()
{
Console. writeline ("myclass ");
}
}

 

The message () method is part of myclass's public interface. message can also be accessed through the imsg point that is part of the myclass type. now let's complicate the situation a little by adding a derived class:

Public class myderivedclass: myclass
{
Public new void message ()
{
Console. writeline ("myderivedclass ");
}
}

 

Notice that I had to add the new keyword to the definition of the previous message method (see item 29 ). myclass. message () is not virtual. derived classes cannot provide an overridden version of message. the myderived class creates anew message method, but that method does not override myclass. message: It hides it. furthermore, myclass. message is still available through the imsg reference:

Myderivedclass d = new myderivedclass ();
D. Message (); // prints "myderivedclass ".
Imsg M = D as imsg;
M. Message (); // prints "myclass"

 

Interface methods are not virtual. When you implement an interface, you are declaring a concrete implementation of a particle contract in that type.

But you often want to create interfaces, implement them in base classes, and modify the behavior in Derived classes. you can. you 've got two options. if you do not have access to the base class, you can reimplement the interface in the derived class:

Public class myderivedclass: myclass, imsg
{
Public new void message ()
{
Console. writeline ("myderivedclass ");
}
}

 

The addition of the imsg keyword changes the behavior of your derived class so that imsg. Message () now uses the derived class version:

Myderivedclass d = new myderivedclass ();
D. Message (); // prints "myderivedclass ".
Imsg M = D as imsg;
M. Message (); // prints "myderivedclass"

 

You still need the new keyword on the myderivedclass. message () method. that's your clue that there are still problems (see item 29 ). the base class version is still accessible through a reference to the base class:

Myderivedclass d = new myderivedclass ();
D. Message (); // prints "myderivedclass ".
Imsg M = D as imsg;
M. Message (); // prints "myderivedclass"
Myclass B = D;
B. Message (); // prints "myclass"

 

The only way to fix this problem is to modify the base class, declaring that the interface methods shoshould be virtual:

Public class myclass: imsg
{
Public Virtual void message ()
{
Console. writeline ("myclass ");
}
}

Public class myderivedclass: myclass
{
Public override void message ()
{
Console. writeline ("myderivedclass ");
}
}

 

Myderivedclassand all classes derived from myclasscan declare their own methods for message (). The overridden version will be called every time: Through the myderivedclass reference, through the imsg reference, and through the myclass reference.

If you dislike the concept of impure virtual functions, just make one small change to the definition of myclass:

Public abstract class myclass, imsg
{
Public abstract void message ();
}

 

Yes, you can implement an interface without actually implementing the methods in that interface. by declaring abstract versions of the methods in the interface, you declare that all types derived from your type must implement that interface. the imsg interface is part of the declaration of myclass, but defining the methods is deferred to each derived class.

Explicit interface implementation enables you to implement an interface, yet hide its members from the public interface of your type. its use throws a few other twists into the relationships between implementing interfaces and overriding virtual functions. you use explicit interface implementation to limit client code from using the interface methods when a more appropriate version is available. the icomparable idiom in item 26 shows this in detail.

Implementing interfaces allows more options than creating and overriding virtual functions. you can create sealed implementations, virtual implementations, or abstract contracts for class hierarchies. you can decide exactly how and when derived classes can modify the default behavior for members of any interface your class implements. interface methods are not virtual methods, but a separate contract.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.