Monday, July 7, 2008

1) An Introduction to Designing Classes in C# - Pt.3

Programming Language: C#
Type: Tutorial
Level: Beginners
Topic Category: General Programming
Main Series:
Designing and Implementing Classes in C#
Topic Title: 1) An Introduction to Designing Classes in C# - Pt.3

Quick Review:
In part 1 of this article, we discussed classes and how to design them. We established what classes are and what they are used for and what they consist of. In part 2, we introduced the general syntax for defining classes in C# and discussed the first part of the declaration: access modifiers. In this article, we will continue discussing the declaration of classes and will introduce the different types of members of classes.

Remind me again how to declare a class in C#!
Here's a small reminder:
access-modifier [static|abstract|sealed] class class-name [: [parentClass][, implementedInterface]*]

Oh yes, I remember now. So we stopped at access modifiers. What are these three other words (static, sealed and abstract)?
I'll introduce each of these modifiers briefly. However, the concepts behind them depend on other concepts we have not discussed yet such as inheritance, polymorphism and scope.
We start with the scope modifier, static.
Static Classes
Classes are usually defined so that we can declare objects of them later. In some cases however, we only need to declare one object of the class, no more no less. For example, if we want to define a class from which we will declare an object that describes the monitor of the system, the memory of the system, the cpu of the system or perhaps, the company for which we are developing the software. Classes like that are called singleton classes. Simply, one use of static classes is to represent these classes. Static, in C#, is usually used to describe members. It means in some way: "belonging to the class itself and not to any specific object of the class". For example, if we are defining a Point class, representing geometrical point objects, we might want to run the code in one of two modes: Cartesian and polar coordinates. The fact that "points" are expressed in either format, is irrelevant to any specific "point". In fact, it affects "all" points. That's a member that belongs to the class of points as a whole not to objects of the class. Now, static classes, are by definition in C# classes with all members being static. Meaning all members of a static class has to be declared static, which in turn means they belong to the class itself. By this, we can think of the class itself as being the only object declared. Static classes are also used to group a set of methods and properties that are related by task but not belonging to any specific object. For example, a set of methods that compare/convert objects of different types in some application are all related by task, but they do not belong to a specific object as they will always behave the same no matter what object they are in (or are not in for that matter). These members are all grouped as static members of a static class. Now we discuss the second modifier: abstract
Abstract classes:
Abstract classes are used when building hierarchies of classes that are related. To fully understand this modifier, you must be familiar with inheritance and polymorphism, so I will only say, they are classes with at least one abstract member. We will discuss abstract members immediatly after inheritance. That leaves us with only one modifier: sealed
Sealed classes:
Sealed classes are simply classes that do not allow any other class to inherit from them. Again, you must be familiar with the concept of inheritance to fully understand sealed classes, and they will be revisited in inheritance
Fair enough. So, can I learn to declare my first class now, or do I have to learn inheritance first?
Actually, it will be nearly impossible and in vain to learn inhertance when you don't know how to declare members. Also, except for an empty class, classes will usually need you declare one or more members. So let's start by a brief introduction about the syntax of these members and then writing the first class?
Types of Class Members:
Classes at most, consist of Fields, Methods, Properties, Events and Nested Types. Following is a brief description of each one:
Nested Types: These are simply types nested within other types. In other words, they are types that are defined within another type. They are used when a major type needs to gather a set of information to be used only by that type. For example, a software that interacts with a hardware device might need a structure to hold the settings of the device not as seen by a high level user, but after converting them to the complex and more detailed binary values that will actually be sent to the device. Nesting types within each other is usually seen in large software libraries development to emphasize a type is only declared for the use of another type only. You nest types simply by declaring the nested type/class within the scope boundaries of the nesting class as you would normally declare any class:
class PrinterDriver {
    class hardwarePageSettings{
    }
}
Fields: fields can be thought of as being the data storage slots of the class. Fields are data (informational) members that do actually store the object's data (unlike properties). In other words, if a class having a field called "length", is used to declare objects, all objects of this class will have its own "length". That's of course if the field is not static. As we mentioned earlier, static members belong to the class, meaning only one copy of the member will be available at anytime regardless of the objects declared from that class. Well, fields are no exception! Also, we mentioned earlier that members have access modifiers. Being a data storage, you must also provide the type of data that will be stored. According to this, the simplest good field declaration will look something like:
public class MailPackage{
    public int width;
    public int height;
    public int depth;
}
Methods: are used to represent the operational attributes of a class. They can be thought of as being blocks of code that takes inputs, makes some processing and return an output. The fields of the class (and the values of these fields in object of the class) are always available to the methods in the class to read and modify. The last feature eleminates the need for long parameters list in methods. Inputs are given to the method in the form of parameters (some methods take no inputs and so have no parameters). Each parameter is defined by a data type and an alias to be used by the moethod to distinguish it from other parameters. Parameters can be passed by value (default behavior), by reference (ref parameters) and as output parameters (out parameters). C# also supports variable length parameters lists (params arguments). Here's a sample method that will take an integer and calculates its square:
public class IntegerCalculations{
    public int Squared( int x){
        return x*x;
    }
}
Properties: are fake fields, or at least, that what they look like to C++ programmers! You use a property just like you would use a field in code. However, when declared, a property is actually two methods! One is used to get the value of the fake field and an optional one that will set that value. You usually use properties for the following purposes:
  1. To act like proxies for you fields. That is, you declare private fiields and create a public property for each field that will return and set its value. This is a common practice amongst programmers because it gives you the opportunity to modify the way a field is retrieved if it was needed or may be call some method everytime the field is written to.
  2. To declare calculated fields. These are fields that do not actually need to be stored because they can be inferred/calculated from other fields in the object. An example would be the area of a circle object which can be calculated from its radius.
  3. To make a field read-only for users of the class and still be able to write to it within the class. This is done by only defining the get method of the property
An example of properties is shown below where CenterX, CenterY and Radius are accessor (proxy) properties and Area is a calculated read only property:
public class Circle{
    private double x,y,r;
    public double CenterX{get{return x;}set{x = value;}}
    public double CenterY{get{return y;}set{y = value;}}
    public double Radius{get{return r;}set{r = value;}}
    public double Area{get{return Math.PI*r*r;}}
}
Events: wil actually be fully discussed in depth along with delegates in a coming article. In brief, they provide a means for other developers who will use your class to be notified when some event of interest occurs. This is done in a Publisher-Event-Subscriber model that works as follows:
  1. You publish an event by creating an event member in your class that will be accessible by subscribers
  2. Subscribers who are interested in the event will provide a method (or more) that should be executed when the event occurs. This is called "Attaching" "Handlers" to event, where handlers are the methods subscribers provide.
  3. Whenever the event occurs within your class, you find all methods attached to the event and execute them.
An example will be in the case where you want to notify develoeprs of a change in the radius of a circle, you will declare an event within the Circle class like this:
public event
EventHandler RadiusChanged;

Events are declared as if they were fields and their type must be a delegate.
Finally, Your First Class
Here we go, the first full class (well, not exactly full, but it will do). We will develop a Name class that is capable of holding the structured information of a person's name (First Name, MiddleName, LastName)
public class Name{
  //Private fields
  private string first, middle, last;
  private string prefix, suffix;
  //Public Accessor Properties
  public string First{get{return first;}set{first = value;}}
  public string Middle{get{return middle;}set{middle = value;}}
  public string Last{get{return last;}set{last = value;}}
  public string Prefix{get{return prefix;}set{prefix = value;}}
  public string Suffix{get{return suffix;}set{suffix = value;}}
  //Public Read-Only Calculated Properties
  public string Full{get{return last + ", " + first + " " + middle;}}
}

Now that you've written your first class, the following articles, will first tackle common basic types in C# and the .NET framework. The understanding of these fundamental types and some of there commonly used members is essential to writing any code. That concludes it for today's article.

No comments: