Overloading Methods and Constructors When a method is overloaded, a component contains two methods with exactly the same name.. For example, the ProductConstructor class in Listing 17.13
Trang 1LISTING 17.11 Quote.cs
using System;
using System.Collections.Generic;
public class Quote
{
private List<string> _quotes = new List<string>();
public string GetQuote()
{
Random rnd = new Random();
return _quotes[rnd.Next(_quotes.Count)];
}
public Quote()
{
_quotes.Add(“All paid jobs absorb and degrade the mind Aristotle”);
_quotes.Add(“No evil can happen to a good man, either in life or after
death Plato”);
_quotes.Add(“The only good is knowledge and the only evil is ignorance
Plato”);
}
}
The collection named _quotes is declared in the body of the class That way, you can refer
to the _quotes field in both the constructor and the GetQuote() method
NOTE
You can create static constructors by using the static keyword when declaring a
con-structor A static constructor is called once before any instance constructors
Overloading Methods and Constructors
When a method is overloaded, a component contains two methods with exactly the same
name Many methods in NET Framework are overloaded, including
String.Replace(),Random.Next(), and Page.FindControl()
For example, here is a list of the three overloaded versions of the Random.Next() method:
Next()—Returns a random number between 0 and 2,147,483,647
Next(upperbound)—Returns a number between 0 and the upper bound
Next(lowerbound, upperbound)—Returns a number between the lower bound and
the upper bound
Trang 2Because all three methods do the same thing—they all return a random number—it makes
sense to overload the Next() method The methods differ only in their signatures A
method signature consists of the order and type of parameters that a method accepts For
example, you can’t overload two methods that have exactly the same set of parameters
(even if the names of the parameters differ)
Overloading is useful when you want to associate related methods Overloading is also
useful when you want to provide default values for parameters For example, the
StoreProduct component in Listing 17.12 contains three overloaded versions of its
SaveProduct() method
LISTING 17.12 StoreProduct.cs
using System;
public class StoreProduct
{
public void SaveProduct(string name)
{
SaveProduct(name, 0, String.Empty);
}
public void SaveProduct(string name, decimal price)
{
SaveProduct(name, price, String.Empty);
}
public void SaveProduct(string name, decimal price, string description)
{
// Save name, price, description to database
}
}
You can call any of the three SaveProduct() methods in Listing 17.12 to save a new
product You can supply the new product with a name, a name and a price, or a name, a
price, and a description
VISUAL WEB DEVELOPER NOTE
When typing an overloaded method in Source view, the Intellisense pops up with all
the different sets of parameters that you can use with the overloaded method (see
Figure 17.4)
Trang 3Because a constructor is just a special method, you also can use overloading when declaring
constructors for a class For example, the ProductConstructor class in Listing 17.13
contains three overloaded constructors that can be used to initialize the Product class
LISTING 17.13 ProductConstructor.cs
using System;
public class ProductConstructor
{
public ProductConstructor(string name)
: this(name, 0, String.Empty) { }
public ProductConstructor(string name, decimal price)
: this(name, price, String.Empty) { }
public ProductConstructor(string name, decimal price, string description)
{
// Use name, price, and description
}
}
When you instantiate the component in Listing 17.13, you can instantiate it in any of the
following ways:
ProductConstructor objProduct = new ProductConstructor(“Milk”);
ProductConstructor objProduct = new ProductConstructor(“Milk”, 2.99d);
ProductConstructor objProduct = new ProductConstructor(“Milk”, 2.99d, “While Milk”);
Declaring Namespaces
A namespace enables you to group logically related classes You are not required to
provide a class with a namespace To this point, all the components you have seen created
FIGURE 17.4 Typing an overloaded method in Visual Web Developer
Trang 4have been members of the global namespace However, several advantages result from
grouping components into namespaces
First, namespaces prevent naming collisions If two companies produce a component with
the same name, namespaces provide you with a method of distinguishing the components
Second, namespaces make it easier to understand the purpose of a class If you group all
your data access components into a DataAccess namespace and all your business logic
components in a BusinessLogic namespace, you can immediately understand the function
of a particular class
In an ASP.NET page, you import a namespace like this:
<%@ Import Namespace=”System.Collections” %>
In a C# component, on the other hand, you import a namespace like this:
using System.Collections;
You can create your own custom namespaces and group your components into
name-spaces by using the namespace statement For example, the component in Listing 17.14 is
contained in the AspUnleashed.SampleCode namespace
LISTING 17.14 Namespaced.cs
namespace AspNetUnleashed.SampleCode
{
public class Namespaced
{
public string SaySomething()
{
return “Something”;
}
}
}
The file in Listing 17.14 uses the Namespace statement to group the Namespaced
compo-nent into the AspUnleashed.SampleCode namespace Components in different files can
share the same namespace, and different components in the same file can occupy
differ-ent namespaces
The periods in a namespace name have no special significance The periods are used to
break up the words in the namespace, but you could use another character, such as an
underscore character, instead
Microsoft recommends a certain naming convention when creating namespaces:
CompanyName.TechnologyName[.Feature][.Design]
Trang 5So, if your company is named Acme Consulting and you are building a data access
component, you might add your component to the following namespace:
AcmeConsulting.DataAccess
Of course this is simply a naming convention No serious harm will come to you if you
ignore it
Creating Partial Classes
You can define a single component that spans multiple files by taking advantage of a
feature of NET Framework called partial classes.
For example, the files in Listings 17.15 and 17.16 contain two halves of the same
component
LISTING 17.15 FirstHalf.cs
public partial class Tweedle
{
private string _message = @”THEY were standing under a tree,
each with an arm round the other’s neck, and Alice knew
which was which in a moment, because one of them had
““DUM”” embroidered on his collar, and the other ““DEE””.”;
}
LISTING 17.16 SecondHalf.cs
public partial class Tweedle
{
public string GetMessage()
{
return _message;
}
}
The private _message field is defined in the first file, but this private field is used in the
GetMessage() method in the second file When the GetMessage() method is called, it
returns the value of the private field from the other class Both files define a class with the
same name The class declaration includes the keyword Partial, which marks the classes
as partial classes
Trang 6NOTE
Partial classes are the basis for code-behind pages in the ASP.NET Framework The
code-behind file and the presentation page are two partial classes that get compiled
into the same class
Inheritance and Abstract Classes
When one class inherits from a second class, the inherited class automatically includes all
the nonprivate methods and properties of its parent class In other words, what’s true of
the parent is true of the child, but not the other way around
Inheritance is used throughout NET Framework For example, every ASP.NET page
inher-its from the base System.Web.UI.Page class The only reason that you can use properties
such as the IsPostback property in an ASP.NET page is that the page derives from the base
Page class
All classes in NET Framework derive from the base System.Object class The Object class is
the great-grandmother of every other class This means that any methods or properties of
the Object class, such as the ToString() method, are shared by all classes in the Framework
You can take advantage of inheritance when building your own components You indicate
that one class inherits from a second class when you declare a class For example, the file
in Listing 17.17 includes three components: a BaseProduct class, a ComputerProduct class,
and a TelevisionProduct class
LISTING 17.17 Inheritance.cs
public class BaseProduct
{
private decimal _price;
public decimal Price
{
get { return _price; }
set { _price = value; }
}
}
public class ComputerProduct : BaseProduct
{
private string _processor;
public string Processor
{
get { return _processor; }
Trang 7}
}
public class TelevisionProduct : BaseProduct
{
private bool _isHDTV;
public bool IsHDTV
{
get { return _isHDTV; }
set { _isHDTV = value; }
}
}
Both the ComputerProduct and TelevisionProduct components inherit from the
BaseProduct component Because the BaseProduct class includes a Price property, both
inherited components automatically inherit this property
When inheriting one class from another, you also can override methods and properties of
the base class Overriding a method or property is useful when you want to modify the
behavior of an existing class
To override a property or method of a base class, the property or method must be marked
with the C# virtual or abstract keyword or the Visual Basic NET Overridable or
MustOverride keyword Only methods or properties marked with the virtual or abstract
keyword can be overridden
For example, the file in Listing 17.18 contains two components: a ProductBase class and a
OnSaleProduct class The second class inherits from the first class and overrides its Price
property The Price property of the OnSaleProduct component divides the price by half
LISTING 17.18 OnSaleProduct.cs
public class ProductBase
{
private decimal _price;
public virtual decimal Price
{
get { return _price; }
set { _price = value; }
}
}
Trang 8{
override public decimal Price
{
get { return base.Price / 2; }
set { base.Price = value; }
}
}
The base keyword (MyBase in Visual Basic) is used in Listing 17.18 to refer to the base class
(the ProductBase class)
Finally, you can use the abstract keyword when declaring a class to mark it as a class that
requires inheritance You cannot instantiate an abstract class To use an abstract class,
you must derive a new class from the abstract class and instantiate the derived class
Abstract classes are the foundation for the ASP.NET Provider Model Personalization,
Membership, Roles, Session State, and Site Maps all use the Provider Model For example,
the MembershipProvider class is the base class for all Membership Providers The
SqlMembershipProvider and ActiveDirectoryMembershipProvider classes both derive
from the base MembershipProvider class
NOTE
Chapter 27, “Using ASP.NET Membership,” discusses the MembershipProvider
class-es in detail, which is rclass-esponsible for saving and loading membership information such
as application usernames and passwords
The base MembershipProvider class is an abstract class You cannot use this class directly
in your code Instead, you must use one of its derived classes However, the base
MembershipProvider class provides a common set of methods and properties that all
MembershipProvider-derived classes inherit
The base MembershipProvider class includes a number of methods and properties marked
as abstract A derived MembershipProvider class is required to override these properties
and methods
The file in Listing 17.19 contains two components The first component, the
BaseEmployee component, is an abstract class that contains an abstract property named
Salary The second component, the SalesEmployee, inherits the BaseEmployee
compo-nent and overrides the Salary property
LISTING 17.19 Employees.cs
public abstract class BaseEmployee
{
public abstract decimal Salary
{
Trang 9}
public string Company
{
get { return “Acme Software”; }
}
}
public class SalesEmployee : BaseEmployee
{
public override decimal Salary
{
get { return 67000.23m; }
}
}
Declaring Interfaces
An interface is a list of properties and methods that a class must implement If a class
implements an interface, you know that the class includes all the properties and methods
contained in the interface
For example, the file in Listing 17.20 contains an interface named IProduct and two
components named MusicProduct and BookProduct
LISTING 17.20 Products.cs
public interface IProduct
{
decimal Price
{
get;
}
void SaveProduct();
}
public class MusicProduct : IProduct
{
public decimal Price
{
get { return 12.99m; }
}
Trang 10public void SaveProduct()
{
// Save Music Product
}
}
public class BookProduct : IProduct
{
public decimal Price
{
get { return 23.99m; }
}
public void SaveProduct()
{
// Save Book Product
}
}
Both components in Listing 17.17 are declared as implementing the IProduct interface
(The colon can mean implements or inherits.) Furthermore, both components include the
SaveProduct() method and the Price property Both components are required to have
this method and property because they are declared as implementing the IProduct
interface
Interfaces are similar to abstract classes with two important differences First, a
compo-nent can inherit from only one class On the other hand, a compocompo-nent can implement
many different interfaces
Second, an abstract class can contain application logic You can add methods to an
abstract class that all derived classes inherit and can use An interface, on the other
hand, cannot contain any logic An interface is nothing more than a list of methods and
properties
Using Access Modifiers
C# supports the following access modifiers, which you can use when declaring a class,
method, or property:
Public—A public class, method, or property has no access restrictions.
Protected—A protected method or property can be accessed only within the class
itself or a derived class