楼主: 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
81#
 楼主| 发表于 2006-8-13 21:27 | 只看该作者
38 Module 7: Essentials of Object-Oriented Programming
Notice also that the Account.NumberSetter.Set method can access the private
balance field of the Account object a. This is because Set is a method of class
NumberSetter, which is nested inside Account. Hence NumberSetter (and its
methods) have access to the private members of Account.
The default accessibility of a nested class is private (as it is for data and
methods). In the following example, the Account class defaults to private:
class Bank
{
class Account( ) { ... }
public Account OpenPublicAccount( )
{
Account opened = new Account( );
opened.Setup( );
return opened;
}
private Account OpenPrivateAccount( )
{
Account opened = new Account( );
opened.Setup( );
return opened;
}
}
The Account class is accessible to OpenPublicAccount and
OpenPrivateAccount because both methods are nested inside Bank. However,
the OpenPublicAccount method will not compile. The problem is that
OpenPublicAccount is a public method, usable as in the following code:
class Program
{
static void Main( )
{
Bank b = new Bank( );
Bank.Account opened = b.OpenPublicAccount( );
...
}
}
This code will not compile because Bank.Account is not accessible to
Program.Main, Bank.Account is private to Bank, and Main is not a method
of Bank. The following error message appears:
error CS0050: Inconsistent accessibility: return type
'Bank.Account' is less accessible than method
'Bank.OpenPublicAccount'
The accessibility rules for a top-level class (that is, a class that is not nested
inside another class) are not the same as those for a nested class. A top-level
class cannot be declared private and defaults to internal accessibility. (Internal
access is covered fully in a later module.)
Module 7: Essentials of Object-Oriented Programming 39
Lab 7: Creating and Using Classes
Objectives
After completing this lab, you will be able to:
n Create classes and instantiate objects.
n Use non-static data and methods.
n Use static data and methods.
Prerequisites
Before working on this lab, you must be familiar with the following:
n Creating methods in C#
n Passing arguments as method parameters in C#
Estimated time to complete this lab: 45 minutes
40 Module 7: Essentials of Object-Oriented Programming
Exercise 1
Creating and Using a Class
In this exercise, you will take the bank account struct that you developed in a
previous module and convert it into a class. You will declare its data members
as private but provide non-static public methods for accessing the data. You
will build a test harness that creates an account object and populates it with an
account number and balance that is specified by the user. Finally, you will print
the data in the account.
? To change BankAccount from a struct to a class
1. Open the CreateAccount.sln project in the install folder\
Labs\Lab07\Starter\CreateAccount folder.
2. Study the program in the BankAccount.cs file. Notice that BankAccount is a
struct type.
3. Compile and run the program. You will be prompted to enter an account
number and an initial balance. Repeat this process to create another account.
4. Modify BankAccount in BankAccount.cs to make it a class rather than a
struct.
5. Compile the program. It will fail to compile. Open the CreateAccount.cs file
and view the CreateAccount class. The class will look as follows:
class CreateAccount
42 Module 7: Essentials of Object-Oriented Programming
3. The BankAccount data member assignments now fail to compile because
the data members are private. Only BankAccount methods can access the
private BankAccount data members. You need to write a public
BankAccount method to do the assignments for you. Perform the following
steps:
Add a non-static public method called Populate to BankAccount. This
method will return void and expect two parameters: a long (the bank
account number) and a decimal (the bank account balance). The body of this
method will assign the long parameter to the accNo field and the decimal
parameter to the accBal field. It will also set the accType field to
AccountType.Checking as shown:
class BankAccount
{
public void Populate(long number, decimal balance)
{
accNo = number;
accBal = balance;
accType = AccountType.Checking;
}
private long accNo;
private decimal accBal;
private AccountType accType;
}
4. Comment out the three assignments to the created variable in the
CreateAccount.NewbankAccount method. In their place, add a statement
that calls the Populate method on the created variable, passing number and
balance as arguments. This will look as follows:
class CreateAccount
{
...
static BankAccount NewBankAccount( )
{
BankAccount created = new BankAccount( );
...
// created.accNo = number;
// created.accBal = balance;
// created.accType = AccountType.Checking;
created.Populate(number, balance);
...
}
...
}
5. Save your work.
Module 7: Essentials of Object-Oriented Programming 43
6. Compile the program. It will fail to compile. There are still three statements
in the CreateAccount.Write method that attempt to directly access the
private BankAccount fields. You need to write three public BankAccount
methods that return the values of these three fields. Perform the following
steps:
a. Add a non-static public method to BankAccount called Number. This
method will return a long and expect no parameters. It will return the
value of the accNo field as shown:
class BankAccount
{
public void Populate(...) ...
public long Number( )
{
return accNo;
}
...
}
b. Add a non-static public method to BankAccount called Balance, as
shown in the following code. This method will return a decimal and
expect no parameters. It will return the value of the accBal field.
class BankAccount
{
public void Populate(...) ...
...
public decimal Balance( )
{
return accBal;
}
...
}
c. Add a non-static public method called Type to BankAccount, as shown
in the following code. This method will return an AccountType and
expect no parameters. It will return the value of the accType field.
class BankAccount
{
public void Populate(...) ...
...
public AccountType Type( )
{
return accType;
}
...
}

使用道具 举报

回复
论坛徽章:
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
82#
 楼主| 发表于 2006-8-13 21:27 | 只看该作者
44 Module 7: Essentials of Object-Oriented Programming
d. Finally, replace the three statements in the CreateAccount.Write
method that attempt to directly access the private BankAccount fields
with calls to the three public methods you have just created, as shown:
class CreateAccount
{
...
static void Write(BankAccount toWrite)
{
Console.WriteLine("Account number is {0}",
êtoWrite.Number( ));
Console.WriteLine("Account balance is {0}",
êtoWrite.Balance( ));
Console.WriteLine("Account type is {0}",
êtoWrite.Type( ).Format( ));
}
}
7. Save your work.
8. Compile the program and correct any other errors. Run the program. Verify
that the data entered at the console and passed to the
BankAccount.Populate method is correctly read back and displayed in the
CreateAccount.Write method.
Module 7: Essentials of Object-Oriented Programming 45
? To further encapsulate the BankAccount class
1. Change the BankAccount.Type method so that it returns the type of the
account as a string rather than as an AccountType enum, as shown:
class BankAccount
{
...
public string Type( )
{
return accType.Format( );
}
...
private AccountType accType;
}
2. Change the last WriteLine statement in the CreateAccount.Write method
so that it no longer calls the Format method, as shown:
class CreateAccount
{
...
static void Write(BankAccount acc)
{
Console.WriteLine("Account number is {0}",
êacc.Number( ));
Console.WriteLine("Account balance is {0}",
êacc.Balance( ));
Console.WriteLine("Account type is {0}",
êacc.Type( ));
}
}
3. Save your work.
4. Compile the program and correct any errors. Run the program. Verify that
the data entered at the console and passed to the BankAccount.Populate
method is correctly read back and displayed in the CreateAccount.Write
method.
46 Module 7: Essentials of Object-Oriented Programming
Exercise 2
Generating Account Numbers
In this exercise, you will modify the BankAccount class from Exercise 1 so
that it will generate unique account numbers. You will accomplish this by using
a static variable in the BankAccount class and a method that increments and
returns the value of this variable. When the test harness creates a new account,
it will call this method to generate the account number. It will then call the
method of the BankAccount class that sets the number for the account, passing
in this value as a parameter .
? To ensure that each BankAccount number is unique
1. Open the project UniqueNumbers.sln in the install folder\
Labs\Lab07\Starter\UniqueNumbers folder.
This project is the same as the completed CreateAccount project from
Exercise 1.
2. Add a private static long called nextAccNo to the BankAccount class, as
shown:
class BankAccount
{
...
private long accNo;
private decimal accBal;
private AccountType accType;
private static long nextAccNo;
}
3. Add a public static method called NextNumber to the BankAccount class,
as shown in the following code. This method will return a long and expect
no parameters. It will return the value of the nextAccNo field in addition to
incrementing this field.
class BankAccount
{
...
public static long NextNumber( )
{
return nextAccNo++;
}
private long accNo;
private decimal accBal;
private AccountType accType;
private static long nextAccNo;
}
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
83#
 楼主| 发表于 2006-8-13 21:28 | 只看该作者
Module 7: Essentials of Object-Oriented Programming 47
4. Comment out the statement in the CreateAccount.NewBankAccount
method that writes a prompt to the console asking for the bank account
number, as shown:
//Console.Write("Enter the account number: ";
5. Replace the initialization of number in the
CreateAccount.NewBankAccount method with a call to the
BankAccount.NextNumber method you have just created, as shown:
//long number = long.Parse(Console.ReadLine( ));
long number = BankAccount.NextNumber( );
6. Save your work.
7. Compile the program and correct any errors. Run the program. Verify that
the two accounts have account numbers 0 and 1.
8. Currently, the BankAccount.nextAccNo static field has a default
initialization to zero. Explicitly initialize this field to 123.
9. Compile and run the program. Verify that the two accounts created have
account numbers 123 and 124.
48 Module 7: Essentials of Object-Oriented Programming
? To further encapsulate the BankAccount class
1. Change the BankAccount.Populate method so that it expects only one
parameter—the decimal balance. Inside the method, assign the accNo field
by using the BankAccount.NextNumber static method, as shown:
class BankAccount
{
public void Populate(decimal balance)
{
accNo = NextNumber( );
accBal = balance;
accType = AccountType.Checking;
}
...
}
2. Change BankAccount.NextNumber into a private method, as shown:
class BankAccount
{
...
private static long NextNumber( ) ...
}
3. Comment out the declaration and initialization of number in the
CreateAccount.NewBankAccount method. Change the created.Populate
method call so that it only passes a single parameter, as shown:
class CreateAccount
{
...
static BankAccount NewBankAccount( )
{
BankAccount created = new BankAccount( );
//long number = BankAccount.NextNumber( );
...
created.Populate(balance);
...
}
...
}
4. Save your work.
5. Compile the program and correct any errors. Run the program. Verify that
the two accounts still have account numbers 123 and 124.
Module 7: Essentials of Object-Oriented Programming 49
Exercise 3
Adding More Public Methods
In this exercise, you will add two methods to the Account class: Withdraw and
Deposit.
Withdraw will take a decimal parameter and will deduct the given amount
from the balance. However, it will check first to ensure that sufficient funds are
available, since accounts are not allowed to become overdrawn. It will return a
bool value indicating whether the withdrawal was successful.
Deposit will also take a decimal parameter whose value it will add to the
balance in the account. It will return the new value of the balance.
? To add a Deposit method to the BankAccount class
1. Open the project MoreMethods.sln in the install folder\
Labs\Lab07\Starter\MoreMethods folder.
This project is the same as the completed UniqueNumbers project
from Exercise 2.
2. Add a public non-static method called Deposit to the BankAccount class,
as shown in the following code. This method will also take a decimal
parameter whose value it will add to the balance in the account. It will
return the new value of the balance.
class BankAccount
{
...
public decimal Deposit(decimal amount)
{
accBal += amount;
return accBal;
}
...
}
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
84#
 楼主| 发表于 2006-8-13 21:28 | 只看该作者
50 Module 7: Essentials of Object-Oriented Programming
3. Add a public static method called TestDeposit to the CreateAccount class,
as shown in the following code. This method will return void and expect a
BankAccount parameter. The method will write a prompt to the console
prompting the user for the amount to deposit, capture the entered amount as
a decimal, and then call the Deposit method on the BankAccount
parameter, passing the amount as an argument.
class CreateAccount
{
...
public static void TestDeposit(BankAccount acc)
{
Console.Write("Enter amount to deposit: ";
decimal amount = decimal.Parse(Console.ReadLine());
acc.Deposit(amount);
}
...
}
4. Add to CreateAccount.Main statements that call the TestDeposit method
you have just created, as shown in the following code. Ensure that you call
TestDeposit for both account objects. Use the CreateAccount.Write
method to display the account after the deposit takes place.
class CreateAccount
{
static void Main( )
{
BankAccount berts = NewBankAccount( );
Write(berts);
TestDeposit(berts);
Write(berts);
BankAccount freds = NewBankAccount( );
Write(freds);
TestDeposit(freds);
Write(freds);
}
}
5. Save your work.
6. Compile the program and correct any errors. Run the program. Verify that
deposits work as expected.
If you have time, you might want to add a further check to Deposit to
ensure that the decimal parameter passed in is not negative.
Note
Module 7: Essentials of Object-Oriented Programming 51
? To add a Withdraw method to the BankAccount class
1. Add a public non-static method called Withdraw to BankAccount, as
shown in the following code. This method will expect a decimal parameter
specifying the amount to withdraw. It will deduct the amount from the
balance only if sufficient funds are available, since accounts are not allowed
to become overdrawn. It will return a bool indicating whether the
withdrawal was successful.
class BankAccount
{
...
public bool Withdraw(decimal amount)
{
bool sufficientFunds = accBal >= amount;
if (sufficientFunds) {
accBal -= amount;
}
return sufficientFunds;
}
...
}
2. Add a public static method called TestWithdraw to the CreateAccount
class, as shown in the following code. This method will return void and will
expect a BankAccount parameter. The method will write a prompt to the
console prompting the user for the amount to withdraw, capture the entered
amount as a decimal, and then call the Withdraw method on the
BankAccount parameter, passing the amount as an argument. The method
will capture the bool result returned by Withdraw and write a message to
the console if the withdrawal failed.
class CreateAccount
{
...
public static void TestWithdraw(BankAccount acc)
{
Console.Write("Enter amount to withdraw: ";
decimal amount = decimal.Parse(Console.ReadLine());
if (!acc.Withdraw(amount)) {
Console.WriteLine("Insufficient funds.";
}
}
...
}

使用道具 举报

回复
论坛徽章:
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
85#
 楼主| 发表于 2006-8-13 21:28 | 只看该作者
52 Module 7: Essentials of Object-Oriented Programming
3. Add to CreateAccount.Main statements that call the TestWithdraw
method you have just created, as shown in the following code. Ensure that
you call TestWithdraw for both account objects. Use the
CreateAccount.Write method to display the account after the withdrawal
takes place.
class CreateAccount
{
static void Main( )
{
BankAccount berts = NewBankAccount( );
Write(berts);
TestDeposit(berts);
Write(berts);
TestWithdraw(berts);
Write(berts);
BankAccount freds = NewBankAccount( );
Write(freds);
TestDeposit(freds);
Write(freds);
TestWithdraw(freds);
Write(freds);
}
}
4. Save your work.
5. Compile the program and correct any errors. Run the program. Verify that
withdrawals work as expected. Test successful and unsuccessful
withdrawals.
Module 7: Essentials of Object-Oriented Programming 53
u Defining Object-Oriented Systems
n Inheritance
n Class Hierarchies
n Single and Multiple Inheritance
n Polymorphism
n Abstract Base Classes
n Interfaces
n Early and Late Binding
In this section, you will learn about inheritance and polymorphism. You will
learn how to implement these concepts in C# in later modules.
54 Module 7: Essentials of Object-Oriented Programming
Inheritance
n Inheritance Specifies an “Is a Kind of" Relationship
l Inheritance is a class relationship
l New classes specialize existing classes
Musician
Violin
Player
Base class
Derived class
Generalization
Specialization Is this a good
example of
inheritance ?
Inheritance is a relationship that is specified at the class level. A new class can
be derived from an existing class. In the slide above, the ViolinPlayer class is
derived from the Musician class. The Musician class is called the base class
(or, less frequently, the parent class, or the superclass); the ViolinPlayer class
is called the derived class (or, less frequently, the child class, or subclass). The
inheritance is shown by using the Unified Modeling Language (UML) notation.
More UML notation will be covered in later slides.
Inheritance is a powerful relationship because a derived class inherits
everything from its base class. For example, if the base class Musician contains
a method called TuneYourInstrument, this method is automatically a member
of the derived ViolinPlayer class.
A base class can have any number of derived classes. For example, new classes
(such as FlutePlayer, or PianoPlayer) could all be derived from the Musician
class. These new derived classes would again automatically inherit the
TuneYourInstrument method from the Musician base class.
A change to a base class is automatically a change to all derived classes.
For example, if a field of type MusicalIntrument was added to the Musician
base class, then every derived class (ViolinPlayer, FlutePlayer, PianoPlayer,
and so on) would automatically acquire a field of type MusicalInstrument. If a
bug is introduced into a base class, it will automatically become a bug in every
derived class. (This is known as the fragile base class problem.)
Note
Module 7: Essentials of Object-Oriented Programming 55
Understanding Inheritance in Object-Oriented
Programming
The graphic on the slide shows a man, a woman, and a small girl riding a
bicycle. If the man and the woman are the biological parents of the girl, then
she will inherit half of her genes from the man and half of her genes from the
woman.
But this is not an example of class inheritance. It is implementation mechanism!
The classes are Man and Woman. There are two instances of the Woman class
(one with an age attribute of less than 16) and one instance of the Man class.
There is no class inheritance. The only possible way there could be class
inheritance in this example is if the Man class and the Woman class share a
base class Person.

使用道具 举报

回复
论坛徽章:
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
86#
 楼主| 发表于 2006-8-13 21:28 | 只看该作者
56 Module 7: Essentials of Object-Oriented Programming
Class Hierarchies
n Classes Related by Inheritance Form Class Hierarchies
Musician
???
String
Musician
??? Violin
Musical
Instrument
plays
plays
Violin plays
Player
Stringed
Instrument
Classes that derive from base classes can themselves be derived from. For
example, in the slide the StringMusician class is derived from the Musician
class but is itself a base class for the further derived ViolinPlayer class. A
group of classes related by inheritance forms a structure known as a class
hierarchy. As you move up a hierarchy, the classes represent more general
concepts (generalization); as you move down a hierarchy the classes represent
more specialized concepts (specialization).
The depth of a class hierarchy is the number of levels of inheritance in the
hierarchy. Deeper class hierarchies are harder to use and harder to implement
than shallow class hierarchies. Most programming guidelines recommend that
the depth be limited to between five and seven classes.
The slide depicts two parallel class hierarchies: one for musicians and another
for musical instruments. Creating class hierarchies is not easy: classes need to
be designed as base classes from the start. Inheritance hierarchies are also the
dominant feature of frameworks— models of work that can be built on and
extended.
Module 7: Essentials of Object-Oriented Programming 57
Single and Multiple Inheritance
n Single Inheritance: Deriving from One Base Class
n Multiple Inheritance: Deriving from Two or More Base
Classes
Stringed
Instrument
Violin
Musical
Instrument
Stringed
Instrument
Pluckable
Violin has a single direct
base class
Stringed Instrumenthas
two direct base classes
Single inheritance occurs when a class has a single direct base class. In the
example in the slide, the Violin class inherits from one class,
StringedInstrument, and is an example of single inheritance.
StringedInstrument derives from two classes, but that is not relevant to the
Violin class. Single inheritance can still be difficult to use wisely. It is well
known that inheritance is one of the most powerful software modeling tools,
and at the same time one of the most misunderstood and misused.
Multiple inheritance occurs when a class has two or more direct base classes. In
the example in the slide, the StringedInstrument class derives directly from
two classes, MusicalInstrument and Pluckable, and provides an example of
multiple inheritance. Multiple inheritance offers multiple opportunities to
misuse inheritance! C#, like most modern programming languages (but not
C++), restricts the use of multiple inheritance: you can inherit from as many
interfaces as you want, but you can only inherit from one non-interface (that is,
at most one abstract or concrete class). The terms interface, abstract class, and
concrete class are covered later in this module.
Notice that all forms of inheritance, but multiple inheritance in particular, offer
many views of the same object. For example, a Violin object could be used at
the Violin class level, but it could also be used at the StringedInstrument class
level.
58 Module 7: Essentials of Object-Oriented Programming
Polymorphism
n The Method Name Resides in the Base Class
n The Method Implementations Reside in the Derived
Classes
String Musician
TuneYourInstrument( )
Guitar Player
TuneYourInstrument( )
Violin Player
TuneYourInstrument( )
A method with no
implementation is
called an operation
A method with no
implementation is
called an operation
Polymorphism literally means many forms or many shapes. It is the concept that
a method declared in a base class can be implemented in many different ways in
the different derived classes.
Consider the scenario of an orchestra of musicians all tuning their instruments
as they get ready for a concert. Without polymorphism, the conductor needs to
visit each musician in turn, seeing what kind of instrument the musician plays,
and giving detailed instructions about how to tune that particular kind of
instrument. With polymorphism, the conductor just tells each musician, “tune
your instrument.” The conductor does not need to know which particular
instrument each musician plays, just that each musician will respond to the
same request for behavior in a manner appropriate to their particular instrument.
Rather than the conductor being responsible for the knowledge of how to tune
all of the different kinds of instruments, the knowledge is partitioned across the
different kinds of musicians as appropriate: a guitar player knows how to tune a
guitar, a violin player knows how to tune a violin. In fact, the conductor does
not know how to tune any of the instruments. This decentralized allocation of
responsibilities also means that new derived classes (such as DrumPlayer) can
be added to the hierarchy without necessarily needing to modify existing
classes (such as the conductor).
There is one problem though. What is the body of the method at the base-class
level? Without knowing which particular kind of instrument a musician plays, it
is impossible to know how to tune the instrument. To manage this, only the
name of the method (and no body) can be declared in the base class. A method
name with no method body is called an operation. One of the ways of denoting
an operation in UML is to use italics, as is shown in the slide.

使用道具 举报

回复
论坛徽章:
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
87#
 楼主| 发表于 2006-8-13 21:29 | 只看该作者
Module 7: Essentials of Object-Oriented Programming 59
Abstract Base Classes
n Some Classes Exist Solely to Be Derived From
l It makes no sense to create instances of these classes
l These classes are abstract
Stringed Musician
{ abstract }
Guitar Player
? concrete ?
Violin Player
? concrete ?
You can create instances
of concrete classes
You can create instances
of concrete classes
You cannot create instances
of abstract classes
You cannot create instances
of abstract classes
In a typical class hierarchy, the operation (the name of a method) is declared in
the base class, and the method is implemented in different ways in the different
derived classes. The base class exists solely to introduce the name of the
method into the hierarchy. In particular, the base class operation does not
require an implementation. This makes it vital that the base class not be used as
a regular class. Most importantly, you must not be allowed to create instances
of the base class: if you could, what would happen if you called the operation
that had no implementation? A mechanism is required that makes it impossible
to create instances of these base classes: the base class needs to be marked
abstract.
In a UML design, you can constrain a class as abstract by writing the name of
the class in italics or by placing the word abstract within braces ({ and }). In
contrast, you can use the word concrete or class between guillemets (<< and >>
as a stereotype to denote in UML a class that is not abstract, a class that can be
used to create instances. This is shown in the slide. All object-oriented
programming languages have grammatical constructs that implement an
abstract constraint. (Even C++ can use protected constructors.)
Sometimes the creation of an abstract base class is more retrospective: duplicate
common features in the derived classes are factored into a new base class.
However, once again, the base class should be marked abstract because its
purpose is to be derived from, and not to create instances.
60 Module 7: Essentials of Object-Oriented Programming
Interfaces
n Interfaces Contain Only Operations, Not Implementation
String Musician
{ abstract }
Violin Player
? concrete ?
Musician
? interface ?
Nothing but operations.
You cannot create instances of an
interface.
Nothing but operations.
You cannot create instances of an
interface.
May contain some implementation.
You cannot create instances of an
abstract class.
May contain some implementation.
You cannot create instances of an
abstract class.
Must implement all inherited
operations. You can create
instances of a concrete class.
Must implement all inherited
operations. You can create
instances of a concrete class.
Abstract classes and interfaces are alike in that neither can be used to instantiate
objec ts. However, they differ in that an abstract class may contain some
implementation whereas an interface contains no implementation of any kind;
an interface contains only operations (the names of methods). You could say
that an interface is even more abstract than an abstract class!
In UML, you can depict an interface by using the word interface between
guillemets (<< and >>. All object-oriented programming languages have
grammatical constructs that implement an interface.
Interfaces are important constructs in object-oriented programs. In UML,
interfaces have specific notation and terminology. When you derive from an
interface, it is said that you implement that interface. UML depicts this with a
dashed line called realization. When you derive from a non-interface (an
abstract class or a concrete class) it is said that you extend that class. UML
depicts this with a solid line called generalization/specialization.
Place your interfaces at the top of a class hierarchy. The idea is simple: if you
can program to an interface— that is, if you use only those features of an object
that are declared in its interface—your program loses all dependence on the
specific object and its concrete class. In other words, when you program to an
interface, many different objects of many different classes can be used
interchangeably. It is this ability to make changes with no impact that leads to
the object-oriented maxim, “Program to an interface and not to an
implementation.”

使用道具 举报

回复
论坛徽章:
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
88#
 楼主| 发表于 2006-8-13 21:29 | 只看该作者
Module 7: Essentials of Object-Oriented Programming 61
Early and Late Binding
n Normal Method Calls Are Resolved at Compile Time
n Polymorphic Method Calls Are Resolved at Run Time
TuneYourInstrument( )
TuneYourInstrument( )
Musician
? interface ?
Violin Player
? concrete ?
Late Binding
Early Binding
runtime
When you make a method call directly on an object, that is, not through a base
class operation, the method call is resolved at compile time. This is also known
as early binding or static binding.
When you make a method call indirectly on an object—that is, through a base
class operation— the method call is resolved at run time. This is also known as
late binding or dynamic binding.
An example of late binding occurs when a conductor tells all of the musicians
in an orchestra to tune their instruments. By working at the interface level, the
conductor does not need to know (and hence be dependent on) the specific
different kinds of concrete musicians (such as ViolinPlayer). The conductor is
also freed from needing to know when a new class is added to the hierarchy for
a new kind of musician (for example, HarpPlayer).
The flexibility of late binding comes with a physical price and a logical price:
n Physical price
Late bound calls are slightly slower than early bound calls. In effect, the
extra work that must be performed as a result of a late bound call is to
discover the class of the calling object. This is done in an efficient manner
(you would not be able to do it faster yourself), but it is extra work.
n Logical price
With late binding, derived classes can be substituted for their base classes.
An operation call can be made through an interface, and at run time the
derived class object will correctly have its method called. In other words, all
derived classes that implement an interface can act as substitutes for the
interface type. Newcomers to object-oriented programming often fail to
fully appreciate the substitutability aspect of inheritance.
62 Module 7: Essentials of Object-Oriented Programming
Review
n Classes and Objects
n Using Encapsulation
n C# and Object Orientation
n Defining Object-Oriented Systems
1. Explain the concept of abstraction and why it is important in software
engineering.
2. What are the two principles of encapsulation?
Module 7: Essentials of Object-Oriented Programming 63
3. Describe inheritance in the context of object-oriented programming.
4. What is polymorphism? How is it related to early and late binding?
5. Describe the differences between interfaces, abstract classes, and concrete
classes.
THIS PAGE INTENTIONALLY LEFT BLANK

使用道具 举报

回复
论坛徽章:
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
89#
 楼主| 发表于 2006-8-13 21:30 | 只看该作者
Contents
Overview 1
Using Reference -Type Variables 2
Using Common Reference Types 15
The Object Hierarchy 23
Namespaces in the .NET Framework 29
Lab 8.1: Defining And Using Reference -
Variables 35
Data Conversions 43
Multimedia: Type-Safe Casting 56
Lab 8.2 Converting Data 57
Review 63
Module 8: Using
Reference-Type Variables
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 C#, 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.
Module 8: Using Reference-Type Variables 1
Overview
n Using Reference-Type Variables
n Using Common Reference Types
n The Object Hierarchy
n Namespaces in the .NET Framework
n Data Conversions
In this module, you will learn how to use reference types in C#. You will learn
about a number of reference types, such as string, that are built into the C#
language and run-time environment. These are discussed as examples of
reference types.
You will also learn about the C# object hierarchy and the object type in
particular, so you can understand how the various reference types are related to
each other and to the value types. You will learn how to convert data between
reference types by using explicit and implicit conversions. You will also learn
how boxing and unboxing conversions convert data between reference types
and value types.
After completing this module, you will be able to:
n Describe the important differences between reference types and value types.
n Use common reference types, such as string.
n Explain how the object type works and become familiar with the methods it
supplies.
n Describe common namespaces in the Microsoft? .NET Framework.
n Determine whether different types and objects are compatible.
n Explicitly and implicitly convert data types between reference types.
n Perform boxing and unboxing conversions between reference and value data.
2 Module 8: Using Reference-Type Variables
u Using Reference-Type Variables
n Comparing Value Types to Reference Types
n Declaring and Releasing Reference Variables
n Invalid References
n Comparing Values and Comparing References
n Multiple References to the Same Object
n Using References as Method Parameters
Reference types are important features of the C# language. They enable you to
write complex and powerful applications and effectively use the run-time
framework.
In this section, you will learn about reference-type variables and about how
they are different from value-type variables. You will learn how to use and
discard reference variables. You will also learn how to pass reference types as
method parameters.
Module 8: Using Reference-Type Variables 3
Comparing Value Types to Reference Types
n Value Types
l The variable
contains the
value directly
l Examples:
char, int
4422
int mol;
mol = 42;
int mol;
mol = 42; ??
string mol;
mol = "Hello";
string mol;
mol = "Hello";
HHeelllloo
n Reference Types
l The variable contains a
reference to the data
l Data is stored in a
separate memory area
C# supports basic data types such as int, long and bool. These types are also
referred to as value types. C# also supports more complex and powerful data
types known as reference types.
Value Types
Value-type variables are the basic built- in data types such as char and int. Value
types are the simplest types in C#. Variables of value type directly contain their
data in the variable.
Reference Types
Reference-type variables contain a reference to the data, not the data itself. The
data itself is stored in a separate memory area.
You have already used several reference types in this course so far, perhaps
without realizing it. Arrays, strings, and exceptions are all reference types that
are built into the C# compiler and the .NET Framework. Classes, both built-in
and user-defined, are also a kind of reference type.

使用道具 举报

回复
论坛徽章:
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
90#
 楼主| 发表于 2006-8-13 21:30 | 只看该作者
4 Module 8: Using Reference-Type Variables
Declaring and Releasing Reference Variables
n Declaring Reference Variables
coordinate c1;
c1 = new coordinate();
c1.x = 6.12;
c1.y = 4.2;
coordinate c1;
c1 = new coordinate();
c1.x = 6.12;
c1.y = 4.2;
?? 66..1122 44..22
cc11 == nnuullll;;
?? 66.1.122 44..22
n Releasing Reference Variables
To use reference-type variables, you need to know how to declare and initialize
them and how to release them.
Declaring Reference Variables
You declare reference-type variables by using the same syntax that you use
when declaring value-type variables:
coordinate c1;
The preceding example declares a variable c1 that can hold a reference to an
object of type coordinate. However, this variable is not initialized to reference
any coordinate objects.
To initialize a coordinate object, use the new operator. This creates a new
object and returns an object reference that can be stored in the reference
variable.
coordinate c1;
c1 = new coordinate( );
If you prefer, you can combine the new operator with the variable declaration
so that the variable is declared and initialized in one statement, as follows:
coordinate c1 = new coordinate( );
After you have created an object in memory to which c1 refers, you can then
reference member variables of that object by using the dot operator as shown in
the following example:
c1.x = 6.12;
c1.y = 4.2;
Module 8: Using Reference-Type Variables 5
Example of Declaring Reference Variables
Classes are reference types. The following example shows how to declare a
user -defined class called coordinate. For simplicity, this class has only two
public member variables: x and y.
class coordinate
{
public double x = 0.0;
public double y = 0.0;
}
This simple class will be used in later examples to demonstrate how reference
variables can be created, used, and destroyed.
Releasing Reference Variables
After you assign a reference to a new object, the reference variable will
continue to reference the object until it is assigned to refer to a different object.
C# defines a special value called null. A reference variable contains null when
it does not refer to any valid object. To release a reference, you can explicitly
assign the value null to a reference variable (or simply allow the reference to go
out of scope).
6 Module 8: Using Reference-Type Variables
Invalid References
n If You Have Invalid References
l You cannot access members or variables
n Invalid References at Compile Time
l Compiler detects use of uninitialized references
n Invalid References at Run Time
l System will generate an exception error
You can only access the members of an object through a reference variable if
the reference variable has been initialized to point to a valid reference. If a
reference is not valid, you cannot access member variables or methods.
The compiler can detect this problem in some cases. In other cases, the problem
must be detected and handled at run time.
Invalid References at Compile Time
The compiler is able to detect situations in which a reference variable is not
initialized prior to use.
For example, if a coordinate variable is declared but not assigned, you will
receive an error message similar to the following: “Use of unassigned local
variable c1.” The following code provides an example:
coordinate c1;
c1.x = 6.12; // Will fail: variable not assigned
Module 8: Using Reference-Type Variables 7
Invalid References at Run Time
In general, it is not possible to determine at compile time when a variable
reference is not valid. Therefore, C# will check the value of a reference variable
before it is used, to ensure that it is not null.
If you try to use a reference variable that has the value null, the run-time system
will throw a NullReferenceException exception. If you want, you can check
for this condition by using try and catch. The following is an example:
try {
c1.x = 45;
}
catch (NullReferenceException) {
Console.WriteLine("c1 has a null value";
}
Alternatively, you can check for null explicitly, thereby avoiding exceptions.
The following example shows how to check that a reference variable contains a
non-null reference before trying to access its members:
if (c1 != null)
c1.x = 45;
else
Console.WriteLine("c1 has a null value";

使用道具 举报

回复

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

本版积分规则 发表回复

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