C # And. NET3.5 advanced programming (version 4th) Note 6

Source: Internet
Author: User

Chapter 6 inheritance and Polymorphism

This chapter focuses on the two pillars of OOP, inheritance and polymorphism. First, I learned how to use inheritance to build a family of related classes. Then I learned how to create a multi-state interface between virtual and abstract members in the class hierarchy. Finally, I introduced the role of super parent class System. Object.

6.1 inheritance

In OOP, there are two types of code reuse: one is the classic inheritance (is-a relationship), and the other is the include/delegate model (has-a relationship ), the former is generally referred to as inheritance.

The basic idea of classic inheritance is that new classes can use or expand the functions of existing classes. Use the colon operator (:) to create an inheritance relationship between classes in class definition. Subclass will haveEvery public Member. Even if no member is added to the subclass, you can directly access the public members of the parent class to reuse the code. Note: The subclass cannot access any private member of the parent class.

The base class is used to define general features that all derived types share. Subclass extends these general functions by adding specific behaviors.

In. NET, each class must have only one direct base class. Multi-inheritance is not supported. However, a class or structure type is allowed to implement many independent interfaces. In this way, the C # type can implement many behaviors and avoid the complexity caused by multiple inheritance. In addition, although only one base class can be inherited, an interface can be derived directly from multiple interfaces. Therefore, a flexible interface level can be built to model complex behaviors. In addition, the system provides the sealed keyword to prevent inheritance. On the one hand, many tool classes should be defined as closed. On the other hand, some classes do not want to be inherited after being inherited from multiple layers. You can also use this function.

The base keyword can be used in the inheritance relationship chain for two purposes:

(1) Optimize the constructor of the derived class

Generally, the default constructor of the base class isAutomatic Call. To help optimize the creation of a derived class, it is best to implement the subclass ConstructorExplicitCall an appropriate custom base class constructor instead of the default constructor. This reduces the number of calls to inherited initialization members. (This saves time). Using this method is similar to using this to call the constructor chain, which means that the derived constructor transfers dataRecentIn the parent Constructor (upper-level ).

Public manager (string fullname, int age): base (fullname)

{}

In this way, the constructor with the parameter fullname in the base class is called!

Q: Can I use this and base on the constructor at the same time? How to write?

(2) Use a Public Member of the parent class

Base is not used only by the constructor logic. Any subclass that wants to access a public or protected member defined by the parent class can use the base keyword. For example:

Public sales ()

{

Base. fun1 ();

}

Note that the two usage methods are slightly different.

It must be emphasized that base access can only be performed in constructors, instance methods, or instance attribute accessors.
It is incorrect to use the base keyword in a static method.

Protected Keyword:

When the base class defines protected data or protected members, it creates a set of items that can be directly accessed by any descendant. For objects outside the family, the protected data is private and cannot be accessed!

Sealed Keyword:

The sealing class cannot be extended by other classes. If you want to build a new class to use the sealing class function, the only way is to discard the classic inheritance and use the include/delegate model. The value type is sealed and cannot be inherited. In addition, sealed can be modified.

Include/delegate model:

IncludeIt is to instantiate another class in the definition of a class, for example:

Class benefitpackage

{

Protected benefitpackage emp = new benefitpackage ();

}

So far, another object has been included and used inside the class.

However, to publish the functions of contained objects to the external worldDelegate. Simply put, a delegate is to add members to the include class to use the functions of the contained object. For example, based on the above Code, add:

Public double getbenefitcost ()

{

Return emp. computepaydeduction ();

}

Public benefitpackage benefits

{

Set {mepbenefits = value ;}

Get {return mepbenefits ;}

}

So far, the external world can access this contained object.

Nested type:

The nested type is in C # and can be directly in the class or structure scope.Define type(Enumeration, class, interface, structure or delegate), if so, nested (or internal)TypeConsidered as a nested (or external) ClassMember. You can operate on nested types like other members.

Because it is considered a member, it has the following features:

  • Any access modifier that controls members can also be used for the nested type;

So don't be surprised to see private class... because this class is a nested type, not an independent class. As a member, the default value isImplicit private. However, it can be set to public, protected internal, protected, internal, or private.

  • You can accessPrivate member

Because it is in the include class, not the external.

  • It is usually used only as an auxiliary method for external classes, rather than for the external world.

Otherwise, it is defined as an independent type. Why do we need to nest it.

The nested type is indeed a bit complicated. It has both the characteristics of the type and the nature of the Members. For details, refer to the following article:

The http://msdn.microsoft.com/en-us/library/ms173120 (zh-cn, VS.80). aspx

Http://www.cnblogs.com/MyLoverLanlan/archive/2009/01/06/1370745.html

6.2 Polymorphism

The polymorphism makes related types make different responses to the same request. It provides a way for sub-classes to customize methods with their basic class definitions. This process is calledRewrite. (Different from overload), to achieve the purpose of modifying the current design, you need to understand the role of the virtual and override keywords.

If the methods to be defined by the base class can be overwritten by the subclass, you should specify virtual Methods in the base class ). In the subclass, if the subclass wants to change the implementation details of the virtual method, the override keyword must be used.

Note that, since override is the implementation of the rewrite method, the name, return type, and parameters of the rewrite method must be exactly the same! In addition, the override method cannot be declared as virtual or abstract in the base class, and the virtual or abstract method must be public, because private methods cannot be overwritten.

In addition, you can override methods orAttributeBecause the attribute is essentially a method!

Previously, when we mentioned the sealed keyword to modify a class, in order to make the class unable to be inherited, we sometimes need to use sealed to modify a method in the class without continuing to rewrite it. Sealed and override must be used at the same time:

PublicOverride sealedTest ()

{}

This method overwrites the method inherited by the base class, and requires that this method cannot be overwritten when the child class is inherited.

Abstract class:

If you want a class not to be instantiated, but to be inherited, You need to declare the class as abstract. If it is defined as an abstract base class, it can define many abstract members, abstract members can be used to define members that do not provide default implementations. This forces each descendant to have a multi-state interface and they need to process the details of the abstract method themselves. In short, the multi-state interface of the abstract base class refers to a set of virtual or abstract methods.

Note: abstract classes can contain non-Abstract METHODS (common methods and virtual methods) and abstract methods.Abstract METHODS can only be declared in abstract classes.Otherwise, the compilation is incorrect.

Note: The class can be an abstract class or a sealed class. The abstract method must be in the abstract class, And the sealed method can be in any class.

6.3 relationship and conversion between base classes and sub classes

Member projection:

The function opposite to rewrite is projection. If the Members defined in the derived class are consistent with those defined in the base class (fields, constants, static methods, attributes, etc.), the derived class projects (overwrites) the version of the parent class. Need to useNewThe keyword modifies the member of the subclass to implement projection. The explicit declaration of the implementation of the derived type is intentionally designedHideThe version of the parent class.

Note that even the projection virtual or abstract method is acceptable. This is actually equivalent to override. Of course, even if the base class members are overwritten, explicit forced conversions can still be used to trigger the implementation of shadow members (subclass members) in the base class:

Circle mycircles = new circle ();

Mycircles. show (); // assume that show uses the new projection method.

(Shape) mycircles). show (); // call the show method of the parent class to forcibly convert

Conversion rules for base classes and derived classes:

Conversions are classified into implicit conversions and Explicit conversions (or forced conversions). Likewise, there are two rules:

(1) If two classes are associated through the "is-a" relationship, it is always safe to point to the derived type in the base class reference, because it is based on the inherited rule, that is, upward conversion, the subclass is converted to the parent class type.

Shape myshapes = new circle (); // circle "is-a" shape

Object myobjects = new shape (); // shape "is-a" object

The rule is that after an equal sign, it must be a subclass before an equal sign. If a subclass is converted to a parent class, the unique feature of the subclass is lost because it has become a parent class. Do not think that the conversion of "Lost things" cannot be implicitly converted either by the system. These conversions are essentially different from conventional conversions, which do not actually perform any data conversion on objects. If the conversion is legal, they only set the new reference to reference the object.

This is because any reference to the class shape can reference the class shape object or the object derived from the shape. In OO programming, the instance of the derived class is actually the instance of the base class, but some additional information is added. Therefore, the first three of the following statements can be implicitly converted. However, if you want to convert the fourth statement successfully, this is the next rule.

Shape derivedObject = new circle ();

Shape baseObject = new shape ();

Circle derivedCopy1 = (circle) derivedObject; // OK

Circle derivedCopy2 = (circle) baseObject; // Throws exception

Similarly, a method parameter can pass this parameter type and all its child types are valid.

(2) the C # forced conversion operator (parentheses) must be used for explicit downward conversion. That is, the parent class is forcibly converted to a subclass:

Circle derivedCopy2 = (circle) baseObject;

Q: I don't know why this book didn't mention: in fact, conversion still fails at runtime. Strictly speaking, the parent class cannot be converted to a subclass, subclass contains all the methods and attributes of the parent class, while the parent class does not necessarily have the same membership scope as the subclass. Therefore, this conversion is not allowed, even if there are two empty types with parent-child relationships, of course, you can write some instances that seem to have been converted from the parent class to the subclass, but this conversion is meaningless. According to the Liskov replacement principle, converting a parent class to a subclass is a serious violation of OOP. It is neither advocate nor recommended.

Therefore, a real parent class cannot be converted to a subclass. The implicit conversion is definitely caused by an error in compilation. Secondly, even if it is forced conversion, no compilation error occurs, however, an error occurs during running. What is the significance of this conversion?

This means that only one scenario can force the conversion to succeed (both compilation and runtime are successful:

The parent class is originally converted by sub-classes and then converted back (or continue to convert.

For example, if the relationships between classes are a, B, and c (c inherits B, B inherits a), if a class is converted from c to, then this c object can be forcibly converted to B or even c type. Let's look at the following code:

Classchil B = new Classchil (); // Classpar is the parent class and Classchil is a subclass.
Classpar c = new Classchil (); // c is the parent class converted from Classchil
B = (Classchil) c; // naturally, the parent class c can be converted back to its original class, subclass.

A similar application is that if the method parameter is of the parent class, if a subclass is passed (this is acceptable of course), The subclass is implicitly converted to the parent class, in the method, if it is determined that it is a subclass and you want to call the subclass member, you should convert this parameter back to the subclass (forced conversion) and then call the corresponding subclass member.

If you check whether a forced type conversion is successful, the common method is to catch possible exceptions through try-catch, but for this type conversion, c # provides the following two keywords to determine:

As Keyword:

The as keyword quickly checks whether a type is compatible with another type at runtime. You can check the compatibility (whether the conversion is successful) by checking the null return value ). Of course, the conditions for successful conversion are still in the bold text above.

The as rules are as follows:

  • Check the compatibility of object types and return results. If not, return null;
  • No exception is thrown.

Circle derivedCopy2 = baseObject as circle; // The baseObject is the parent class object.

If (derivedCopy2 = null)

{}

Is Keyword:

The is keyword is provided to check whether the two items are compatible (the condition is still in the black text above). Unlike the as, if the type is incompatible, is returns false instead of null.

Is rules are as follows:

  • Check the compatibility of object types and return results, true or false;
  • No exception is thrown;
  • If the object is null, the return value is always false.

If (baseObject is circle)

{

Circle derivedCopy2 = (circle) baseObject;

}

Note: This sentence must be judged. If it is compatible, the force conversion will continue.

In summary, the is/as operator provides a more flexible type transformation method,As is first converted before judgment, is first judgment, then conversion. The as operator is superior in execution efficiencyIn actual programming, we should understand the similarities and differences and make appropriate decisions.

6.4 super parent class System. Object

In the. NET world, all types will eventually be derived from the base class of System. Object. If the constructed class does not explicitly define its base class, the compiler will automatically derive our type from the Object, then the following colon and object can be absent:

Class car: object

{}

Object defines a group of Members. Some are declared as virtual, some are instance-level, and some are static members.

Q: On the 168th page of the book, I said that the object has a virtual member Finalize, but in 2008, why didn't I have this?

There are a few concepts that need to be emphasized:

Among all the 50 recommendations in Objective C #, the only one is the recommendation on unrecommended functions.GetHashCode() This method is only used in one place: defines the Hash value for the Key of the Hash-based Collection (such as HashTable and Dictionary), that is, the object is used as the Key, and the GetHashCode () of the object () obtain the Hash value for this Key.

MemberwiseCloneMethod To create a superficial copy, specifically to create a new object, and then copy the non-static fields of the current object to the new object. If the field is of the value type, perform a step-by-step copy on the field. If the field is of reference type, the referenced object is copied but not referenced. Therefore, the original object and its counterparts reference the same object.

6.5 conclusion

Here, based on the previous chapter and this chapter, we will summarize the keywords used to modify the class:

  • Public: public class
  • Internal: internal class
  • Partial: partial class
  • Abstract: abstract class
  • Sealed: sealed
  • Static: static class

Public and internal cannot modify a class at the same time. abstract, sealed, and static cannot modify the same class at the same time. Other cases can be matched as needed, and the partial must be next to the type (class, struct, interface. For example:

Sealed public partial class groovy {},

Then summarize the keywords that can be modified for members (methods, attributes:

  • Public
  • Private
  • Internal
  • Protected
  • Protected internal
  • Abstract
  • Vitrual
  • Override
  • New
  • Static
  • Stealed override

Public, private, internal, protected, and protected internal cannot be used at the same time. Abstract, vitrual, override, new, static, and stealed override cannot exist at the same time. The override or stealed override method must be abstract or virtual orOverrideThe access modifier of the parent class, but the order of other keywords can be changed. Abstract METHODS can only be used in abstract classes.

To sum up, we can modify the keywords of member variables:

  • Public
  • Private
  • Internal
  • Protected
  • Protected internal
  • New
  • Static

Public, private, internal, protected, and protected internal cannot be used at the same time. New and static cannot exist at the same time.

For the differences between new and override, refer:

Http://www.cnblogs.com/OpenCoder/archive/2009/11/20/1607225.html

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.