The difference between static methods, instance methods, and virtual methods

Source: Internet
Author: User

Basic knowledge

For object-oriented languages, All types are derived from the System.Object type, and it is for this reason that each type is guaranteed to have a basic set of methods, that is, to inherit the methods from their parent class System.Object, the definition of object as shown in the following code, the basic method defined by System.Object Basically contains all of the CLR's method types, static methods (static adornments, belonging to class members), virtual methods (virtural decorated, instance members), instance methods (common methods, members of instances). Some may say that there are abstract methods, in fact, the final compilation of abstract methods is also a virtual method.

One of the most important features of the CLR is type safety, and at run time the CLR always knows what type of object it is, and we see an GetType method in object that always knows the exact type of an object, since GetType is a non-virtual instance method, This ensures that a derived type cannot override it, so one type cannot be disguised as another, but it can be done if we want to intentionally hide it (we can overwrite the GetType method with the new keyword), but generally we do not recommend it.

So how does the GetType method return the True type of an object? This introduces a new concept, which is also a "type Object", and when we create an object on the managed heap using the new keyword, we roughly do a few things:

 classProgram {Static voidMain (string[] args) {Person P=NewPerson ("Aseven");        Console.readkey (); }    }     Public classPerson {Private string_name; Private int_age;  Public stringName {Get{return_name;} Set{_name =value;} }         Public Virtual voidSay () {Console.WriteLine ("******"); }         Public StaticPerson Find (stringname) {            return Newperson (name);//Simulating database lookups        }         Public intGetage () {return_age; }         PublicPerson () {} PublicPerson (stringname) {             This. _name =name; }    }
View Code

1. For all instance fields of the computed type and all base types (until System.Object, although it has no instance fields defined) (Note: No static fields and methods) are required for the number of bytes, each object on the heap requires some extra members---that is, type object pointers and synchronous index blocks, which are used by the CLR to manage objects and also to be counted into The size of the object.

2. Allocate the memory of the object from the managed heap and initialize the field to 0 (0).

3. Initialize the object's "type Object pointer" and "Synchronize Index block".

4. Executes the instance constructor and passes it to the argument specified in the call to new ("Aseven" in the previous example), and most compilers automatically generate code to call the constructor of the base class and, ultimately, the System.Object constructor.

After new executes, a reference (or pointer) to the object in the heap is returned, and for the above example, the reference (address) is stored in the variable e, and after the person object is created, the memory structure is roughly the following, and you can see that the type object pointer is to the type object of person.

Summary: After an instance object is created, the variable e holds a reference (pointer) to the person object in the managed heap. The person object indicates that an instance field of the object is saved (including the type object pointer and the synchronized index block), as for the static field, the method list is stored in the person's type object, especially the list of methods, which contains static methods, instance methods, virtual methods, Let's describe how these three methods are called.

Invocation of the method

1. Static method: When a static method is called, the CLR locates the type object corresponding to the type that defines the static method (a bit around). The corresponding record entry is then looked up in the method list of the type object, JIT-compiled (if necessary), and then called.

2. Example method: When a non-virtual instance method is called, the JIT compiler finds the type object corresponding to the type of the variable (p) that makes the call, and if the method list of the type object does not contain the called method, the JIT compiler backtracking the class hierarchy (which goes back to object). And find this method in each type of method collection along the way, so backtracking, because each type of object has a field that refers to his accumulation, this information is not displayed on the way.

3, virtual method: When a virtual method is called, generates some extra code, each time the method is called, the code is executed, the code first checks the calling variable, and then follows the address (that is, the pointer to the object saved in P) to the object that emitted the call, and then the code checks the object's internal " The type object pointer is a member that points to the object's type object, and then the code looks for the method in the method collection of the type object, JIT-compiles (if necessary), and calls the JIT-compiled code. If not, the methods defined in the base class are also looked up.

The following are examples:

classProgram {Static voidMain (string[] args) {Person P=NewPerson ("test1"); P= Person.find ("Aseven"); intAge =P.getage ();            P.say ();        Console.readkey (); }    }     Public classPerson {Private string_name; Private int_age;  Public stringName {Get{return_name;} Set{_name =value;} }         Public Virtual voidSay () {Console.WriteLine ("******"); }         Public StaticPerson Find (stringname) {            return NewChinese (name);//Simulating database lookups        }         Public intGetage () {return_age; }         PublicPerson () {} PublicPerson (stringname) {             This. _name =name; }    }     Public classChinese:person { PublicChinese (stringname) {             This. Name =name; }         Public Override voidSay () {Console.WriteLine ("Hi there! "); }    }     Public classAmerican:person { PublicAmerican (stringname) {             This. Name =name; }         Public Override voidSay () {Console.WriteLine ("hello! "); }    }
View Code

1, first we define the person object, person p=new person (), this code after execution and memory allocation above basically similar.

2, we call the static method of the person, P=person.find ("Aseven"), according to the above definition, call a static method will directly find the type object's method list, directly call, after the call we see the Find method directly returned a Chinese object , this creates a Chinese object in the managed heap, and stores the address in the variable p, where p is not the address of the person object, but the address of the Chinese object (and of course it could be a American object, If find returns a American object).

3, then we call P. A non-virtual instance method of Getage () that, when the CLR invokes a non-virtual instance method, finds the Getage method based on the type object (Person type object) that emits the caller (P), and, if not found, the backtracking base class lookup. This method is called directly because there is a method in the collection of methods for the type object of person. The returned result (here is 0) is stored in an age variable of line stacks.

4. Calling the P.say () method, the Say method is a virtual method that the CLR finds the real object (Chinese object) in the managed heap based on the address of the caller (P) (here is a pointer to the Chinese object), and then finds the real type object based on the objects in the managed heap (this is the Chinese type Object ), and iterates through the method collection to find the Say method, (in case the Chinese class overrides the Say method, there is a method in the method collection of the Chinese type Object) to invoke.

This is the allocation of memory roughly as follows: Because the person object already has no other object reference, it will be the next major object of garbage collection.

Test Demo
 Public classA { Public voidmethodf () {Console.WriteLine ("A.F"); }         Public Virtual voidMETHODG () {Console.WriteLine ("A.G"); }    }     Public classb:a {New  Public voidmethodf () {Console.WriteLine ("B.f"); }         Public Override voidMETHODG () {Console.WriteLine ("B.G"); }    }    classTest {Static voidMain () {b b; b=NewB (); A A=b;            A.METHODF ();            B.METHODF ();            A.METHODG ();        B.METHODG (); }
View Code

Output results: A.F, B.f, B.G, B.G

1, first METHODF is a non-virtual instance method, at this time we use a. METHODF (); Because A is an instance of type A, the output is A.F.

2, then call B. METHODF (), since B is an instance of type B, and B overrides the Methodf method of a, the Methodf method is already in the method table of the type object of the B type object and is called directly, so the output is B.F

3, because METHODG is a virtual method, we use a. When METHODG is called, the specific object in the managed heap is first found based on the address (pointer) stored in a, and the actual type object is found based on the specific object, where a is an instance of B, so the object's type object is the type object of type B,

The call will look directly at the collection of methods in the type object of Type B object, find the Methodg method and call it, so the output is B.G

4, for B. MEHTODG, the object in the managed heap is first found based on the address (pointer) stored in B, and then the actual type object is found based on the specific object, where B is an instance of B, so the object's type object is the type object of type B, The call will look directly at the collection of methods in the type object of Type B object, find the Methodg method and call it, so the output is B.G

Summarize

1. The invocation of a method is accomplished by looking up a collection of methods in the Type object.

2. The static method directly finds the type object in the method combination to make the call.

3, the non-virtual instance method is based on the caller (for the above demo, the line stacks variable A, B is the caller) type to find the corresponding type object, and then find the type of the object's method collection to call, did not find the backtracking base class to find.

4, the virtual method is based on the caller (for the above demo, the line stacks variable A, B is the caller) to find the specific object in the managed heap, and then according to the object to find the real type object, and then according to the type object to find the method collection.

The difference between static methods, instance methods, and virtual methods

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.