". NET programming Pioneer C #" fifth chapter (Next) (Turn)

Source: Internet
Author: User
Tags abstract define command line implement inheritance instance method variables textout
Programming 5.2.3 Method Masking
A different way to redefine a method is to mask the method of the base class. When deriving a class from a class provided by someone else, this feature

It's not worth it. 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 (). However, if the base class's

Developers think it's a good idea to put TestMethod () in a base class, and what happens when you implement it with the same name

It? (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

The keyword. )
With the modifier new, you can tell the compiler that you don't have to rewrite the derived class or change the code that uses the derived class, 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 write in the following way:
DerivedClass test = new DerivedClass ();
((baseclass) test). TestMethod ();
The implementation of the base class method is invoked. This behavior differs from the Overtype method, which guarantees that most derived methods are called.
5.3 Class Properties
There are two ways to expose the naming properties of a class-either through a domain member or through a property. The former is implemented as a member variable with public access, and the latter does not respond directly to the storage location, but is accessed through the access flag (accessors).
When you want to read or write the value of a property, the access flag qualifies the implemented statement. The access flag used to read the value of the property is the keyword get, and the read-write flag of the value to modify the property is set. Before you have a smattering of this theory, take a look at the example in Listing 5.9, where the attribute Squarefeet is marked with access flags for get and set.
Listing 5.9 implements the attribute access flag
1:using System;
2:
3:public Class House
4: {
5:private int m_nsqfeet;
6:
7:public int Squarefeet
8: {
9:get {return m_nsqfeet;}
10:set {m_nsqfeet = value;}
11:}
12:}
13:
14:class TestApp
15: {
16:public static void Main ()
17: {
18:house myhouse = new House ();
19:myhouse.squarefeet = 250;
20:console.writeline (Myhouse.squarefeet);
21:}
22:}

House class has a property named Squarefeet, which can be read and written. The actual value is stored in a variable that can be accessed from within the class--if you want to rewrite it as a domain member, all you have to do is omit the access flag and redefine the variable to:
public int squarefeet;
For such a simple variable, that's good. However, if you want to hide the details of a class's internal storage structure, you should use an Access flag. In this case, the set access flag passes the new value to the property in the value parameter. (Can be renamed, see Line 10th.) )
In addition to being able to hide the implementation details, you are free to define various actions:
Get and set: Allows read and write access to attributes.
Get only: values that allow only read properties.
Set only: Values for write properties are allowed only.
In addition, you can get the opportunity to implement valid code in the SET flag. For example, you can reject a new value for a variety of reasons (or for no reason at all). It's best if no one tells you it's a dynamic property--When you first request it, it's saved, so try to postpone the resource allocation as much as possible.

5.4 Index
Do you ever want to use an indexed access class like an array? With the indexing function of C #, the expectation of it can be closed.

The syntax is basically like this:
Property modifier declaration {declaration Content}

The concrete example is
public string This[int nindex]
{
get {...}
set {...}
}

The index returns or presses the given index set string. It has no attributes, but uses the public modifier. The Declarations section consists of a type string and this is used to represent the index of the class. Get and set have the same rules for executing rules and properties. (You can't cancel one of them.) There is only one difference: You can almost arbitrarily define the parameters in the braces. Limited to, you must specify at least one argument that allows ref and out modifiers.
This keyword ensures an explanation. The index does not have a user-defined name, this represents the index of the default interface. If the class implements more than one interface, you can add more indexes described by Interfacename.this.

To demonstrate the use of an index, I created a small class that can parse a host name as an IP address-or a list of IP addresses (take http://www.microsoft.com as an example). This list can be accessed through the index, you can look at the list

5.10 of the concrete implementation.

Listing 5.10 Gets an IP address through an index

1:using System;
2:using System.Net;
3:
4:class Resolvedns
5: {
6:ipaddress[] m_arrips;
7:
8:public void Resolve (String strhost)
9: {
10:iphostentry Iphe = DNS. gethostbyname (Strhost);
11:m_arrips = Iphe. AddressList;
12:}
13:
14:public IPAddress This[int Nindex]
15: {
16:get
17: {
18:return M_arrips[nindex];
19:}
20:}
21st:
22:public int Count
23: {
24:get {return m_arrips.length;}
25:}
26:}
27:
28:class Dnsresolverapp
29: {
30:public static void Main ()
31: {
32:resolvedns mydnsresolver = new Resolvedns ();
33:mydnsresolver.resolve ("http://www.microsoft.com");
34:
35:int ncount = Mydnsresolver.count;
36:console.writeline ("Found {0} IP ' for hostname", ncount);
37:for (int i=0 i < ncount; i++)
38:console.writeline (Mydnsresolver[i]);
39:}
40:}

To resolve the host name, I used the DNS class, which is part of the system. Net namespace. However, since this namespace is not included in the core library, you must reference the library in the compilation Command line:
Csc/r:system.net.dll/out:resolver.exe Dnsresolve.cs
The parsing code is parsed forward. In the Resolve method, the code calls the static method gethostbyname of the DNS class, which returns a Iphostentry object. As a result, the object contains a--addresslist array of the array I am looking for. Before exiting the Resolve method, in the local object instance member M_arrips, a copy of the AddressList array is stored (the type IPAddress object is stored therein).
With an array that is now generated, the application code can give the IP address in the 37th to 38th row by using the index evaluated in the class Resolvedns. (In the 6th chapter, "Control statement", there is more information about the statement.) Because there is no way to change the IP address, only get access flags are used for the index. For the sake of simplicity, I ignored the bounds of the array overflow check.

5.4 Events
When you write a class, it is sometimes necessary to let the customers of the class know about some events that have occurred. If you are a programmer with years of programming experience, there seems to be a number of solutions, including function pointers for callbacks and event sinks for ActiveX controls. Now you're going to learn another way to relate customer code to class notifications--using events.
An event can be declared either as a class domain member (a member variable) or as a property. The generality of the two is that the type of the event must be the representative element, and the function pointer and the representative element of C # have the same meaning.
Each event can be consumed by 0 or more customers, and the customer can associate or cancel the event at any time. You can define representative elements in either static or instance methods, which are popular with C + + programmers.
Now that I have mentioned all the features of the event and the corresponding representative element, see the example in Listing 5.11. It vividly embodies the theory.

Listing 5.11 Implements event handling in a class
1:using System;
2:
3://Forward statement
4:public delegate void EventHandler (string strText);
5:
6:class EventSource
7: {
8:public event EventHandler TextOut;
9:
10:public void Triggerevent ()
11: {
12:if (null!= textout) textout ("Event triggered");
13:}
14:}
15:
16:class TestApp
17: {
18:public static void Main ()
19: {
20:eventsource evsrc = new EventSource ();
21st:
22:evsrc. TextOut + = new EventHandler (catchevent);
23:evsrc. Triggerevent ();
24:
25:evsrc. TextOut-= new EventHandler (catchevent);
26:evsrc. Triggerevent ();
27:
28:testapp Theapp = new TestApp ();
29:evsrc. TextOut + = new EventHandler (theapp.instancecatch);
30:evsrc. Triggerevent ();
31:}
32:
33:public static void Catchevent (String strText)
34: {
35:console.writeline (StrText);
36:}
37:
38:public void Instancecatch (String strText)
39: {
40:console.writeline ("Instance" + strText);
41:}
42:}

Line 4th declares the representative element (the event method prototype), which is used to declare TextOut event domain members to the EventSource class in line 8th. You can observe the representation of the meta as a new type declaration, which can be used when declaring an event.
The class has only one method, which allows us to trigger events. Note that you must perform detection of the event domain members that are not NULL because there may be situations where no customer is interested in the event.
The TestApp class contains the main method and two other methods that have the necessary signals for the event. One of the methods is static and the other is an instance method.
The EventSource is instantiated, and the static method Catchevent is preloaded with the TextOut event:
Evsrc. TextOut + = new EventHandler (catchevent);
From now on, the method is invoked when the event is triggered. If you are no longer interested in events, simply cancel the association:
Evsrc. TextOut-= new EventHandler (catchevent);
Note that you are not free to cancel the associated handler function--only those functions are created in the class code. To prove that event handlers work with instance methods, the rest of the code establishes an instance of TestApp and hooks up the event-handling method.
In what ways is the event particularly useful to you? You will often be in asp+ or used to WFC (Windows Foundation Classes) When it comes to events and Representative elements.

5.5 Application Modifiers
In this chapter of the learning process, you have seen like public, virtual and other modifiers. To generalize them in an easy-to-understand way, I divide them into sections:

。 Class modifiers
。 Member modifiers
。 Access modifiers

5.5.1 class modifier
So far, I have not covered the class modifiers, but only the access modifiers applied to the class. However, there are two modifiers you can use for classes:
abstract--the important point about an abstract class is that it cannot be instantiated. Only derived classes that are not abstract can be instantiated. A derived class must implement all abstract members of the abstract base class. You cannot use the sealed modifier for an abstract class.
sealed--sealed class cannot be inherited. Use this modifier to prevent accidental inheritance, which is used by classes in the. NET Framework.
To see the use of two modifiers, look at listing 5.12, which creates a sealed class based on an abstract class (definitely a very extreme example).

Listing 5.12 abstract classes and sealed classes

1:using System;
2:
3:abstract class AbstractClass
4: {
5:abstract public void MyMethod ();
6:}
7:
8:sealed class Derivedclass:abstractclass
9: {
10:public override void MyMethod ()
11: {
12:console.writeline ("sealed class");
13:}
14:}
15:
16:public class TestApp
17: {
18:public static void Main ()
19: {
20:derivedclass dc = new DerivedClass ();
21:DC. MyMethod ();
22:}
23:}

5.5.2 member Modifiers
The number of class modifiers is very small compared to the number of useful member modifiers. I have mentioned some of the upcoming examples of this book that describe other member modifiers.
The following are useful member modifiers:
abstract--indicates that a method or access flag cannot contain an implementation. They are all implicitly virtual, and in the inheritance class you must provide the override keyword.
const--This modifier applies to domain members or local variables. A compile-time expression is evaluated, so it cannot contain a reference to a variable.
event--defines a domain member or attribute as a type event. An event that is used to bundle client code into classes.
extern--tells the compiler that the method is actually implemented externally. The 10th chapter "Interoperability with non-regulated code" will involve the external code in a comprehensive manner.
override--is used to overwrite methods and access flags that are defined as virtual in any base class. The method to overwrite the name and base class must be consistent.
readonly--a domain member that uses the ReadOnly modifier can only be changed in its declaration or in the constructor of the class that contains it.

static--members declared as static belong to the class, not to instances of the class. You can use static to domain members, methods, properties, operators, and even constructors.
The virtual--description method or access flag can be overridden by an inherited class.

5.5.3 access modifier
The access modifier defines the level of access that some code has to class members, such as methods and properties. You must add the desired access modifier to each member, otherwise the default access type is implied.
You can apply one of the 4 access modifiers:
This member can be accessed anywhere in the public--, which is a least restrictive access modifier.
protected--can access the member in the class and all derived classes, and does not allow external access.
private--can access the member only within the same class. Even derived classes cannot access it.
internal--allows all code access to the same component (application or library). At the. NET component level, you can think of it as public and externally private.
To demonstrate the use of the access modifier, I have slightly modified the triangle example to include the new domain member and a newly derived class (see listing 5.13).

Listing 5.13 using the access modifier in the class

1:using System;
2:
3:internal class Triangle
4: {
5:protected int m_a, M_b, M_c;
6:public triangle (int A, int b, int c)
7: {
8:m_a = A;
9:m_b = b;
10:m_c = C;
11:}
12:
13:public Virtual double Area ()
14: {
://Heronian formula
16:double s = (m_a + m_b + m_c)/2.0;
17:double Darea = math.sqrt (s* (s-m_a) * (s-m_b) * (S-m_c));
18:return Darea;
19:}
20:}
21st:
22:internal class Prism:triangle
23: {
24:private int m_h;
25:public Prism (int A, int b, int c, int h): base (A,b,c)
26: {
27:m_h = h;
28:}
29:
30:public override double Area ()
31: {
32:double Darea = base. Area () * 2.0;
33:darea + + M_a*m_h + m_b*m_h + m_c*m_h;
34:return Darea;
35:}
36:}
37:
38:class Prismapp
39: {
40:public static void Main ()
41: {
42:prism Prism = new Prism (2,5,6,1);
43:console.writeline (Prism. Area ());
44:}
45:}
The Triangle class and the Prism class are now marked as internal. This means that they can only be accessed in the current assembly.
Please remember ". NET component "refers to the packaging (packaging,) rather than the components you might use in COM +.
The Triangle class has three protected members, which are initialized in the constructor and used in the method of area calculation. Because these members are protected members, I can access them in the derived class prism, where different area calculations are performed.
Prism has added a member of its own m_h, which is private-even derived classes cannot access it.
It is usually a good idea to spend some time planning a level of protection for each class member or even for each class. When you need to introduce changes, a comprehensive plan will eventually help you, because no programmer would be willing to use the "no Document" class feature.
5.6 Summary
This chapter shows the various elements of the class, which is the template for running the instance (object). In the lifetime of an object, the first code executed is a constructor. Constructors are used to initialize variables that are later used in methods to compute results.
method allows you to pass values, refer to variables, or send only one output value. Method can be rewritten to implement new functionality, or you can mask a base class member if it implements a method with the same name as a derived class member.
Named attributes can be implemented as domain members (member variables) or attribute access flags. The latter is get and set access flags, ignoring one or the other, and you can create write-only or read-only properties. The access flag is ideal for confirming the value assigned to a property.
Another feature of the C # class is the index, which makes it possible to access the values of the class as array syntax does. Also, if something happens in a class, you want the customer to be notified and have them associate with the event.
When the garbage collector calls the destructor, the object's life ends. Since you cannot accurately predict when this situation will occur, you should create a method to release these valuable resources when you stop using them.

Related Article

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.