楼主: bnso

Introduction to C# Programming

[复制链接]
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
131#
 楼主| 发表于 2006-8-13 21:43 | 只看该作者
Module 9: Creating and Destroying Objects 59
The answer is that reader.Close is not guaranteed to be called. The problem is
that if a statement before the call to Close throws an exception, the flow of
control will bypass the call to Close. One way you can solve this problem is by
using a finally block, as follows:
class SourceFile
{
public SourceFile(string name)
{
StreamReader reader = null;
try {
File src = new File(name);
contents = new char[(int)src.Length];
reader = src.OpenText( );
reader.ReadBlock(contents, 0, contents.Length);
}
finally {
if (reader != null) {
reader.Close( );
}
}
}
...
private char[ ] contents;
}
This solution works, but it is not completely satisfactory because:
n You must reorder the declaration of the resource reference.
n You must remember to initialize the reference to null.
n You must remember to ensure that the reference is not null in the finally
block.
n It quickly becomes unwieldy if there is more than one resource to dispose of.
Proposed Modifications to C#
A proposed amendment to C# provides a solution that avoids all of these
problems. It uses an extension of the using statement (part of the C# language)
with the IDisposable interface (part of the C# .NET Framework SDK) to
implement resource classes.
These new enhancements are not available in Beta 1 and therefore are not
covered in this course.
60 Module 9: Creating and Destroying Objects
Lab 9.2: Destroying Objects
Objectives
In this lab, you will learn how to use finalizers to perform processing before
garbage collection destroys an object.
After completing this lab, you will be able to:
n Create a destructor.
n Make requests of garbage collection.
n Use the Disposal design pattern.
Prerequisites
Before working on this lab, you must be able to:
n Create classes and instantiate objects.
n Define and call methods.
n Define and use constructors.
n Use the StreamWriter class to write text to a file.
You should also have completed Lab 9.1. If you did not complete Lab 9.1, you
can use the solution code provided.
Estimated time to complete this lab: 15 minutes
Module 9: Creating and Destroying Objects 61
Exercise 1
Creating a Destructor
In this exercise, you will create a finalizer for the BankTransaction class. The
finalizer will allow BankTransaction to persist its data to the end of the file
Transactions.dat in the current directory. The data will be written out in humanreadable
form.
? To save transactions
1. Open the Finalizers.sln project in the Lab Files\Lab09\Starter\Finalizers
folder.
2. Add the following using directive to the start of the BankTransaction.cs file:
using System.IO;
3. In the BankTransaction class, add a destructor, as follows:
a. It should be called ~BankTransaction.
b. It should not have an access modifier.
c. It should not take any parameters.
d. It should not return a value.
4. In the body of the destructor, add statements to:
a. Create a new StreamWriter variable that opens the Transactions.dat file
in the current directory in append mode (that is, it writes data to the end
of the file if it already exists.) You can achieve this by using the
File.AppendText method. For information about this method, search for
“File.AppendText” in the .NET Framework SDK Help documents.
b. Write the contents of the transaction to this file. (Format so that it is
readable.)
c. Close the file:
~BankTransaction( )
{
StreamWriter swFile =
êFile.AppendText("Transactions.Dat";
swFile.WriteLine(“Date/Time: {0}\tAmount {1}”, when,
êamount);
swFile.Close( );
}
5. Compile your program and correct any errors.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
132#
 楼主| 发表于 2006-8-13 21:43 | 只看该作者
62 Module 9: Creating and Destroying Objects
? To test the destructor
1. Review the CreateAccount.cs test harness. The test harness:
a. Creates an account (acc1).
b. Deposits money to and withdraws money from acc1.
c. Prints the contents of acc1 and its transactions.
When the Main method finishes, what will happen to the account acc1 and
the transactions?
2. Compile and execute the program. Verify that the information displayed is
as expected. Is the Transactions.dat file created as expected? (It should be in
the bin \debug folder in the project folder.) If not, why not?
You will find that the Transactions.dat file is not created because garbage
collection never needs to collect garbage in such a small program, so the
destructor is never executed. For a bank, this is not a good situation because the
bank is probably not allowed to lose records of transactions. You will fix this
problem in Exer cise 2 by using the Disposal pattern.
Note
Module 9: Creating and Destroying Objects 63
Exercise 2
Using the Disposal Design Pattern
In this exercise, you will use the Disposal design pattern to ensure that a
BankTransaction’s data is saved on demand rather than when garbage
collection destroys the BankTransaction. You will also need to inform
garbage collection that the BankTransaction has already been disposed of and
suppress any attempt by garbage collection to destroy it again later.
You will add a Dispose method to the BankAccount and BankTransaction
classes. The Dispose method in BankAccount will iterate through all of the
transactions in its transaction queue, and call Dispose for each transaction.
? To make BankTransaction suitable for finalizing
1. In the BankTransaction class, add a public void method called Dispose
that only calls Finalize:
public void Dispose( )
{
Finalize( );
}
2. Add to the end of the destructor a call to GC.SuppressFinalize(this).
Calling Finalize will invoke the destructor. You need to ensure that garbage
collection does not call the destructor again after you have used it.
64 Module 9: Creating and Destroying Objects
? To create a Dispose method for the BankAccount class
1. In the BankAccount class, add a using System directive.
2. Add a private bool instance variable called dead. Initialize it to false.
3. Add a public method called Dispose. It should take no parameters and have
a void return type.
4. In the Dispose method, add statements to:
a. Examine the value of dead. If it is true , return from the method and do
nothing else.
b. If dead is false, iterate through all of the BankTransaction objects in
tranQueue and call Dispose for each one. Use a foreach statement, as
you did in Lab 9.1.
c. Call GC.SuppressFinalize(this) to prevent garbage collection from
destroying the account again.
d. Set dead to true .
The completed code should be as follows:
public void Dispose( )
{
if (dead) return;
foreach(BankTransaction tran in tranQueue)
{
tran.Dispose( );
}
GC.SuppressFinalize(this);
dead = true;
}
5. Compile the project and correct any errors.
? To test the destructor
1. Open the CreateAccount.cs test harness.
2. Add a statement to the end of Main that calls the Dispose method of acc1,
to ensure that it is saved correctly, as follows:
acc1.Dispose( );
3. Compile the project and correct any errors.
4. Run the program. The same output as before should be displayed on the
screen. However, this time the Transactions.dat file should also be created.

Module 9: Creating and Destroying Objects 65
Review
n Using Constructors
n Initializing Data
n Objects and Memory
n Using Destructors
1. Declare a class called Date with a public constructor that expects three int
parameters called year, month, and day.
2. Will the compiler generate a default constructor for the Date class that you
declared in question 1? What if Date were a struct with the same three-int
constructor?
66 Module 9: Creating and Destroying Objects
3. Which method does garbage collection call on the object just before it
recycles the object’s memory back to the heap? Declare a class called
SourceFile that contains this method.
4. What is wrong with the following code fragment?
class Example
{
~Example( ) { }
protected void override Finalize( ) { }
}

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
133#
 楼主| 发表于 2006-8-13 21:44 | 只看该作者
Module 10: Inheritance in C# 1
Overview
n Deriving Classes
n Implementing Methods
n Using Sealed Classes
n Using Interfaces
n Using Abstract Classes
Inheritance, in an object-oriented system, is the ability of an object to inherit
data and functionality from its parent object. Therefore, a child object can
substitute for the parent object. Also, by using inheritance, you can create new
classes from existing classes instead of starting at the beginning and creating
them new. You can then write new code to add the features required in the new
class. The parent class on which the new class is based is know n as a base class,
and the child class is known as a derived class.
When you create a derived class, it is important to remember that a derived
class can substitute for the base class type. Therefore, inheritance is a typeclassification
mechanism in addit ion to a code-reuse mechanism, and the
former is more important than the latter.
In this module, you will learn how to derive a class from a base class. You will
also learn how to implement methods in a derived class by defining them as
virtual methods in the base class and overriding or hiding them in the derived
class, as required. You will learn how to seal a class so that it cannot be derived
from. You will also learn how to implement interfaces and abstract classes,
which define the terms of a contract to which derived classes must adhere.
After completing this module, you will be able to:
n Derive a new class from a base class, and call members and constructors of
the base class from the derived class.
n Declare methods as virtual and override or hide them as required.
n Seal a class so that it cannot be derived from.
n Implement interfaces by using both the implicit as well as the explicit
methods.
n Describe the use of abstract classes and their implementation of interfaces.
2 Module 10: Inheritance in C#
u Deriving Classes
n Extending Base Classes
n Accessing Base Class Members
n Calling Base Class Constructors
You can only derive a class from a base class if the base class was designed to
enable inheritance. This is because objects must have the proper structure or
inheritance cannot work effectively. A base class that is designed for
inheritance should make this fact clear. If a new class is derived from a base
class that is not designed appropriately, then the base class might change at
some later time, and this would make the derived class inoperable.
In this section, you will learn how to derive a class from a base class, and how
to access the members and constructors of the base class from the derived class.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
134#
 楼主| 发表于 2006-8-13 21:44 | 只看该作者
Module 10: Inheritance in C# 3
Extending Base Classes
n Syntax for Deriving a Class from a Base Class
n A Derived Class Inherits Most Elements of Its Base Class
n A Derived Class Cannot Be More Accessible Than Its
Base Class
class Token
{
...
}
class CommentToken: Token
{
...
}
class Token
{
...
}
class CommentToken: Token
{
...
}
CommentToken
? concrete ?
CommentToken
? concrete ?
Token
? concrete ?
Token
DDDeeerririviveedd cc cllalassss BBBaaassee c cllaasssss ? concrete ?
CCCooolloloonnn
Deriving a class from a base class is also known as extending the base class. A
C# class can extend at most one class.
Syntax for Deriving a Class
To specify that one class is derived from another, you use the following syntax:
class Derived: Base
{
...
}
The elements of this syntax are labeled on the slide. When you declare a
derived class, the base class is specified after a colon. The white space around
the colon is not significant. The recommended style for using this syntax is to
include no spaces before the colon and a single space after it.
Derived Class Inheritance
A derived class inherits everything from its base class except for the base class
constructors and destructors. It usually adds its own members to those that it
inherits from its base class. Public members of the base class are implicitly
public members of the derived class. Private members of the base class, though
inherited by the derived class, are accessible only to the members of the base
class.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
135#
 楼主| 发表于 2006-8-13 21:45 | 只看该作者
Module 10: Inheritance
in C#
This course is based on the prerelease Beta 1 version of Microsoft? Visual Studio .NET.
Content in the final release of the course may be different from the content included in this
prerelease version. All labs in the course are to be completed with the Beta 1 version of
Visual Studio .NET.
Information in this document is subject to change without notice. The names of companies,
products, people, characters, and/or data mentioned herein are fictitious and are in no way intended
to represent any real individual, company, product, or event, unless otherwise noted. Complying
with all applicable copyright laws is the responsibility of the user. No part of this document may
be reproduced or transmitted in any form or by any means, electronic or mechanical, for any
purpose, without the express written permission of Microsoft Corporation. If, however, your only
means of access is electronic, permission to print one copy is hereby granted.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
ó 2001 Microsoft Corporation. All rights reserved.
Microsoft, ActiveX, BizTalk, IntelliSense, JScript, Microsoft Press, MSDN, PowerPoint, Visual
Basic, Visual C++, Visual #, Visual Studio, Windows, and Windows Media are either registered
trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other countries.
Other product and company names mentioned herein may be the trademarks of their respective
owners.
4 Module 10: Inheritance in C#
Accessibility of a Derived Class
A derived class cannot be more accessible than its base class. For example, it is
not possible to derive a public class from a private class, as is shown in the
following code:
class Example
{
private class NestedBase { }
public class NestedDerived: NestedBase { } // Error
}
The C# syntax for deriving one class from another is also allowed in C++,
where it implicitly specifies a private inheritance relationship between the
derived and base classes. C# has no private inheritance; all inheritance is public.
Module 10: Inheritance in C# 5
Accessing Base Class Members
n Inherited Protected Members Are Implicitly Protected in the Derived
Class
n Methods of a Derived Class Can Access Only Their Inherited Protected
Members
n Protected Access Modifiers Cannot Be Used in a Struct
class Token
{ ... class Outside
protected string name; {
} void Fails(Token t)
class CommentToken: Token {
{ ... ...
public string Name( ) t.name
{ ...
return name; }
} }
}
class Token
{ ... class Outside
protected string name; {
} void Fails(Token t)
class CommentToken: Token {
{ ... ...
public string Name( ) t.name
{ ...
return name; }
} }
}
?
ü
The meaning of the protected access modifier depends on the relationship
between the class that has the modifier and the class that seeks to access the
members that use the modifier.
Members of a derived class can access all of the protected members of their
base class. To a derived class, the protected keyword behaves like the public
keyword. Hence, in the code fragment shown on the slide, the Name method of
CommentToken can access the string name, w hich is protected inside Token.
It is protected inside Token because CommentToken has specified Token as
its base class.
However, between two classes that are not related by a derived-class and baseclass
relationship, protected members of one class act like private members for
the other class. Hence, in the other code fragment shown on the slide, the Fails
method of Outside cannot access the string name, which is protected inside
Token because Outside does not specify Token as its base class.
6 Module 10: Inheritance in C#
Inherited Protected Members
When a derived class inherits a protected member, that member is also
implicitly a protected member of the derived class. This means that protected
members are accessible to all directly and indirectly derived classes of the base
class. This is shown in the following example:
class Base
{
protected string name;
}
class Derived: Base
{
}
class FurtherDerived: Derived
{
void Compiles( )
{
Console.WriteLine(name); // Okay
}
}
Protected Members and Methods
Methods of a derived class can only access their own inherited protected
members. They cannot access the protected members of the base class through
references to the base class. For example, the following code will generate an
error:
class CommentToken: Token
{
void AlsoFails(Token t)
{
Console.WriteLine(t.name); // Compile-time error
}
}
Many coding guidelines recommend keeping all data private and using
protected access only for methods.
Protected Members and structs
A struct does not support inheritance. Consequently, you cannot derive from a
struct, and, therefore, the protected access modifier cannot be used in a struct.
For example, the following code will generate an error:
struct Base
{
protected string name; // Compile-time error
}
Tip

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
136#
 楼主| 发表于 2006-8-13 21:45 | 只看该作者
Module 10: Inheritance in C# 7
Calling Base Class Constructors
n Constructor Declarations Must Use the base Keyword
n A Private Base Class Constructor Cannot Be Accessed by a
Derived Class
n Use the base Keyword to Qualify Identifier Scope
class Token
{
protected Token(string name) { ... }
...
}
class CommentToken: Token
{
public CommentToken(string name) : base(name) { }
...
}
class Token
{
protected Token(string name) { ... }
...
}
class CommentToken: Token
{
public CommentToken(string name) : base(name) { }
...
}
To call a base class constructor from the derived class constructor, use the
keyword base. The syntax for this keyword is as follows:
C(...): base( ) {...}
The colon and the accompanying base class constructor call are together known
as the constructor initializer.
Constructor Declarations
If the derived class does not explicitly call a base class constructor, the C#
compiler will implicitly use a constructor initializer of the form :base( ).
This implies that a constructor declaration of the form
C(...) {...}
is equivalent to
C(...): base( ) {...}
Often this implicit behavior is perfectly adequate because:
n A class with no explicit base classes implicitly extends the System.Object
class, which contains a public parameterless constructor.
n If a class does not contain a constructor, the compiler will automatically
provide a public parameterless constructor called the default constructor.
8 Module 10: Inheritance in C#
If a class provides an explicit constructor of its own, the compiler will not
create a default constructor. However, if the specified constructor does not
match any constructor in the base class, the compiler will generate an error as
shown in the following code:
class Token
{
protected Token(string name) { ... }
}
class CommentToken: Token
{
public CommentToken(string name) { ... } // Error here
}
The error occurs because the CommentToken constructor implicitly contains
a :base( ) constructor initializer, but the base class Token does not contain a
parameterless constructor. You can fix this error by using the code shown on
the slide.
Constructor Access Rules
The access rules for a derived constructor to call a base class constructor are
exactly the same as those for regular methods. For example, if the base class
constructor is private, then the derived class cannot access it:
class NonDerivable
{
private NonDerivable( ) { ... }
}
class Impossible: NonDerivable
{
public Impossible( ) { ... } // Compile-time error
}
In this case, there is no way for a derived class to call the base class constructor.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
137#
 楼主| 发表于 2006-8-13 21:46 | 只看该作者
Module 10: Inheritance in C# 9
Scoping an Identifier
You can use the keyword base to also qualify the scope of an identifier. This
can be useful, since a derived class is permitted to declare members that have
the same names as base class members. The following code provides an
example:
class Token
{
protected string name;
}
class CommentToken: Token
{
public void Method(string name)
{
base.name = name;
}
}
Unlike in C++, the name of the base class, such as Token in the example
in the slide, is not used. The keyword base unambiguously refers to the base
class because in C# a class can extend one base class at most.
Note
10 Module 10: Inheritance in C#
u Implementing Methods
n Defining Virtual Methods
n Working with Virtual Methods
n Overriding Methods
n Working with Override Methods
n Using new to Hide Methods
n Working with the new Keyword
n Practice: Implementing Methods
n Quiz: Spot the Bugs
You can redefine the methods of a base class in a derived class when the
methods of the base class have been designed for overriding. In this section,
you will learn how to use the virtual, override , and hide method types to
implement this functionality.
Module 10: Inheritance in C# 11
Defining Virtual Methods
n Syntax: Declare as Virtual
n Virtual Methods Are Polymorphic
class Token
{
...
public int LineNumber( )
{ ...
}
public virtual string Name( )
{ ...
}
}
class Token
{
...
public int LineNumber( )
{ ...
}
public virtual string Name( )
{ ...
}
}
A virtual method specifies an implementation of a method that can be
polymorphically overridden in a derived class. Conversely, a non-virtual
method specifies the only implementation of a method. You cannot
polymorphically override a non-virtual method in a derived class.
In C#, whether a class contains a virtual method or not is a good
indication of whether the author designed it to be used as a base class.
Keyword Syntax
To declare a virtual method, you use the virtual keyword. The syntax for this
keyword is shown on the slide.
When you declare a virtual method, it must contain a method body. If it does
not contain a body, the compiler will generate an error, as shown:
class Token
{
public virtual string Name( ); // Compile-time error
}
Note
12 Module 10: Inheritance in C#
Working with Virtual Methods
n To Use Virtual Methods:
l You cannot declare virtual methods as static
l You cannot declare virtual methods as private
To use virtual methods effectively, you need to understand the following:
n You cannot declare virtual methods as static.
You cannot qualify virtual methods as static because static methods are
class methods and polymorphism works on objects, not on classes.
n You cannot declare virtual methods as private.
You cannot declare virtual methods as private because they cannot be
polymorphically overridden in a derived class. Following is an example:
class Token
{
private virtual string Name( ) { ... }
// Compile-time error
}
Module 10: Inheritance in C# 13
Overriding Methods
n Syntax: Use the override Keyword
class Token
{ ...
public virtual string Name( ) { ... }
}
class CommentToken: Token
{ ...
public override string Name( ) { ... }
}
class Token
{ ...
public virtual string Name( ) { ... }
}
class CommentToken: Token
{ ...
public override string Name( ) { ... }
}
An override method specifies another implementation of a virtual method. You
define virtual methods in a base class, and they can be polymorphically
overridden in a derived class.
Keyword Syntax
You declare an override method by using the keyword override , as shown in
the following code:
class Token
{ ...
public virtual string Name( ) { ... }
}
class CommentToken: Token
{ ...
public override string Name( ) { ... }
}
As with a virtual method, you must include a method body in an override
method or the compiler generates an error. Following is an example:
class Token
{
public virtual string Name( ) { ... }
}
class CommentToken: Token
{
public override string Name( ); // Compile-time error
}

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
138#
 楼主| 发表于 2006-8-13 21:46 | 只看该作者
14 Module 10: Inheritance in C#
Working with Override Methods
n You Can Only Override Identical Inherited Virtual Methods
n You Must Match an Override Method with Its Associated Virtual
Method
n You Can Override an Override Method
n You Cannot Explicitly Declare an Override Method As Virtual
n You Cannot Declare an Override Method As Static or Private
class Token
{ ...
public int LineNumber( ) { ... }
public virtual string Name( ) { ... }
}
class CommentToken: Token
{ ...
public override int LineNumber( ) { ... }
public override string Name( ) { ... }
}
class Token
{ ...
public int LineNumber( ) { ... }
public virtual string Name( ) { ... }
}
class CommentToken: Token
{ ...
public override int LineNumber( ) { ... }
public override string Name( ) { ... }
}

To use override methods effectively, you must understand a few important
restrictions:
n You can only override identical inherited virtual methods.
n You must match an override method with its associated virtual method.
n You can override an override method.
n You cannot implicitly declare an override method as virtual.
n You cannot declare an override method as static or private.
Each of these restrictions is described in more detail as in the following topics.
You Can Only Override Identical Inherited Virtual
Methods
You can use an override method to override only an identical inherited virtual
method. In the code on the slide, the LineNumber method in the derived class
CommentToken causes a compile-time error because the inherited method
Token.LineNumber is not marked virtual.
You Must Match an Override Method with Its Associated
Virtual Method
An override declaration must be identical in every way to the virtual method it
overrides. They must have the same access level, the same return type, the same
name, and the same parameters.
Module 10: Inheritance in C# 15
For example, the override in the following example fails because the accesslevels
are different (protected as opposed to public), the return types are
different (string as opposed to void), and the parameters are different (none as
opposed to int):
class Token
{
protected virtual string Name( ) { ... }
}
class CommentToken: Token
{
public override void Name(int i) { ... } // Errors
}
You Can Override an Override Method
An override method is implicitly virtual, so you can override it. Following is an
example:
class Token
{
public virtual string Name( ) { ... }
}
class CommentToken: Token
{
public override string Name( ) { ... }
}
class OneLineCommentToken: CommentToken
{
public override string Name( ) { ... } // Okay
}
You Cannot Explicitly Declare an Override Method As
Virtual
An override method is implicitly virtual but cannot be explicitly qualified as
virtual. Following is an example:
class Token
{
public virtual string Name( ) { ... }
}
class CommentToken: Token
{
public virtual override string Name( ) { ... } // Error
}
You Cannot Declare an Override Method As Static or
Private
An override method can never be qualified as static because static methods are
class methods and polymorphism works on objects rather than classes.
Also, an override method can never be private. This is because an override
method must override a virtual method, and a virtual method cannot be private.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
139#
 楼主| 发表于 2006-8-13 21:46 | 只看该作者
16 Module 10: Inheritance in C#
Using new to Hide Methods
n Syntax: Use the new Keyword to Hide a Method
class Token
{ ...
public int LineNumber( ) { ... }
}
class CommentToken: Token
{ ...
new public int LineNumber( ) { ... }
}
class Token
{ ...
public int LineNumber( ) { ... }
}
class CommentToken: Token
{ ...
new public int LineNumber( ) { ... }
}
You can hide an identical inherited method by introducing a new method into
the class hierarchy. The old method that was inherited by the derived class from
the base class is then replaced by a completely different method.
Keyword Syntax
You use the new keyword to hide a method. The syntax for this keyword is as
follows:
class Token
{ ...
public int LineNumber( ) { ... }
}
class CommentToken: Token
{ ...
new public int LineNumber( ) { ... }
}
Module 10: Inheritance in C# 17
Working with the new Keyword
n Hide Both Virtual and Non-Virtual Methods
n Resolve Name Clashes in Code
n Hide Methods That Have Identical Signatures
class Token
{ ...
public int LineNumber( ) { ... }
public virtual string Name( ) { ... }
}
class CommentToken: Token
{ ...
new public int LineNumber( ) { ... }
public override string Name( ) { ... }
}
class Token
{ ...
public int LineNumber( ) { ... }
public virtual string Name( ) { ... }
}
class CommentToken: Token
{ ...
new public int LineNumber( ) { ... }
public override string Name( ) { ... }
}
By using the new keyword, you can do the following:
n Hide both virtual and non-virtual methods.
n Resolve name clashes in code.
n Hide methods that have identical signatures.
Each of these tasks is described in detail in the following subtopics.
Hide Both Virtual and Non-Virtual Methods
Using the new keyword to hide a method has implications if you use
polymorphism. For example, in the code on the slide,
CommentToken.LineNumber is a new method. It is not related to the
Token.LineNumber method at all. Even if Token.LineNumber was a virtual
method, CommentToken.LineNumber would still be a new unrelated method.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
140#
 楼主| 发表于 2006-8-13 21:46 | 只看该作者
18 Module 10: Inheritance in C#
In this example, CommentToken.LineNumber is not virtual. This means that
a further derived class cannot override CommentToken.LineNumber.
However, the new CommentLineToken.LineNumber method could be
declared virtual, in which case further derived classes could override it, as
follows:
class CommentToken: Token
{
...
new public virtual int LineNumber( ) { ... }
}
class OneLineCommentToken: CommentToken
{
public override int LineNumber( ) { ... }
}
The recommended layout style for new virtual methods is
new public virtual int LineNumber( ) { ... }
rather than
public new virtual int LineNumber( ) { ... }
Resolve Name Clashes in Code
Name clashes often generate warnings during compilation. For example,
consider the following code:
class Token
{
public virtual int LineNumber( ) { ... }
}
class CommentToken: Token
{
public int LineNumber( ) { ... }
}
When you compile this code, you will receive a warning stating that
CommentToken.LineNumber hides Token.LineNumber. This warning
highlights the name clash. You then have three options to choose from:
1. Add an override qualifier to CommentToken.LineNumber.
2. Add a new qualifier to CommentToken.LineNumber. In this case, the
method still hides the identical method in the base class, but the explicit
new tells the compiler and the code maintenance personnel that the name
clash is not accidental.
3. Change the name of the method.
Tip
Module 10: Inheritance in C# 19
Hide Methods That Have Identical Signatures
The new modifier is necessary only when a derived class method hides a visible
base class method that has an identical signature. In the following example, the
compiler warns that new is unnecessary bec ause the methods take different
parameters and so do not have identical signatures:
class Token
{
public int LineNumber(short s) { ... }
}
class CommentToken: Token
{
new public int LineNumber(int i ) { ... } // Warning
}
Conversely, if two methods have identical signatures, then the compiler will
warn that new should be considered because the base class method is hidden. In
the following example, the two methods have identical signatures because
return types are not a part of a method’s signature:
class Token
{
public virtual int LineNumber( ) { ... }
}
class CommentToken: Token
{
public void LineNumber( ) { ... } // Warning
}
You can also use the new keyword to hide fields and nested classes.
Note

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表