楼主: 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
71#
 楼主| 发表于 2006-8-13 21:24 | 只看该作者
8 Module 7: Essentials of Object-Oriented Programming
Abstraction
n Abstraction Is Selective Ignorance
l Decide what is important and what is not
l Focus and depend on what is important
l Ignore and do not depend on what is unimportant
l Use encapsulation to enforce an abstraction
The purpose of abstraction is not to be vague, but to create a
new semantic level in which one can be absolutely precise.
Edsger Dijkstra
The purpose of abstraction is not to be vague, but to create a
new semantic level in which one can be absolutely precise.
Edsger Dijkstra
Abstraction is the tactic of stripping an idea or object of its unnecessary
accompaniments until you are left with its essential, minimal form. A good
abstraction clears away unimportant details and allows you to focus and
concentrate on the important details.
Abstraction is an important software principle. A well-designed class exposes a
minimal set of carefully considered methods that provide the essential behavior
of the class in an easy-to-use manner. Unfortunately, creating good software
abstractions is not easy. Finding good abstractions usually requires a deep
understanding of the problem and its context, great clarity of thought, and
plenty of experience.
Minimal Dependency
The best software abstractions make complex things simple. They do this by
ruthlessly hiding away unessential aspects of a class. These unessential aspects,
once truly hidden away, cannot then be seen, used, or depended upon in any
way.
It is this principle of minimal dependency that makes abstraction so important.
One of the few things guaranteed in software development is that the code will
need to be changed. Perfect understanding only comes at the end of the
development process, if it comes at all; early decisions will be made with an
incomplete understanding of the problem and will need to be revisited.
Specifications will also change when a clearer understanding of the problem is
reached. Future versions will require extra functionality. Change is normal in
software development. The best you can do is to minimize the impact of change
when it happens. And the less you depend on something, the less you are
affected when it changes.
Module 7: Essentials of Object-Oriented Programming 9
Related Quotes
To illustrate the principle of minimal dependency that makes abstraction so
important, here are some related quotes:
The more perfect a machine becomes, the more they are invisible behind their
function. It seems that perfection is achieved not when there is nothing more to
add, but when there is nothing more to take away. At the climax of its evolution,
the machine conceals itself entirely.
— Antoine de Saint-Exupéry, Wind, Sand and Stars
The minimum could be defined as the perfection that an artifact achieves when
it is no longer possible to improve it by subtraction. This is the quality that an
object has when every component, every detail, and every junction has been
reduced or condensed to the essentials. It is the result of the omission of the
inessentials.
—John Pawson, Minimum
The main aim of communication is clarity and simplicity. Simplicity means
focused effort.
— Edward de Bono, Simplicity
10 Module 7: Essentials of Object-Oriented Programming
u Using Encapsulation
n Combining Data and Methods
n Controlling Access Visibility
n Why Encapsulate?
n Object Data
n Using Static Data
n Using Static Methods
In this section, you will learn how to combine data and methods in a single
capsule. You will learn how to use encapsulation within a class, and you will
also learn how to use static data methods in a class.
Module 7: Essentials of Object-Oriented Programming 11
Combining Data and Methods
n Combine the Data and Methods in a Single Capsule
n The Capsule Boundary Forms an Inside and an Outside
Withdraw( )
Deposit( )
balance
Withdraw( )
Deposit( )
balance
BankAccount ? BankAccount ?
There are two important aspects to encapsulation:
n Combining data and functions in a single entity (covered in the slide)
n Controlling the accessibility of the entity members (covered in the next slide)
Procedural Programming
Traditional procedural programs written in languages such as C essentially
contain a lot of data and many functions. Every function can access every piece
of data. For a small program this highly coupled approach can work, but as the
program grows larger it becomes less feasible. Changing the data representation
causes havoc. All functions that use (and hence depend upon) the changed data
fail. As the program becomes larger, making any change becomes more
difficult. The program becomes more brittle and less stable. The separate datafunction
approach does not scale. It does not facilitate change, and as all
software developers know, change is the only constant.
There is another serious problem with keeping the data separated from the
functions. This technique does not correspond to the way people naturally think,
in terms of high-level behavioral abstractions. Because people (the ones who
are programmers) write programs, it is much better to use a programming
model that approximates the way people think rather than the way computers
are currently built.

使用道具 举报

回复
论坛徽章:
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
72#
 楼主| 发表于 2006-8-13 21:25 | 只看该作者
12 Module 7: Essentials of Object-Oriented Programming
Object-Oriented Programming
Object-oriented programming arose to alleviate these problems. Object-oriented
programming, if understood and used wisely, is really person-oriented
programming because people naturally think and work in terms of the highlevel
behavior of objects.
The first and most important step away from procedural programming and
towards object-oriented programming is to combine the data and the functions
into a single entity.
Module 7: Essentials of Object-Oriented Programming 13
Controlling Access Visibility
n Methods Are Public, Accessible from the Outside
n Data Is Private, Accessible Only from the Inside
Withdraw( )
Deposit( )
balance
BankAccount ?
Withdraw( )
Deposit( )
balance
BankAccount
?
In the graphic on the left, Withdraw, Deposit, and balance have been grouped
together inside a “capsule.” The slide suggests that the name of the capsule is
BankAccount. However, there is something wrong with this model of a bank
account: the balance data is accessible. (Imagine if real bank account balances
were directly accessible like this; you could increase your balance without
making any deposits!) This is not how bank accounts work: the problem and its
model have poor correspondence.
You can solve this problem by using encapsulation. Once data and functions are
combined into a single entity, the entit y itself forms a closed boundary,
naturally creating an inside and an outside. You can use this boundary to
selectively control the accessibility of the entities: some will be accessible only
from the inside; others will be accessible from both the inside and the outside.
Those members that are always accessible are public, and those that are only
accessible from the inside are private. It is not possible to have members that
are only accessible from the outside.
To make the model of a bank account closer to a real bank account, you can
make the Withdraw and Deposit methods public, and the balance private.
Now the only way to increase the account balance from the outside is to deposit
some money into the account. Note that Deposit can access the balance
because Deposit is on the inside.
14 Module 7: Essentials of Object-Oriented Programming
C#, like many other object-oriented programming languages, gives you
complete freedom when choosing whether to make members accessible. You
can, if you want, create public data. However, it is recommended that data
always be marked private. (Some programming languages enforce this
guideline.)
Types whose data representation is completely private are called abstract data
types (ADTs). They are abstract in the sense that you cannot access (and rely on)
the private data representation; you can only use the behavioral methods.
The built- in types such as int are, in their own way, ADTs. When you want to
add two integer variables together, you do not need to know the internal binary
representation of each integer value; you only need to know the name of the
method that performs addition: the addition operator (+).
When you make members accessible (public), you can create different views of
the same entity. The view from the outside is a subset of the view from the
inside. A restricted view relates closely to the idea of abstraction: stripping an
idea down to its essence.
A lot of design is related to the decision of whether to place a feature on the
inside or on the outside. The more features you can place on the inside (and still
retain usability) the better.
Module 7: Essentials of Object-Oriented Programming 15
Why Encapsulate?
n It Allows Control
l Use of the object
is solely through the
public methods
n It Allows Change
l Use of the object
is unaffected if the
private data type
changes
Withdraw( )
Deposit( )
dollars 12
Withdraw( )
Deposit( )
balance 12.56
cents 56
?
Two reasons to encapsulate are:
n To control use.
n To minimize the impact of change.
Encapsulation Allows Control
The first reason to encapsulate is to control use. When you drive a car, you
think only about the act of driving, not about the internals of the car. When you
withdraw money from an account, you do not think about how the account is
represented. You can use encapsulation and behavioral methods to design
software objects so that they can only be used in the way you intend.
Encapsulation Allows Change
The second reason to encapsulate follows from the first. If an object’s
implementation detail is private, it can be changed and the changes will not
directly affect users of the object (who can only access the public methods). In
practice, this can be tremendously useful. The names of the methods typically
stabilize well before the implementation of the methods.
The ability to make internal changes links closely to abstraction. Given two
designs for a class, as a rule of thumb, use the one with fewer public methods.
In other words, if you have a choice about whether to make a method public or
private, make it private. A private method can be freely changed and perhaps
later promoted into a public method. But a public method cannot be demoted
into a private method without destroying client code.

使用道具 举报

回复
论坛徽章:
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
73#
 楼主| 发表于 2006-8-13 21:25 | 只看该作者
16 Module 7: Essentials of Object-Oriented Programming
Object Data
n Object Data Describes Information for Individual
Objects
l For example, each bank account has its own balance. If
two accounts have the same balance, it is only a
coincidence.
Withdraw( )
Deposit( )
balance 12.56
owner "Bert"
Withdraw( )
Deposit( )
balance 12.56
owner "Fred"
Most items of data inside an object describe information about that individual
object. For example, each bank account has its own balance. It is, of course,
perfectly possible for many bank accounts to have the same balance. However,
this would only be a coincidence.
The data inside an object is held privately, and is accessible only to the object
methods. This encapsulation and separation means that an object is effectively
self-contained.
Module 7: Essentials of Object-Oriented Programming 17
Using Static Data
n Static Data Describes Information for All Objects of a
Class
l For example, suppose all accounts share the same
interest rate. Storing the interest rate in every account
would be a bad idea. Why?
Withdraw( )
Deposit( )
balance 12.56
interest 7%
Withdraw( )
Deposit( )
balance 99.12
interest 7% ? ?
Sometimes it does not make sense to store information inside every object. For
example, if all bank accounts always share the same interest rate, then storing
the rate inside every account object would be a bad idea for the following
reasons:
n It is a poor implementation of the problem as described: “All bank accounts
share the same interest rate.”
n It needlessly increases the size of each object, using extra memory resources
when the program is running and extra disk spac e when it is saved to disk.
n It makes it difficult to change the interest rate. You would need to change
the interest rate in every account object. If you needed to make the interest
rate change in each individual object, an interest rate change might make all
accounts inaccessible while the change took place.
n It increases the size of the class. The private interest rate data would require
public methods. The account class is starting to lose its cohesiveness. It is
no longer doing one thing and one thing well.
18 Module 7: Essentials of Object-Oriented Programming
To solve this problem, do not share information that is common between
objects at the object level. Instead of describing the interest rate many times at
the object level, describe the interest rate once at the class level. When you
define the interest rate at the class level, it effectively becomes global data.
However, global data, by definition, is not stored inside a class, and therefore
cannot be encapsulated. Because of this, many object-oriented programming
languages (including C#) do not allow global data. Instead, they allow data to
be described as static.
Declaring Static Data
Static data is physically declared inside a class (which is a static, compile -time
entity) and benefits from the encapsulation the class affords, but it is logically
associated with the class itself and not with each object. In other words, static
data is declared inside a class as a syntactic convenience and exists even if the
program never creates any objects of that class.
Module 7: Essentials of Object-Oriented Programming 19
Using Static Methods
n Static Methods Can Only Access Static Data
l A static method is called on the class, not the object
InterestRate( )
interest 7%
Withdraw( )
Deposit( )
balance 99.12
owner "Fred"
An account object
The account class
Classes contain static data and
static methods
Objects contain object data and
object methods
?
?
ü
You use static methods to encapsulate static data. In the example in the slide,
the interest rate belongs to the account class and not to an individual account
object. It therefore makes sense to provide methods at the class level that can be
used to access or modify the interest rate.
You can declare methods as static in the same way that you would declare data
as static. Static methods exist at the class level. You can control accessibility
for both static methods and static data can by using access modifiers such as
public and private. By choosing public static methods and private static data,
you can encapsulate static data in the same way that you can encapsulate object
data.
A static method exists at the class level and is called against the class and not
against an object. This means that a static method cannot use this, the operator
that implicitly refers to the object making an object method call. In other words,
a static method cannot access non-static data or non-static methods. The only
members of a class that a static method can access are static data and other
static methods.
20 Module 7: Essentials of Object-Oriented Programming
Static methods retain access to all private members of a class and can access
private non-static data by means of an object reference. The following code
provides an example:
class Time
{
...
public static void Reset(Time t)
{
t.hours = 0; // Okay
t.minutes = 0; // Okay
hour = 0; // compile-time error
minute = 0 // compile-time error
}
private int hour, minute;
}

使用道具 举报

回复
论坛徽章:
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
74#
 楼主| 发表于 2006-8-13 21:25 | 只看该作者
Module 7: Essentials of Object-Oriented Programming 21
u C# and Object Orientation
n Hello, World Revisited
n Defining Simple Classes
n Instantiating New Objects
n Using the this Operator
n Creating Nested Classes
n Accessing Nested Classes
In this section, you will re-examine the original Hello, World program.
The structure of the program will be explained from an object-oriented
perspective. You will then learn about the mechanisms that enable one object to
create another in C#. You will also learn how to define nested classes.
22 Module 7: Essentials of Object-Oriented Programming
Hello, World Revisited
using System;
class Hello
{
public static int Main( )
{
Console.WriteLine("Hello, World";
return 0;
}
}
using System;
class Hello
{
public static int Main( )
{
Console.WriteLine("Hello, World";
return 0;
}
}
The code for Hello, World is shown in the slide. There are some questions that
can be asked and answered:
n How does the runtime invoke a class?
n Why is Main static?
How Does the Runtime Invoke a Class?
If there is a single Main method, the compiler will automatically make it the
program entry point. The following code provides an example:
// OneEntrance.cs
class OneEntrance
{
static void Main( )
{
...
}
}
// end of file
c:\> csc OneEntrance.cs
The entry point of a C# program must be Main with a capital “M.”
The signature of Main is also important.
Warning
Module 7: Essentials of Object-Oriented Programming 23
However, if there are several methods called Main, one of them must explicitly
be designated as the program entry point (and that Main must also be explicitly
public) The following code provides an example:
// TwoEntries.cs
using System;
class EntranceOne
{
public static void Main( )
{
Console.Write("EntranceOne.Main( )";
}
}
class EntranceTwo
{
public static void Main( )
{
Console.Write("EntranceTwo.Main( )";
}
}
// End of file
c:\> csc /main:EntranceOne TwoEntries.cs
c:\> twoentries.exe
EntranceOne.Main( )
c:\> csc /main:EntranceTwo TwoEntries.cs
c:\> twoentries.exe
EntranceTwo.Main( )
c:\>
Note that the command-line option is case sensitive. If the name of the class
containing Main is EntranceOne (with a capital E and a capital O) then the
following will not work:
c:\> csc /main:entranceone TwoEntries.cs

使用道具 举报

回复
论坛徽章:
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
75#
 楼主| 发表于 2006-8-13 21:25 | 只看该作者
24 Module 7: Essentials of Object-Oriented Programming
If there is no Main method in the project, you cannot create an executable
program. However, you can create a dynamic -link library (DLL) as follows:
// NoEntrance.cs
class NoEntrance
{
public static void NotMain( )
{
Console.Write("NoEntrance.NotMain( )";
}
}
// End of file
c:\> csc /target:library NoEntrance.cs
c:\> dir
...
NoEntrance.dll
...
Why Is Main Static?
Making Main static allows it to be invoked without the runtime needing to
create an instance of the class.
Non-static methods can only be called on an object, as shown in the following
code:
class Example
{
void NonStatic( ) { ... }
static void Main( )
{
Example eg = new Example( );
eg.NonStatic( ); // Compiles
NonStatic( ); // compile-time error
}
...
}
This means that if Main is non-static, as in the following code, the runtime
needs to create an object in order to call Main.
class Example
{
void Main( )
{
...
}
}
In other words, the runtime would effectively need to execute the following
code:
Example run = new Example( );
run.Main( );
Module 7: Essentials of Object-Oriented Programming 25
Defining Simple Classes
n Data and Methods Together Inside a Class
n Methods Are Public, Data Is Private
class BankAccount
{
public void Withdraw(decimal amount)
{ ... }
public void Deposit(decimal amount)
{ ... }
private decimal balance;
private string name;
}
class BankAccount
{
public void Withdraw(decimal amount)
{ ... }
public void Deposit(decimal amount)
{ ... }
private decimal balance;
private string name;
}
Public methods
describe
accessible
behaviour
Public methods
describe
accessible
behaviour
Private fields
describe
inaccessible
state
Private fields
describe
inaccessible
state
Although classes and structs are semantically different, they do have syntactic
similarity. To define a class rather than a struct:
n Use the keyword class instead of struct.
n Declare your data inside the class exactly as you would for a struct.
n Declare your methods inside the class.
n Add access modifiers to the declarations of your data and methods. The
simplest two access modifiers are public and private. (The other three will
be covered later in this course.)
It is up to you to use public and private wisely to enforce encapsulation.
C# does not prevent you from creating public data.
The meaning of public is “access not limited.” The meaning of private is
“access limited to the containing type.” The following example clarifies this:
class BankAccount
{
public void Deposit(decimal amount)
{
balance += amount;
}
private decimal balance;
}
Note

使用道具 举报

回复
论坛徽章:
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
76#
 楼主| 发表于 2006-8-13 21:26 | 只看该作者
26 Module 7: Essentials of Object-Oriented Programming
In this example, the Deposit method can access the private balance because
Deposit is a method of BankAccount (the type that contains balance). In other
words, Deposit is on the inside. From the outside, private members are always
inaccessible. In the following example, the expression underAttack.balance
will fail to compile.
class BankRobber
{
public void StealFrom(BankAccount underAttack)
{
underAttack.balance -= 999999M;
}
}
The expression underAttack.balance will fail to compile because the
expression is inside the StealFrom method of the BankRobber class. Only
methods of the BankAccount class can access private members of
BankAccount objects.
To declare static data, follow the pattern used by static methods (such as Main),
and prefix the data declaration with the keyword static. The following code
provides an example:
class BankAccount
{
public void Deposit(decimal amount) { ... }
public static void Main( ) { ... }
...
private decimal balance;
private static decimal interestRate;
}
Module 7: Essentials of Object-Oriented Programming 27
If you do not specify an access modifier when declaring a class member, it will
default to private. In other words, the following two methods are semantically
identical:
class BankAccount
{
...
decimal balance;
}
class BankAccount
{
...
private decimal balance;
}
It is considered good style to explicitly write private even though it is not
strictly necessary.
The order in which members of a class are declared is not significant to the C#
compiler. However, it is considered good style to declare the public members
(methods) before the private members (data). This is because a class user only
has access to the public members anyway, and declaring public members before
private members naturally reflects this priority.
Tips
28 Module 7: Essentials of Object-Oriented Programming
Instantiating New Objects
n Declaring a Class Variable Does Not Create an Object
l Use the new operator to create an object
class Program
{
static void Main( )
{
Time now;
now.hour = 11;
BankAccount yours = new BankAccount( );
yours.Deposit(999999M);
}
}
class Program
{
static void Main( )
{
Time now;
now.hour = 11;
BankAccount yours = new BankAccount( );
yours.Deposit(999999M);
}
}
hour
minute
now
yours ...
...
new
BankAccount
object
Consider the following code examples:
struct Time
{
public int hour, minute;
}
class Program
{
static void Main( )
{
Time now;
now.hour = 11;
now.minute = 59;
...
}
}
Variables of the struct type are value types. This means that when you declare a
struct variable (such as now in Main), you create a value on the stack. In this
case, the Time struct contains two ints, so the declaration of now creates two
ints on the stack, one called now.hour and one called now.minute. These two
ints are not, repeat not, default initialized to zero. Hence the value of now.hour
or now.minute cannot be read until they have been assigned a definite value.
Values are scoped to the block in which they are declared. In this example, now
is scoped to Main. This means that when the control flow exits Main (either
through a normal return or because an exception has been thrown), now will go
out of scope; it will cease to exist.
Module 7: Essentials of Object-Oriented Programming 29
Classes are completely different as shown in the following code:
class Time // NOTE: Time is now a class
{
public int hour, minute;
}
class Program
{
static void Main( )
{
Time now;
now.hour = 11;
now.minute = 59;
...
}
}
When you declare a class variable, you do not create an instance or object of
that class. In this case, the declaration of now does not create an object of the
Time class. Declaring a class variable creates a reference that is capable of
referring to an object of that class. This is why classes are called reference types.
This means that if the runtime were allowed to run the preceding code, it would
be trying to access the integers inside a non-existent Time object. Fortunately,
the compiler will warn you about this error. If you compile the preceding code,
you will get the following error message:
error CS0165: Use of possibly unassigned local variable 'now'

使用道具 举报

回复
论坛徽章:
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
77#
 楼主| 发表于 2006-8-13 21:26 | 只看该作者
30 Module 7: Essentials of Object-Oriented Programming
To fix this error, you must create a Time object (using the new keyword) and
make the reference variable now actually refer to the newly created object, as in
the following code:
class Program
{
static void Main( )
{
Time now = new Time( );
now.hour = 11;
now.minute = 59;
...
}
}
Recall that when you create a local struct value on the stack, the fields are not,
repeat not, default initialized to zero. Classes are different: when you create an
object as an instance of a class, as above, the fields of the object are default
initialized to zero. Hence the following code compiles cleanly:
class Program
{
static void Main( )
{
Time now = new Time( );
Console.WriteLine(now.hour); // writes 0
Console.WriteLine(now.minute); // writes 0
...
}
}
Module 7: Essentials of Object-Oriented Programming 31
Using the this Operator
n The this Operator Refers to the Object Used to Call the
Method
l Useful when identifiers from different scopes clash
class BankAccount
{
...
public void SetName(string name)
{
this.name = name;
}
private string name;
}
class BankAccount
{
...
public void SetName(string name)
{
this.name = name;
}
private string name;
}
If this statement were
name = name;
What would happen?
The this operator implicitly refers to the object that is making an object method
call.
In the following code, the statement name = name would have no effect at all.
This is because the identifier name on the left side of the assignment does not
resolve to the private BankAccount field called name. Both identifiers resolve
to the method parameter, which is also called name.
class BankAccount
{
public void SetName(string name)
{
name = name;
}
private string name;
}
The C# compiler does not emit a warning for this bug.
Using the this Keyword
You can solve this reference problem by using the this keyword, as illustrated
on the slide. The this keyword refers to the current object for which the method
is called.
Static methods cannot use this as they are not called by using an object.
Warning
Note
32 Module 7: Essentials of Object-Oriented Programming
Changing the Parameter Name
You can also solve the reference problem by changing the name of the
parameter, as in the following example:
class BankAccount
{
public void SetName(string newName)
{
name = newName;
}
private string name;
}
Using this when writing constructors is a common C# idiom. The
following code provides an example:
struct Time
{
public Time(int hour, int minute)
{
this.hour = hour;
this.minute = minute;
}
private int hour, minute;
}
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
78#
 楼主| 发表于 2006-8-13 21:26 | 只看该作者
Module 7: Essentials of Object-Oriented Programming 33
The this operator is also used to implement call chaining. Notice in the
following class that both methods return the calling object:
class Book
{
public Book SetAuthor(string author)
{
this.author = author;
return this;
}
public Book SetTitle(string title)
{
this.title = title;
return this;
}
private string author, title;
}
Returning this allows method calls to be chained together, as follows:
class Usage
{
static void Chained(Book good)
{
good.SetAuthor(“Fowler”).SetTitle(“Refactoring”);
}
static void NotChained(Book good)
{
good.SetAuthor(“Fowler”);
good.SetTitle(“Refactoring”);
}
}
A static method exists at the class level and is called against the class and
not against an object. This means that a static method cannot use the this
operator.
Tip
Note
34 Module 7: Essentials of Object-Oriented Programming
Creating Nested Classes
n Classes Can Be Nested Inside Other Classes
class Program
{
static void Main( )
{
Bank.Account yours = new Bank.Account( );
}
}
class Bank
{
... class Account { ... }
}
class Program
{
static void Main( )
{
Bank.Account yours = new Bank.Account( );
}
}
class Bank
{
... class Account { ... }
}
The full name of the nested
class includes the name of
the outer class
The full name of the nested
class includes the name of
the outer class
There are five different kinds of types in C#:
n class
n struct
n interface
n enum
n delegate
You can nest all five of these inside a class or a struct.
You cannot nest a type inside an interface, an enum, or a delegate.
Note
Module 7: Essentials of Object-Oriented Programming 35
In the code above, the Account class is nested inside the Bank class. The full
name of the nested class is Account . Bank, and this name must be used when
naming the nested type outside the scope of Bank. The following code provides
an example:
// Program.cs
class Program
{
static void Main( )
{
Account yours = new Account( ); // compile-time error
}
}
// end of file
c:\> csc Program.cs
error CS0234: The type...'Account' does not exist in the
class...'Program'
In contrast, just the name Account can be used from inside of Bank, as in the
following example:
class Bank
{
class Account( ) { ... }
Account OpenAccount( )
{
return new Account ( );
}
}
See the next topic for a more thorough examination of the example.
Nested classes offer several useful features:
n Nested classes can be declared with specific accessibility. This is covered in
the next topic.
n Using nested classes removes fewer names from the global scope or the
containing namespace.
n Nested classes allow extra structure to be expressed in the grammar of the
language. For example, the name of the class is Bank . Account (three
tokens) rather than BankAccount (one token).
Note

使用道具 举报

回复
论坛徽章:
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
79#
 楼主| 发表于 2006-8-13 21:26 | 只看该作者
36 Module 7: Essentials of Object-Oriented Programming
Accessing Nested Classes
n Nested Classes Can Also Be Declared As Public or
Private
class Bank
{
public class Account { ... }
private class AccountNumberGenerator { ... }
}
class Program
{
static void Main( )
{
Bank.Account accessible;
Bank.AccountNumberGenerator inaccessible;
}
}
class Bank
{
public class Account { ... }
private class AccountNumberGenerator { ... }
}
class Program
{
static void Main( )
{
Bank.Account accessible;
Bank.AccountNumberGenerator inaccessible;
}
}

You control the accessibility of data and methods by declaring them as public
or private. You control the accessibility of a nested class in exactly the same
way.
Public Nested Class
A public nested class has no access restrictions. It is declared to be publicly
accessible. The full name of a nested c lass must still be used when outside the
containing class.
Private Nested Class
A private nested class has exactly the same access restrictions as private data or
methods. A private nested class is inaccessible from outside the containing class,
as the following example shows:
class Bank
{
private class AccountNumberGenerator( )
{
...
}
}
class Program
{
static void Main( )
{
// Compile time error
Bank.AccountNumberGenerator variable;
}
}
Module 7: Essentials of Object-Oriented Programming 37
In this example, Main cannot use Bank.AccountNumberGenerator because
Main is a method of Program and AccountNumberGenerator is private and
hence only accessible to its outer class, Bank.
A private nested class is accessible only to members of the containing class as
the following examples shows:
class Bank
{
public class Account
{
public void Setup( )
{
NumberSetter.Set(this);
balance = 0M;
}
private class NumberSetter
{
public static void Set(Account a)
{
a.number = nextNumber++;
}
private static int nextNumber = 2311;
}
private int number;
private decimal balance;
}
}
In this code, note that the Account.Setup method can access the
NumberSetter class because, although NumberSetter is a private class, it is
private to Account, and Setup is a method of Account.

使用道具 举报

回复
论坛徽章:
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
80#
 楼主| 发表于 2006-8-13 21:27 | 只看该作者
{
...
static BankAccount NewBankAccount( )
{
BankAccount created;
...
created.accNo = number; // Error here
...
}
...
}
6. The assignment to created.accNo compiled without error when
BankAccount was a struct. Now that it is a class, it does not compile! This
is because when BankAccount was a struct, the declaration of the created
variable created a BankAccount value (on the stack). Now that
BankAccount is a class, the declaration of the created variable does not
create a BankAccount value; it creates a BankAccount reference that does
not yet refer to a BankAccount object.
Module 7: Essentials of Object-Oriented Programming 41
7. Change the declaration of created so that it is initialized with a newly
created BankAccount object, as shown:
class CreateAccount
{
...
static BankAccount NewBankAccount( )
{
BankAccount created = new BankAccount( );
...
created.accNo = number;
...
}
...
}
8. Save your work.
9. Compile and run the program. Verify that the data entered at the console is
correctly read back and displayed in the CreateAccount.Write method.
? To encapsulate the BankAccount class
1. All the data members of the BankAccount class are currently public.
Modify them to make them private, as shown:
class BankAccount
{
private long accNo;
private decimal accBal;
private AccountType accType;
}
2. Compile the program. It will fail to compile. The error occurs in the
CreateAccount class as shown::
class CreateAccount
{
...
static BankAccount NewBankAccount( )
{
BankAccount created = new BankAccount( );
...
created.accNo = number; // Error here again
...
}
...
}

使用道具 举报

回复

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

本版积分规则 发表回复

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