"Tutorial" "Reprint" C # Sharp Experience (Li Jianzhong)-04

Source: Internet
Author: User
Tags abstract define bool exception handling hash implement inheritance tostring
Tutorial C # Sharp Experience
Iv. class and Object [/b]

Nanjing University of Posts and Telecommunications Li Jianzhong (cornyfield@263.net)

Component programming is not to discard traditional object-oriented objects, and the opposite component programming is the deepening and development of object-oriented programming. Class as the object-oriented soul in the C # language has a considerable depth of application, many very "Sharp" component features are even directly from the class packaging. The depth of the class mastery of nature is our "Sharp XP" important link.
class
The C # class is a data structure that encapsulates data members, function members, and nested types. Where data members can be constants, fields. A function member can be a method, a property, an indexer, an event, an operator, an instance builder, a static builder, and a destructor. We will make a detailed analysis of these members and their characteristics in the five-talk constructor and destructor and the sixth domain method properties and indexers. In addition to some imported external methods, declarations and implementations of classes and their members in C # are often put together.
C # uses a variety of modifiers to express the different properties of a class. There are five different restriction modifiers based on their protection-level C # classes:
    1. Public can be arbitrarily accessed;
    2. Protected can only be accessed by this class and its inheriting subclasses;
    3. Internal can only be accessed by all classes within this group (Assembly), which is the logical unit and physical unit of a class in the C # language, and the compiled file name extension is often ". DLL "or". EXE ".
    4. Protected internal a unique combination restriction modifier that can be accessed only by all classes in this combination and by inheriting subclasses of those classes.
    5. Private can only be accessed by this class.

If it is not a nested class, the class within the namespace or compilation unit has only public and internal two adornments.
The new modifier can only be used for nested classes that represent a hidden type that inherits the parent class with the same name.
Abstract is used to decorate an abstraction class, which means that the class can only be used as a parent class for inheritance, not object instantiation. An abstract class can contain abstract members, but this is not necessary. Abstract cannot be used at the same time as new. Here is the pseudo code for the abstract class usage:
Abstract class a{public abstract void F ();} Abstract class b:a{public void G () {}}class c:b{public override void F () {//Method F implementation}}

Abstract Class A contains an abstract method F (), which cannot be instantiated. Class B inherits from Class A, which contains an instance method g (), but does not implement the abstract method F (), so it must still be declared as an abstract class. Class C inherits from Class B, implements the class abstract method F (), and can then instantiate the object.
Sealed is used to decorate a class as a sealed class, preventing the class from being inherited. At the same time, the modification of the abstract and sealed of a class is meaningless and is forbidden.
object with the This keyword
The distinction between classes and objects is critical to our mastery of OO programming. We say class is a kind of encapsulation of its members, but the encapsulation design of class is only the first step in our programming, the object instantiation of class, and the implementation of operation on its data member is the fundamental of our realistic task. The instantiated object takes the MyClass myobject=new MyClass () syntax, where the new semantics will invoke the corresponding builder. All of the objects in C # will be created on the managed heap. The type of the instantiation we call the object, whose core feature is a copy of its own unique data member. These are the data members held by the unique objects that we call instance members. Instead of the data members that are held by objects that are not unique, we call them static members, declared with the static modifier in the class. A member of a static function that enforces operations only on static data members. Static data members and function members in C # can only be obtained by using the class name reference, looking at the following code:
Using system;class a{    public int count;    public void F ()      {        console.writeline (This.count);     }    public static string name;    public static void G ()      {        console.writeline (name);     } }class test{    public static void Main ()     {         a a1=new A ();         a a2=new A ();         a1. F ();        a1.count=1;         a2. F ();        a2.count=2;         a.name= "CCW";         a.g (); &nBSP;  &NBSP}} 

We have declared two a object a1,a2. For instance member Count and F (), we can only use the A1,A2 reference. For static member name and G () we can only reference it through type A, not a1.name, or a1.g ().
In the above program, we see that in instance method F () We use this to refer to the variable count. What do you mean by this? The This keyword refers to the members of the current object instance. In an instance method body we can also omit this and refer directly to count, which in fact has the same semantics. Of course, static member functions do not have this pointer. This keyword is typically used to access members from constructors, instance methods, and instance accessors.
This is used in constructors to qualify members that are hidden by the same name, for example:
Class Employee{public Employee (string name, string alias) {this.name = name;    This.alias = alias; }}

You also use this expression when you pass an object as a parameter to another method, for example:
Calctax (this);

This is essential when declaring indexers, for example:
public int this [int param]{get {return array[param];      } set {Array[param] = value; }}

System.Object Class
All classes in C # inherit directly or indirectly from the System.Object class, which allows classes in C # to be inherited single roots. If we do not explicitly specify an inheritance class, the compiler defaults to the class that inherits from the System.Object class. The System.Object class can also be represented by the lowercase object keyword, which is exactly equivalent. All classes in natural C # inherit the common interfaces of the System.Object class, and parsing them is important for us to understand and master the behavior of classes in C #. The following is the System.Object class, which is represented only in the form of an interface:
Namespace system{public class Object {public static Boolean Equals (Object obja,object objb) {} public St atic bool ReferenceEquals (object Obja,object objb) {} public object () {} public virtual bool Equals (Object obj                {} public virtual int GetHashCode () {} public Type GetType () {} public virtual string ToString () {} protected virtual void Finalize () {} protected Object MemberwiseClone () {}}

We first look at the two static method equals (object Obja,object objb) of object, ReferenceEquals (object Obja,object OBJB), and an instance method equals (object obj). Before we explain these two methods, we need to be clear about two important equality concepts of object-oriented Programming: value equality and reference equality. Equal values mean that their data members are equal in bits of memory. Reference equality means that they point to the same memory address, or that their object handles are equal. Reference equality necessarily introduces equal value. For a value type relationship equals "= =" to determine whether the value is equal (the struct type and enum type do not define the relationship equal sign "= =", we must define it ourselves). For reference type relationship equals "= =" to determine whether the two references are equal. Value types typically do not refer to equal representations in C #, and only the address character "&" is used in unmanaged programming to indirectly determine whether the addresses are equal.
static method Equals (Object Obja,object OBJB) first checks that all two objects obja and OBJB are null, and returns True if they are, otherwise obja.equals (OBJB) calls and returns their values. The problem boils down to instance method equals (object obj). The default implementation of this method is actually {return this= =obj;} That is, to determine whether two objects reference equality. But we notice that the method is a virtual method, and C # recommends that we override this method to determine whether two objects are of equal value. In fact, many of the types provided within the Microsoft.NET Framework class library Override the method, such as: System.String (String), System.Int32 (int), and so on, but some types do not override the method such as: System.Array, we must pay attention when using. For reference types, if there is no overridden instance method equals (object obj), our invocation of it is equivalent to the this= =obj, that is, the reference equality judgment. All value types (implicitly inherited from the System.ValueType Class) Override instance method equals (object obj) to determine whether the values are equal.
Note returns false for object X,x.equals (null), where x is clearly not null (otherwise the Equals () call cannot be completed, and the system throws a null reference error). From here we can also see the reason for designing the static method Equals (object Obja,object OBJB)-If two objects Obja and OBJB can be null, we can only use object. Equals (object Obja,object OBJB) to determine whether they are of equal value--of course, if we don't overwrite instance method equals (object obj), we get a result that is still reference equal. We can implement interface IComparable (we will describe the interface in "seventh interface Inheritance and polymorphism") to force Overwrite instance method equals (object obj).
For value types, instance method equals (object obj) should be consistent with the return value of the equal equals "= =", that is, if we override instance method equals (object obj), we should also overload or define the relationship equal sign "= =" operator, and vice versa. Although the value type (inherited from the System.ValueType Class) Overrides instance method equals (object obj), C # recommends that we override the instance method equals (object obj) of our own value type. Because the system's System.ValueType class overrides are inefficient. For reference types We should override instance method equals (object obj) to express equal values, and generally should not overload the relation equal sign "= =" operator because its default semantics is to judge the reference to be equal.
The static method ReferenceEquals (object Obja,object OBJB) determines whether two objects reference equality. If two objects are reference types, then its semantics are the same as the equals "= =" operator without overloading the relationship. If the two object is a value type, its return value must be false.
The instance Method GetHashCode () provides a hash (hash) code value for the corresponding type, and is applied to the hash algorithm or hash table. It should be noted that if we rewrite an instance method equals (object obj) of a certain type, we should also rewrite the instance method GetHashCode ()--which is, of necessity, equal values for two objects, and their hash codes should be equal. The following code is a good example of a few previous methods:
Using system;struct a{    public int count;} class b{    public int number;} Class C{    public int integer=0;    public override bool Equals (object obj) & Nbsp;   {        c C=obj as C;         if (c!=null)              Return this.integer==c.integer;        else             return false;    }     public override int GetHashCode ()     {        return 2 ^integer;    }}class test{    public static void Main ()      {        a A1,A2;       &Nbsp;a1.count=10;        a2=a1;         //console.write (A1==A2) does not define the "= =" operator         console.write ( A1. Equals (A2));//true        console.writeline (object. ReferenceEquals (A1,A2));//false        b b1=new B ();         b b2=new B ();        b1.number=10;         b2.number=10;         Console.Write (B1==B2);//false        console.write (B1. Equals (B2));//false        console.writeline (object. ReferenceEquals (B1,B2));//false        b2=b1;         console.write (B1==B2);//true   &nBsp;    console.write (B1. Equals (B2));//true        console.writeline (object. ReferenceEquals (B1,B2));//true        c c1=new C ();         c c2=new C ();        c1.integer=10;         c2.integer=10;         Console.Write (C1==C2);//false        console.write (C1. Equals (C2));//true        console.writeline (object. ReferenceEquals (C1,C2));//false        c2=c1;         console.write (C1==C2);//true         Console.Write (C1. Equals (C2));//true        console.writeline (object. ReferenceEquals (C1,C2));//TRUE   &NBSP}} 

As we expect, compiling the program and running it will get the following output:
      TrueFalse
      Falsefalsefalse
      Truetruetrue
      Falsetruefalse
      Truetruetrue

The instance method GetType () is the same as the semantics of the TypeOf, and they all determine the object's run-time type by querying the object's metadata, and we elaborate on the tenth feature and mapping.
Instance method ToString () returns the string representation of an object. If we do not override this method, the system typically returns the type name as a string.
The protected finalize () method has special semantics in C #, which we will elaborate on in "the five-talk constructor and the destructor."
The protected MemberwiseClone () method returns a "shadow copy" of the current object, which cannot be overridden by a quilt class. "Shadow copy" is just a copy of a bitwise copy of an object, meaning a copy of the value type variable within the object, and a handle copy of the reference type variable inside it, that is, the copied reference variable holds a reference to the same block of memory. Relative to shadow copy is a deep copy, which makes a value copy of a variable of a reference type, rather than a handle copy. For example, X is an object that contains an object a,b reference, and object A contains a reference to the object M. Y is a "shadow copy" of X. Then Y will have the same a,b reference. But for a "deep copy" Z of x, it will have references to objects C and D, and a reference to an indirect object n, where C is a copy of a, D is a copy of B, and N is a copy of M. The deep copy is done in C # by implementing the ICloneable interface (providing the clone () method).
The mastery of objects and System.Object is a good cushion for class learning, but this is only one small step for our sharp trip, about object member initialization, memory reference release, inheritance and polymorphism, exception handling, and so many "Sharp" stunts are vast, let us continue to look forward to the following topic!

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.