Nanjing University of Posts and Telecommunications Li Jianzhong (Cornyfield@263.net)
Methods, also known as member functions, concentrated in the behavior of classes or objects. Methods are also divided into static methods and examples. The static method can only operate static domains, while the instance method can operate the instance domain or the static domain - although this is not recommended, it will be useful in certain special situations. The method also has five types of access modifiers as the domain --public, protected, internal, protected in both, private, and their significance are as described above.
Method parameters
The parameters of the method are places worth particular attention. The parameters of the method have four types: BY value, by reference, output parameter (by output), array parameters (by array). The transmission value parameter does not require additional modifiers, the address parameter requires the modifier REF, the output parameter requires modifier OUT, and the array parameters require modifier params. The pass value parameter is changed during the method call, so the parameter of the incoming method is not changed after the method call is completed, but the value of the original incoming is retained. The inquiry of the inline parameter is the opposite. If the method calling process changes the value of the parameter, the parameter of the incoming method is also changed after the call is completed. In fact, from the name we can clearly see the meaning of the meaning - the transmission value parameter is a copy of the calling parameter, and the address parameter passes the memory address of the calling parameter, which is pointed out inside and outside the method. Is the same storage location. Look at the examples below and their output:
Using system;
Class test
{
Static Void Swap (Ref Int X, Ref Int Y)
{
INT TEMP = X;
X = Y;
Y = TEMP;
}
Static void swap (int x, int y)
{
INT TEMP = X;
X = Y;
Y = TEMP;
}
Static void main ()
{
INT i = 1, J = 2;
SWAP (Ref I, REF J);
Console.writeline ("i = {0}, j = {1}", i, j);
SWAP (i, j);
Console.writeline ("i = {0}, j = {1}", i, j);
}
}
The program executes the output after compiling:
i = 2, j = 1
i = 2, j = 1
We can clearly see that the two exchange functions SWAP () is different from the difference between the parameters - the pass value and the address, and obtain different call results. Note that the method calls for the service parameters should be plus the Ref modifier when they are declared or called.
In general, the value does not change the value of the parameters in some cases, and we look at one example:
Using system;
Class Element
{
Public int number = 10;
}
Class test
{
Static Void Change (Element S)
{
S.Number = 100;
}
Static void main ()
{
ELEMENT E = New Element ();
Console.writeLine (E.NUMBER);
Change (e);
Console.writeLine (E.NUMBER);
}
}
The program executes the output after compiling:
10
100
We see that even if the pass value has changed the type of object T for the ELEMENT class. However, in strict sense, we have changed the domain of the object T, not the object T itself. We look at the example below: use system;
Class Element
{
Public int number = 10;
}
Class test
{
Static Void Change (Element S)
{
ELEMENT R = New Element ();
R.Number = 100;
s = R;
}
Static void main ()
{
ELEMENT E = New Element ();
Console.writeLine (E.NUMBER);
Change (e);
Console.writeLine (E.NUMBER);
}
}
The program executes the output after compiling:
10
10
The pass value does not change the type of object T for the Element class at all. In fact, if we can understand the characteristics of the reference type in this C #, we can see the difference between the above two examples! During the pass value, the reference type itself will not change (T does not change), but the domain containing the reference type will change (T.Number changes)! The c # language reference types are: Object types (including system built-in Class types and user-built Class Types - Inherited from Object Types), String Type, Interface Type, Array Type, delegate Type. They have the characteristics of the above two examples in the pass value call.
In the case of passing values and delivery, the C # enforcement requirements parameters are explicitly initialized by the user before passing, otherwise the compiler is wrong! But if we don't rely on the function of the first value, we just need to get a function to get its value what to do? It is often necessary to return the value in our function. We specially need this skill. The answer is the output parameter modified with OUT. However, it is necessary to remember that the output parameter has a certain difference between the return value of the usual function: Function return value often exists in the stack, pops up when it returns; and output parameters require users to pre-depart the storage location, that is, the user needs to declare the variable in advance - of course It can also be initialized. Look at the example below:
Using system;
Class test
{
Static Void ResolutionName (String Fullname, Out String Firstname)
{
String [] stratay = fullname.split (new char [] {''});
Firstname = stratay [0];
Lastname = strRay [1];
}
Public static void main ()
{
String myname = "cornfield lee";
String myfirstname, mylastname;
ResolutionEname (MyName, Out myfirstname, out mylastname);
Console.writeline ("My First Name: {0}, my last name: {1}",
Myfirstname, mylastname;
}
}
The program executes the output after compiling:
My First Name: Cornfield, My Last Name: Lee
All output parameters in the function must be assigned, otherwise the compiler error! OUT modifiers should also be applied to function declarations and call two places. In addition to acting as a special function of returning, the OUT modifier Ref modifier has a similar place: an address. We can see that C # completely abandoned the traditional C / C language to give the programmer's magical freedom, after all, C # is used to develop an efficient next-generation network platform, security - including system security (system structure) and engineering security (Avoiding the error of programmers) is an important consideration when it is designed. Of course, we see C # does not lose how many languages are lost because of security, this is the excellence of C #, "Sharp"! Array parameters are also a place we often use - pass a large number of array set parameters. Let's take a look at the example below:
Using system;
Class test
{
Static int sum (params int [] args)
{
INT S = 0;
Foreach (Int N in args)
{
S = N;
}
Return S;
}
Static void main ()
{
Int [] var = new int [] {1, 2, 3, 4, 5};
Console.writeline ("The Sum:" SUM (VAR);
Console.writeline ("The Sum:" SUM (10, 20, 30, 40, 50);
}
}
The program executes the output after compiling:
The Sum: 15
THE SUM: 150
It can be seen that the array parameters may be arrays such as: Var, or may be implicitly converted to array parameters such as: 10, 20, 30, 40, 50. This provides a high scalability for our procedures.
The difference between the same name method parameters will result in a polymorphic phenomenon, which is also a overloading method. It is to be pointed out that the compiler is bound to the method and method call when compiling. You can only overload the method by different parameters, other different (such as return values) cannot provide valid overload information for the compiler.
Methods Inheriting the first-class method of object-oriented mechanisms introduced four modifiers for Virtual, Override, Sealed, and Abstract to provide different inheritance requirements. The imaginary method of the class is to change its implementation in the inheritance of such classes, of course, this change is limited to the change of the method body, rather than the change of the method head (method declaration). The false method of the quilt change must be represented in the method header. When an imaginary method is called, the instance of such a class is also the runtime type (run-time type) of the object to determine which method is called. Let's look at the example below:
Using system;
Class Parent
{
Public void f () {console.writeLine ("parent.f");}
Public Virtual Void g () {console.writeLine ("parent.g");}
}
Class Child: Parent
{
New public void f () {console.writeLine ("child.f");}
Public override void g () {console.writeLine ("child.g");
}
Class test
{
Static void main ()
{
Child b = new child ();
Parent a = B;
A.f ();
B.f ();
A.G ();
B.G ();
}
}
The program executes the output after compiling:
Parent.f
Child.f
Child.g
Child.g
We can see the declaration of the Class Child's F () method takes a rewriting method to shield the declaration of non-virtual methods f () in the Class Parent. The G () method uses an override method to provide a polymorphism mechanism. It should be noted that the rewrite method and the override method are different. From essentially rewriting method is compiled, the overlay method is binding time. It is worth noting that the virtual method can not be a static method - that is, it is not possible to use Static and Virtual to modify a method, which is determined by its runtime analysis mechanism. Override must be used in conjunction with Virtual, of course, cannot be used simultaneously with Static.
So if we don't want to make an imaginary method in a class's inheritance system, what should we do? The answer is Sealed Override, and we will reach this for Sealed and Override simultaneously to achieve this purpose: Sealed Override public void f (). Note that this must be used in Sealed and Override, and it must also be a seal to cover a virtual method, or an imaginary method that is covered (rather than sealed). Sealing a non-virtual method is meaningless, it is also wrong. Look at the example below:
//sealed.cs
// CSC / T: library seled.cs
Using system;
Class Parent
{
Public Virtual Void f ()
{
Console.writeline ("parent.f");
}
Public Virtual Void G ()
{
Console.writeline ("parent.g");
}
}
Class Child: Parent
{
Sealed Override public void f ()
{
Console.writeline ("child.f");
}
Override public void g ()
{
Console.writeline ("child.g");
}
}
Class Grandson: Child
{
Override public void g ()
{
Console.writeLine ("Grandson.g");
}
}
Abstract approach is logically similar to the false method, but cannot be called like virtual methods, but only a declaration of an interface is not implemented. The abstract method is not similar to the method of {...}, nor does it allow this. The abstract method can also be static. Class containing abstract methods must be an abstract class, and must also add Abstract to modifiers. But abstract classes do not have to contain abstract methods. Inheriting an abstract class of an abstract method must be covered and implemented (directly using Override) the method, or combined using Abstract Override to continue abstraction, or not to provide any coverage and implementation. The behavior of the two is the same. Look at the example below:
//ABSTRACT1.CS
// CSC / T: library abstract1.cs
Using system;
Abstract Class Parent
{
Public abstract void f ();
Public Abstract Void g ();
}
Abstract Class Child: Parent
{
Public Abstract Override void f ();
Abstract Class Grandson: Child
{
Public override void f ()
{
Console.writeline ("GrandSon.f");
}
Public Override Void G ()
{
Console.writeLine ("Grandson.g");
}
}
Abstract method can abstract a inherited imaginary method, let's see the example below:
//abstract2.cs
// CSC / T: library abstract2.cs
Using system;
Class Parent
{
Public Virtual Void Method ()
{
Console.writeline ("parent.method");
}
}
Abstract Class Child: Parent
{
Public Abstract Override void method ();
}
Abstract Class Grandson: Child
{
Public Override Void Method ()
{
Console.Writeline ("Grandson.Method");
}
}
At the end of the root, we grasp the basic mechanisms of binding and compile time, we can see the peers of all of the way OverLoad, Virtual, Override, Sealed, Abstract, etc., we can use this tool!
External method
C # introduces Extern modifiers to represent an external method. The external method is a method implemented by a language other than C #, such as the Win32 API function. As far as the external method cannot be an abstract method. We look at an example:
Using system;
Using system.Runtime.InteropServices;
Class myclass
{
[DLLIMPORT ("User32.dll")]]]]]
Static Extern Int MessageBoxa (int hwnd, string msg, string capen, int type);
Public static void main ()
{
MessageBoxa (0, "Hello, World!", "This Is Called from A C # App!", 0);
}
}
The program executes the output after compiling:
Here we call the Win32 API function int MessageBoxa (int hWnd, String Msg, String Caption, Int Type).