Вы находитесь на странице: 1из 30


IObject oriented aspects of C#

Classes and objects .

Classes At the heart of object oriented programming Application structure mirrors real world objects Related methods and data encapsulated in object Objects with the same structure are of same type A class is a blueprint for all things of that type Instance of a class is a thing, an object Classes have three main types of members Methods (functions in other languages) Fields (the data, sometimes called member variables) Properties (accessed like fields, but actually methods

Basic Principles of OOP

OOP is about objects collaborating It is NOT a series of subroutines or functions or tasks bound together. Objects send and receive messages

What is an Object?
An object is a self-contained piece of functionality that can be easily used, and reused as the building blocks for a software application. Objects consist of data variables and functions (called methods) that can be accessed and called on the object to perform tasks. These are collectively referred to as members.

What is a Class? .
Much as a blueprint or architect's drawing defines what an item or a building will look like once it has been constructed, a class defines what an object will look like when it is created. It defines, for example, what the methods will do and what the member variables will be. .

Declaring a C# Class
Before an object can be instantiated we first need to define the class 'blueprint' for the object. In this chapter we will create a Bank Account class to demonstrate the concepts of C# object oriented programming. A C# class is declared using the public class keywords followed by the name of the class. Although the C# compiler will accept just about any name for a class, programming convention dictates that a class name begin with a capital letter:

public class BankAccount


We have now defined a class which currently contains no members. The next task, therefore, is to add some members.

Creating C# Class Members

Class members or properties are essentially variables and methods embedded into the class. Members can be public, private or protected. public members can be accessed from outside the object and are also visible in classes derived from the current class. private members can only be accessed by methods contained in the class and are not accessible to derived classes. protected classes are only available to derived classes. This is the key to what is called data encapsulation. Object-oriented programming convention dictates that data should be encapsulated in the class and accessed and set only through the methods of the class (typically called getters and setters). We can now extend our BankAccount class to add member variables to hold the account name and number. True to the concept of data encapsulation we will be making some of these members private and writing methods to access these values later: ). public class BankAccount { public string accountName; public int accountFee; private int accountBalance; private int accountNumber; }

Static, Read-only and Const Data Members

In addition the data member types we have looked at so far, C# also provides support for a number of additional member types. C# static member types (also referred to as class properties) are used to store data values which are common to all object instances of class. For example, all bank customers would likely earn the same rate of interest on a savings account. An interestRate member would, therefore, be declared as static since it is common across all object instances of the class. Static members are declared using the static keyword. For example:

public class BankAccount { public static int interestRate; }

Instantiating an Object from a C# Class

The process of creating an object from the class 'blueprint' is called instantiation. The first step is to create an object variable of the required object type. An instance of the object is then created using the new keyword and assigned to the object variable: BankAccount custAccount; custAccount = new BankAccount(); It is also possible to declare the object variable and assign the object in a single statement: BankAccount custAccount = new BankAccount();

Accessing C# Object Members

Now that we know how to write a class and instantiate objects from the class, we now need to know how to access the members of the object. Firstly, you will recall that we declared some members as being public and others as being private. The public methods are fully accessible from outside the object. This is achieved using something called dot notation. Dot notation is a mechanism by which object members may be accessed by specifying the object and member names separated by a dot (.). For example, to access the accountName member of an object named custAccount we would reference this member using custAccount.accountName:

using System; class Hello { public class BankAccount { public string accountName; public int accountFee; private int accountBalance; private int accountNumber; } static void Main() { BankAccount custAccount = new BankAccount(); custAccount.accountName = "John Smith"; custAccount.accountFee = 5; Console.WriteLine ("Customer Name is " + custAccount.accountName); Console.WriteLine ("Account Fee = $" + custAccount.accountFee); } }
The above code assigns values to the accountName and accountFee members Our object. It then references the properties in order to display text which reads:

Adding Methods to a C# Class

Class method members are sections of code contained in a class which can be called from outside an object to perform specific tasks. Common types of methods are getter and setter methods which are used to access private data members of a class. For example, we can declare a getter and a setter method to get and set the protected accountNumber member:
public class BankAccount { public string accountName; public int accountFee; private int accountBalance; private int accountNumber; public int getAccountNumber() { return accountNumber; } public void setAccountNumber(int newNumber) { accountNumber = newNumber; } }

Class methods are called using dot notation. For example, to set the value of the accountNumber:
BankAccount custAccount = new bankAccount(); custAccount.setAccountNumber( 12345 ); Console.WriteLine ("Account Number = " + custAccount.getAccountNumber() ); The above code sets the account number using the setter method and then displays the account number using the getter method.

C# Constructors and Finalizers

Despite the grand sounding names, C# class constructors and finalizers are nothing more than methods which get called when an object is instantiated and destroyed. The constructor is particularly useful for allowing initialization values to be passed through to an object at creation time. Let's say that we would like to be able to initialize the accountName and accountNumber members at the point that we initialize the custAccount object. To do so we need to declare a constructor. Constructors are declared the same way as other methods with the exception that the name of the method must match the class name: We can now use the constructor to initialize these members at object creation:
public class BankAccount { public string accountName; public int accountFee; private int accountBalance; private int accountNumber; // Constructor public BankAccount(string acctName, int acctNumber) { accountName = acctName; accountNumber = acctNumber; } // .... }
BankAccount custAccount = new BankAccount("Fred Wilson", 123456);

Finalizers are used to clean up any resources used by a class object when the object is destroyed. Unlike constructors which can be triggered from code using the new keyword there is no way to explicitly call a finalizer (for example there is no delete equivalent to the new keyword). Instead, the finalizer will be called when the garbage collector decides that the object instance is no longer needed. All the programmer can be sure of is that the finalizer will be called at some time between the when the object is no longer needed by the code and the point that the application terminates. Finalizers are defined in the same way as constructors with the exception that the name is preceded by a tilde (~):

// Finalizer public ~BankAccount(string acctName, int acctNumber) { // Code to perform clean up }

CLR via C#, Jeffrey Richter

What is Inheritance?
The concept of inheritance brings something of a realworld view to programming. It allows a class to be defined which has a number of characteristics and then other classes to be created which are derived from that class. The derived class inherits all of the features of the parent class and typically then adds some features of its own. By deriving classes we create what is often referred to as a class hierarchy. The class at the top of the hierarchy is known as the base class and the derived classes as subclasses. Any number of classes may be derived from a class. It is only possible for a derived class to inherit from one class. As such, C# is known as a single inheritance programming language. Classes need not only be derived from a base class. For example, a subclass can also inherit from another subclass.

An Example of Inheritance
public class BankAccount { public string accountName; public int accountFee; private int accountBalance; private int accountNumber; public int getAccountNumber() { return accountNumber; } public void setAccountNumber(int newNumber) { accountNumber = newNumber; } }
This class does a good job of defining characteristics common to any type of bank account, such as account holder name, account number and current balance. Imagine, however, that our banking program needs to support a number of specific types of account. For example, the bank might offer its customers an interest bearing savings account. A savings account will have all the characteristics of our BankAccount class but would also need a way to store the prevailing interest rate. One option would be to create a brand new class from the ground up called SavingsAccount which duplicates everything we have in our BankAccount class, plus extra members needed for a savings account. Another, more efficient method is to derive a SavingsAccount class from the BankAccount class and then add in the extra functionality into this subclass.

Creating a Subclass in C#
Now that we have ascertained that we need to create a sub class of our BankAccount class we can take a look at the code necessary to achieve this. Subclasses are declared in the same way as any other class with the exception that the class name is followed by a colon (:) followed by the name of the class from which it is to inherit. With this in mind we can begin by creating our SavingsAccount class:
public class BankAccount { public string accountName; public int accountBalance; public int accountNumber; public BankAccount (string name, int number) { accountName = name; accountNumber = number; } public int getAccountNumber() { return accountNumber; } public void setAccountNumber(int newNumber) { accountNumber = newNumber; } } public class SavingsAccount : BankAccount { } { }

Passing Arguments to the Base Class Constructor

Of particular significance is the constructor. In the BankAccount base class we have a constructor which takes the account name and account number as arguments. In the SavingsAccount subclass we need to accept two additional arguments - the balance and the interest rate. The : base code instructs C# to handle the name and number arguments using the constructor from the base class. The remaining two arguments are then passed to the SavingsAccount constructor. With our subclass complete we can now make use of it:
static void Main() { SavingsAccount saveAccount = new SavingsAccount("Fred Wilson", 123456, 432, 0.02F); Console.WriteLine ("Interest this Month = " + saveAccount.monthlyInterest() ); }

Polymorphism Polymorphism is the ability for classes to provide different implementations of methods that are called by the same name. Polymorphism allows a method of a class to be called without regard to what specific implementation it provides.

Method overriding
Virtual and Override keywords allows you to implement Methods Overriding in Base and Derived Classes. Different implementations of a method with the same name and signature in the base and sub-classes is called as Polymorphism.
Sample code

The New Keyword

C# introduces a keyword new to mark a method as a nonoverriding method and as the one which we don't want to use polymorphically.

is and as keyword
To check the run-time type of an object, you can use either is or as keyword. is compares the type of the object with the given type and returns true if it is cast-able otherwise, it returns false.




Operator overloading
All unary and binary operators have pre-defined implementations, that are automatically available in any expressions. In addition to this pre-defined implementations, user defined implementations can also be introduced in C#. The mechanism of giving a special meaning to a standard C# operator with respect to a user defined data type such as classes or structures is known as operator overloading. Remember that it is not possible to overload all operators in C#. The following table shows the operators and their overloadability in C#.

Operator overloading
Operators Overloadability +, -, *, /, %, &, |, <<, >> All C# binary operators can be overloaded. +, -, !, ~, ++, --, true, false All C# unary operators can be overloaded. ==, !=, <, >, <= , >= All relational operators can be overloaded, but only as pairs. &&, || They can't be overloaded () (Conversion operator) They can't be overloaded +=, -=, *=, /=, %= These compound assignment operators can be overloaded. But in C#, these operators are automatically overloaded when the respective binary operator is overloaded. =, . , ?:, ->, new, is, as, sizeof These operators can't be overloaded

Delegates and Events

A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked. The Event model in C# finds its roots in the event programming model that is popular in asynchronous programming. The basic foundation behind this programming model is the idea of "publisher and subscribers." In this model, you have publishers who will do some logic and publish an "event." Publishers will then send out their event only to subscribers who have subscribed to receive the specific event. In C#, any object can publish a set of events to which other applications can subscribe. When the publishing class raises an event, all the subscribed applications are notified. The following figure shows this mechanism.

Errors and Exceptions

The C# language's exception handling features provide a way to deal with any unexpected or exceptional situations that arise while a program is running. Exception handling uses the try, catch, and finally keywords to attempt actions that may not succeed, to handle failures, and to clean up resources afterwards. Exceptions can be generated by the common language runtime (CLR), by third-party libraries, or by the application code using the throw keyword. In this example, a method tests for a division by zero, and catches the error. Without the exception handling, this program would terminate with a DivideByZeroException was unhandled error.

int SafeDivision(int x, int y) { try { return (x / y); } catch ( (System.DivideByZeroException dbz) { System.Console.WriteLine("Division by zero attempted!"); return 0; } }