> Chapter Fifth Class (Rainbow translation) *1 (from heavy particle space)

Source: Internet
Author: User
Tags definition class definition exception handling garbage collection implement interface variables tostring
<< Show c#>> Fifth Chapter class (Rainbow translation)
Source: http://www.informit.com\matter\ser0000002
Body:
Fifth Chapter Class
The previous chapter discusses data types and their usage. Now we move to the most important structure in C #-class. Without a class, even a simple C # program cannot be compiled. This chapter assumes that you know the basic components of a class: Methods, properties, constructors, and destructors. C # has added indexes and events to it.
In this chapter, you learn the following topics about class.
。 Using constructors and destructors
。 Write method to Class
。 Add attribute access flags to a class
。 Implementing an Index
。 Create an event and associate a customer with an event by representing a dollar
。 Apply classes, members, and access modifiers.

5.1 Constructors and destructors
Before you can access a class's methods, properties, or anything else, the first executed statement is a constructor that contains the corresponding class. Even if you do not write a constructor yourself, there will also be a default constructor provided to you.

Class TestClass
{
Public TestClass (): Base () {}//supplied by compiler
}

A constructor is always the same as its class name, but it does not declare a return type. In summary, constructors are always public, and you can use them to initialize variables.

Public TestClass ()
{
Give the variable here
Initialization code, and so on.
}

You can create a private constructor if the class contains only static members (which can be invoked as a type instead of a member called by an instance).
Private TestClass () {}
Although the access modifier will be discussed in greater detail later in this chapter, private means it is not possible to access the constructor from outside the class. Therefore, it cannot be invoked, and no object can be instantiated from that class definition.
is not limited to a parameterless constructor-you can pass the initial argument to initialize the member.
Public TestClass (string strName, int nage) {...}

You may be accustomed to writing an additional method for initialization, as a C + + programmer, because there is no return value in the constructor. Of course, although there is no return value in C #, you can throw a homemade exception to get the return value from the constructor. More knowledge of exception handling is discussed in the seventh chapter, "Exception Handling".
However, when you keep references to valuable resources, you should think of writing a method to solve: one can be explicitly invoked to free these resources. The problem is why you write an additional method when you can do the same thing in the destructor (named in front of the class name plus "~").
Public ~testclass ()
{
Clear
}

The reason you should write an additional method is the garbage collector, which is not invoked immediately after the variable is out of range, and is triggered only if the intermittent period or memory condition is satisfied. It happens when you lock the resource longer than you plan to time. Therefore, it is a good idea to provide an explicit release method, which can also be invoked from a destructor.

public void Release ()
{
Release all the valuable resources
}

Public ~testclass ()
{
Release ();
}

It is not necessary to call a release method in a destructor--in short, garbage collection will pay attention to releasing the object. But not forgetting to erase is a good habit.

5.2 Method
Now that the object can initialize and end correctly, what remains is adding functionality to the class. In most cases, the main part of the function can be implemented in the method. You've already seen the use of static methods, but these are part of the type (class), not the instance (object).
In order to get you started quickly, I've arranged the tedious issues of these methods for the following sections:
。 Method parameters
。 Rewriting methods
。 Method Mask
5.2.1 Method Parameters
Because the method is going to handle changing values, you have to pass the value to the method more or less and get the return value from the method. The following three sections relate to problems caused by passing values and retrieving the returned results for the caller.

。 Input parameters
。 Reference parameters
。 Output parameters

5.2.1.1 Input Parameters
One of the parameters that you have seen in the example is the input parameter. You use an input parameter to pass a variable by value to a method--the variable of the method is initialized by a copy of the value passed in by the caller. Listing 5.1 demonstrates the use of input parameters.

Listing 5.1 passing parameters by value

1:using System;
2:
3:public class Squaresample
4: {
5:public int calcsquare (int nsidelength)
6: {
7:return nsidelength*nsidelength;
8:}
9:}
10:
11:class Squareapp
12: {
13:public static void Main ()
14: {
15:squaresample sq = new squaresample ();
16:console.writeline (Sq. Calcsquare (25). ToString ());
17:}
18:}

Because I pass a value instead of a reference to a variable, you can use a constant expression (25) when calling a method (see line 16th). The integer result is passed back to the caller as the return value, and it is immediately displayed to the screen without saving to the intermediate variable.
Input parameters are working in a way that is already used by C + + programmers. If you are from VB, please note that there is no implicit ByVal or byref--that can be processed by the compiler if not set, the parameter is always passed by value.
This seems to conflict with what I have stated earlier: For some variable types, passing by value actually means passing by reference. Are you confused? A bit of background knowledge does not need: COM is the thing is the interface, each class can have one or more interfaces. An interface is simply a set of function pointers that do not contain data. Repeating the array wastes a lot of memory resources; Therefore, only the start address is copied to the method, which, as the caller, still points to the same pointer to the interface. That's why the object passes a reference with a value.

5.2.1.2 Reference Parameters
Although you can use input parameters and return values to create many methods, you are less fortunate when you think of passing a value and modifying it in place (that is, in the same memory location). It is convenient to use reference parameters here.
void MyMethod (ref int ninout)
Because you pass a variable to the method (not just its value), the variable must be initialized. Otherwise, the compiler will alert you. Listing 5.2 shows how to create a method with a reference parameter.

Listing 5.2 Passing arguments by reference

1://Class Squaresample
2:using System;
3:
4:public class Squaresample
5: {
6:public void Calcsquare (ref int None4all)
7: {
8:none4all *= None4all;
9:}
10:}
11:
12:class Squareapp
13: {
14:public static void Main ()
15: {
16:squaresample sq = new squaresample ();
17:
18:int nsquaredref = 20; Be sure to initialize
19:sq. Calcsquare (ref nsquaredref);
20:console.writeline (Nsquaredref.tostring ());
21:}
22:}

As you can see, all you have to do is add a ref qualifier to both the definition and the call. Because a variable is passed by reference, you can use it to calculate the result and return the result. However, in real-world applications, I strongly recommend that you use two variables, an input parameter, and a reference parameter.

5.2.1.3 Output parameters
The third option for passing a parameter is to set it as an output parameter. As the name implies, an output parameter is used only to pass back a result from the method. Another difference between it and reference parameters is that the caller does not have to initialize the variable before calling the method. This is shown in Listing 5.3.

Listing 5.3 defines an output parameter

1:using System;
2:
3:public class Squaresample
4: {
5:public void Calcsquare (int nsidelength, out int nsquared)
6: {
7:nsquared = Nsidelength * NSIDELENGTH;
8:}
9:}
10:
11:class Squareapp
12: {
13:public static void Main ()
14: {
15:squaresample sq = new squaresample ();
16:
17:int nsquared; Do not have to initialize
18:sq. Calcsquare (out nsquared);
19:console.writeline (Nsquared.tostring ());
20:}
21:}


5.2.2 Rewriting method
The important principle of object-oriented design is polymorphism. Regardless of the advanced theory, polymorphism means that when a base class programmer has designed a method for rewriting, in a derived class you can redefine (overwrite) the method of the base class. The base class programmer can use the Virtual keyword design method:
virtual void Canboverridden ()
When deriving from a base class, all you have to do is add the override keyword to the new method:
override void Canboverridden ()
When rewriting a method of a base class, you must understand that you cannot change the access property of the method--you will learn more about access modifiers later in this chapter.
In addition to overwriting the fact of the base class method, there is another, even more important, rewriting feature. When you cast a derived class to a base class type and then call a virtual method, you are called a method of the derived class rather than the base class.
((BaseClass) derivedclassinstance). Canboverridden ();
To demonstrate the concept of virtual methods, listing 5.4 shows how to create a triangular base class that has a member method that can be overwritten (Computearea).

Listing 5.4 Ways to rewrite a base class

1:using System;
2:
3:class Triangle
4: {
5:public virtual double Computearea (int a, int b, int c)
6: {
7://Heronian formula
8:double s = (A + B + C)/2.0;
9:double Darea = math.sqrt (s* (s-a) * (s-b) * (s-c));
10:return Darea;
11:}
12:}
13:
14:class Rightangledtriangle:triangle
15: {
16:public override double Computearea (int a, int b, int c)
17: {
18:double Darea = a*b/2.0;
19:return Darea;
20:}
21:}
22:
23:class Triangletestapp
24: {
25:public static void Main ()
26: {
27:triangle tri = new triangle ();
28:console.writeline (Tri.computearea (2, 5, 6));
29:
30:rightangledtriangle rat = new Rightangledtriangle ();
31:console.writeline (Rat.computearea (3, 4, 5));
32:}
33:}

The base class triangle defines the method Computearea. It takes three parameters, returns a double result, and has public access. Derived from the Triangle class is the rightangledtriangle, which rewrites the Computearea method and implements its own area calculation formula. All two classes are instantiated and validated in the main () method of the application class named Triangletestapp.
I missed the explanation. Line 14th:
Class Rightangledtriangle:triangle
A colon (:) In a class statement indicates that Rightangledtriangle derives from the class triangle. That's what you have to do to get C # to know that you want to use triangle as a rightangledtriangle base class.
When you look closely at the Computearea method of the right-angled triangle, you will find that the 3rd parameter is not used for calculation. However, you can use this parameter to verify that it is "right angle." As shown in Listing 5.5.

Listing 5.5 calls the base class implementation

1:class Rightangledtriangle:triangle
2: {
3:public override double Computearea (int a, int b, int c)
4: {
5:const double Depsilon = 0.0001;
6:double Darea = 0;
7:if (Math.Abs (a*a + b*b-c*c)) > Depsilon)
8: {
9:darea = Base.computearea (a,b,c);
10:}
11:else
12: {
13:darea = a*b/2.0;
14:}
15:
16:return Darea;
17:}
18:}

This test simply uses the Pythagorean formula, and for a right-angled triangle, the test result must be 0. If the result is not 0, the class calls its base class's computearea to implement it.
Darea = Base.computearea (a,b,c);
The point of the example is that you can easily invoke the base class implementation rewrite method by explicitly using the qualification check of the base class.
This is helpful when you need to implement its functionality in the base class rather than repeating it in a way that overwrites it.

5.2.3 Method Mask
A different way to redefine a method is to mask the method of the base class. This feature is particularly valuable when deriving classes from a class that is provided by others. Look at listing 5.6, assuming BaseClass is written by someone else, and you derive derivedclass from it.

Listing 5.6 Derived class implements a method that is not included in the Base class

1:using System;
2:
3:class BaseClass
4: {
5:}
6:
7:class Derivedclass:baseclass
8: {
9:public void TestMethod ()
10: {
11:console.writeline ("Derivedclass::testmethod");
12:}
13:}
14:
15:class TestApp
16: {
17:public static void Main ()
18: {
19:derivedclass test = new DerivedClass ();
20:test. TestMethod ();
21:}
22:}

In this example, DerivedClass implements an additional function through the TestMethod (). But what happens when a base class developer thinks it's a good idea to put TestMethod () in a base class and implement it with the same name? (See listing 5.7)

Listing 5.7 Base class implements the same method as Derived class

1:class BaseClass
2: {
3:public void TestMethod ()
4: {
5:console.writeline ("Baseclass::testmethod");
6:}
7:}
8:
9:class Derivedclass:baseclass
10: {
11:public void TestMethod ()
12: {
13:console.writeline ("Derivedclass::testmethod");
14:}
15:}

In a good programming language, you will now encounter a real big problem. But C # will give you a warning:
Hiding2.cs (13,14): Warning CS0114: ' Derivedclass.testmethod () ' hides inherited member ' Baseclass.testmethod () '. To make is override that implementation, add the override keyword. Otherwise add the New keyword.
(Hiding2.cs (13,14): Warning CS0114: ' Derivedclass.testmethod () ' Masks inherited members ' BaseClass. TestMethod () '. To make the current method overwrite the original implementation, add the override keyword. Otherwise add a new keyword. )
With the modifier new, you can tell the compiler that you do not have to rewrite the derived class or change the code that uses the derived class, and your method can mask the newly added base class method. Listing 5.8 shows how to use the new modifier in the example.

Listing 5.8 Shielding base class method

1:class BaseClass
2: {
3:public void TestMethod ()
4: {
5:console.writeline ("Baseclass::testmethod");
6:}
7:}
8:
9:class Derivedclass:baseclass
10: {
11:new public void TestMethod ()
12: {
13:console.writeline ("Derivedclass::testmethod");
14:}
15:}

With the additional new modifier, the compiler knows that you have redefined the base class method, and it should mask the base class method. However, if you are writing in the following way:
DerivedClass test = new DerivedClass ();
((baseclass) test). TestMethod ();
The implementation of the base class method is invoked. This behavior differs from rewriting methods, which ensure that most derived 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.