Beruflich Dokumente
Kultur Dokumente
Object oriented thinking :- Need for oop paradigm, A way of viewing world – Agents,
responsibility, messages, methods, classes and instances, class hierarchies (Inheritance),
method binding, overriding and exceptions, summary of oop concepts, coping with
complexity, abstraction mechanisms
One of the most important characteristics of OOP (Object Oriented Programming) is the
data encapsulation concept, which means that there is a very close attachment between
data items and procedures. The procedures (methods) are responsible for manipulating
the data in order to reflect its behaviour. The public interface, formed by the collections
of messages understood by an object, completely defines how to use this object.
Programs that want to manipulate an object, only have to be concerned about which
messages this object understands, and do not have to worry about how these tasks are
achieved nor the internal structure of the object. The hiding of internal details makes an
object abstract, and the technique is normally known as data abstraction. Normally,
objects of a given type are instances of a class, whose definition specifies the private
(internal) working of these objects as well as their public interface. Basically the creation
of an object is referred to as instantiation, and it consists of a class definition with
appropriate initial values.
Another powerful feature of OOP, is the concept of inheritance (derived classes in C++),
meaning the derivation of a similar or related object (the derived object) from a more
general based object. The derived class can inherit the properties of its base class and also
adds its own data and routines. The concept above is known as single inheritance, but it is
also possible to derive a class from several base classes, which is known as multiple
inheritance. Overloading, in OOP, means the ability to assign multiple meanings to the
names of operators and functions. For example, the operator +, normally associated with
arithmetic addition can be overloaded to add one list to another in a certain context.
Polymorphism means the sending of a message to an object without concern about how
the software is going to accomplish the task, and furthermore it means that the task can
be executed in completely different ways depending on the object that receives the
message (in C++, polymorphism is implemented through the use of virtual functions).
When the decision as to which actions are going to be executed is made at run-time, the
polymorphism is referred to as late binding (as in the case of virtual functions). If they
are made at compile time then it is known as early binding.
After this brief introduction, we now describe the major advantages of OOP.
Class Hierarchies
There is more information about Flora, not necessarily because she is a florist, but
because she is a shopkeeper. The knowledge of Flora is organized in terms of a hierarchy
of categories. Flora is a Florist, but Florist is a specialized form of Shopkeeper. A
Shopkeeper is a Human . . The principle that knowledge of a more general category is
also applicable to a more specific category is called inheritance. The class Florist will
inherit attributes of the class Shopkeeper.
CRC CARDS
• It is often useful, when you are designing an object-oriented application, to think about
the process as being similar to organizing a group of individuals, such as a club or
association. If any particular actions is to happen, somebody must be responsible for
doing it. No action takes place without an agent performing the action. One objective of
object-oriented design is first to establish who is responsible for each action that is to be
performed.
• One technique that is very useful is the use of index cards to represent individual
classes. Such cards are known as CRC card, since they are divided into three
components: class, responsibility, and collaboration.
• The purpose of the methodology is to provide a framework in which an initial set of
classes, their variables, and methods can be specified for a new application. The utility of
the method is the assistance it gives users in organizing their thoughts about how to
structure an application.
• This kind of decomposition is a first step in understanding how a problem can be
separated into parts.
CLASS
• The upper-left corner of each CRC card contains the name of the class being described.
The selection of meaningful names is extremely important, as the class name create the
vocabulary with which the design will be formulated. Shakespeare could claim that a
change in the name of an object will not alter the physical characteristics of the entity so
denoted, but it is certainly not the case that all names will conjure up the same mental
images to the listener.
• Names should be internally consistent, meaningful, preferably short, and evocative in
the context of the problem at hand.
RESPONSIBILITIES
• Immediately below the class name on the CRC card, the responsibilities of the class are
listed. Responsibilities describe the problem to be solved. They should be expressed by
short verb phrases, each containing an active verb.
• Responsibilities should describe what is to be done, and should avoid detailed
specifications of how each task is to be accomplished.
COLLABORATORS
• Few objects can perform useful operations entirely on their own. Almost all stand in
some relationship to several others, either as providers or as requesters of a service or
facility.
• The list of collaborators should include all classes of which the class being described
needs to be aware. It should certainly include classes that provide services needed to meet
the responsibilities of the class being described. It could also, but need not to, include
classes that require services provided by the described class.
• The decision whether to list another class as a collaborator is based on the degree of
connection or cooperation.
Ex: A special type of Window may be tied symmetrically to the data being displayed,
and thus would be considered a collaborator. Ex: A Stack may not care at all to whom it
is providing services, and thus need not list its caller as a collaborator (although the caller
should list the stack as a collaborator).
Discovering Classes
One of the first decisions that must be made in creating an OO application is the selection
of classes.
The following categories cover the majority of types of classes:
• Data Managers, Data, or State: These are classes whose principle responsibility is to
maintain data or state information. Ex: In a card game application the class Card will hold
the rank and the suit of the card.
• Data Sinks, Data Sources: Classes that generate data (random number generator), or
accept data and then process them further (class to perform output to disk or file). Unlike
the data managers they do not hold the data for any period of time, but generates it on
demand (for a data source), or processes it when called upon (for a data sink).
•View or Observer: An essential portion of most applications is the display of info on an
output device. Because the code for these activities is often complex, frequently
modified, and largely independent of the actual data being displayed, it is good
programming practice to isolate display behavior in separate classes form those classes
that maintain the data being displayed.
Ex: For the card application we may create CardView to take care of writing a card image
on a screen. Often the base data is called the model, and the display class the
view.Because we separate the object being viewed (model) from the view that displays
the visual representation of that object, the design of the model and the display system are
usually greatly simplified. Ideally, the model should neither require nor contain any info
about the view. This facilitates code reuse, since a model can then be used in several
different applications, or have more than one view.
• Facilitater or Helper: Classes that maintain little or no state info themselves but assist in
the execution of complex tasks. Ex: To display the card image we may use the services of
a class that handles the drawing of line and text on the display. Another facilitater
will help maintain linked lists of cards. These categories are intended to be representative
of the most uses of classes, and hence useful as a guide in the design phase of object-
oriented programming, but the list is certainly not complete. If a class appears to span
tow or more of these categories, it can often be broken into two or more classes.
Another Set of Class Categories
Tangible Things: easiest classes to discover because they are visible in the problem
domain.
System Interfaces and Devices: easy to discover by considering the system resources
and interactions of the system. Ex: DisplayWindow.
Agents: Sometimes it is helpful to change an operation into an agent class.
For example an InputReader class can be created to separate the operation of getting the
text which is used to construct a message by the Message class. The agent class
decouples the Message class from input mechanisms and separates the abstraction levels
of input processing and controlling message contents.
Events and Transactions: useful to model records of activities that describe what
happened in the past or what needs to be done later. For example, a CustomerArrival
class to specify when where what type of customer is scheduled to arrive. Ex:
MouseEvent
Users and Roles: stand-ins for actual users of the program. For example an
Administrator class is an interface to the human administrator of the system.
Systems: model a subsystem or the overall system being built. Their role are typically
to perform initialization and shutdown and to start the flow of input into the system.
Containers: used to store and retrieve information. Many are implemented using the
standard data structures (lists, queues, … ).
Designing From Scenarios
Designing with CRC cards follows neither the "top-down" nor the "bottomup" models of
software development. Instead, the design might be said to progress from the known to
the unknown. The design process should begin with only the most obvious classes, and
the classes necessary to handle the beginning of an application. The designer(s) then
proceed by playing "what if" - by simulating scenarios that illustrate expected use. The
CRC cards can play a concrete role in this simulation process.
Method Binding
Static binding is where the linker copies the referenced module into the executable image
of the program at compilation/link time. The referenced module becomes a part of the
executable image.
Dynamic binding is where the linker copies only a stub code for the referenced
module into the executable image. That stub code loads the referenced module into
memory at load/run time.
Advantage of static is simplicity. The executable is stand-alone. Disadvantage is
the executable image is larger, and if the referenced module changes, then each
executable that uses it must be relinked. Another disadvantage is that if you have more
than one executable using the module at the same time, you must have multiple copies of
it in memory.
Advantage of dynamic is reduced size of the executable image and that changing
the referenced module does not require relink of the executable. Another advantage is
that most operating systems can share the referenced module, meaning that only one copy
of the referenced module need exist in all of memory for any number of references to that
module, such as from multiple instances of the executable. Disadvantage of dynamic is
that the executable is dependent on the shared library at run time. Another disadvantage
is that, since the module is shared, it must be reentrant and thread safe, and this is not
always done correctly. It helps simplify your application by not having to determine
which type of object you have and which method is appropriate to call.
For example, one of my first OO applications maintained files on different media.
Each class was based on a basic archive class and had the same set of function: generate,
display, print, save, etc. There were derived classes for floppy, tape, CD, hard drive, etc.
From my application point of view I just had to worry about how to create the
initial object because initial input was different for each. But then for the user to
manipulate each of the archive sources my application didn't care. It would just call the
object's display method, the dynamic binding figured out which derived class was
responsible and then called that class' display function. So, all the class would display
their results in a list box. .
Overriding
Method overriding is using same method name along with same number & type of
arguements in base as well as derived class.This is called run time polymorphism asthe
instance i.e object type differntite between the methods.If not done properly then only
base class method will be invoked.so be carefull to bind object with method.
Method overriding is a language feature that allows a subclass to override a specific
implementation of a method that is already provided by one of its super-classes.
Overriding is an important concept in Object Oriented Technology. In today's world
you can't live without overriding. For example in most of the API's used for building
windows based application you always need to override some parent window. Like in
Java you may override methods and data of class Frame, in C++ CMainWnd, in QT
Form etc. In many of your applications that you build using Inheritance you need to
override some members of the parent class.
Let's understand inheritance by an analogous example. Let S be the son of F. There can
be many characteristics that C inherit from his/her father F. Like may be he also loves
listening to music and so does C, F is genius and so is C, F writes poems like C does.
These all are inherited characteristics. But there can be situation like C writes romantic
poems and his/her father used to write tragic poems. Here, C has overridden his/her
father's characteristics of writing a poem. It was inherited from his/her father but he/she
does it differently. The concept of overriding is same in Object Oriented Programming
Languages.
For overriding, there must be inheritance. Once you inherit, you can then override data
member of methods of the parent class. In C++ ":" is used to tell C++ compiler that you
want to inherit something. For example "Class MangoTree : public Tree " means class
MangoTree is inheriting class Tree.
The keyword public adds the information that only the public members are inherited.
Once class MangoTree inherits class Tree, all the public members of class Tree are
accessible from class MangoTree. Like is there is a data member "height" defined in class
"Tree" you can directly use this variable in any method of class "MangoTree". Similar is
the case with methods. But, sometimes you would like to change the implementation of
some of the methods of the parent class. Like though there was a method called,
"getFruitName()", you would write another method of the same name and parameter in
class "MangoTree". The method "getFruitName()" of parent class is not visible in child
class "MangoTree" now. It has its own now. It has overridden the method of its parent.
Similarly, it can also override the data member of its parent. This is what known as
overriding, a popular technique in object oriented paradigm.
A subclass can give its own definition of methods but need to have the same signature as
the method in its super-class. This means that when overriding a method the subclass's
method has to have the same name and parameter list as the super-class's overridden
method.
using System;
public class Complex
{
private int real;
public int Real
{ get { return real; } }
Exceptions
Introduction
Stated simply, the exception-handling capability of Java makes it possible for you to:
This is accomplished using the keywords: try, catch, throw, throws, and finally. The
basic concept is as follows:
• You try to execute the statements contained within a block of code. (A block of
code is a group of one or more statements surrounded by braces.)
• If you detect an exceptional condition within that block, you throw an
exception object of a specific type.
• You catch and process the exception object using code that you have designed.
• You optionally execute a block of code, designated by finally, which needs to
be executed whether or not an exception occurs. (Code in the finally block is
normally used to perform some type of cleanup.)
For example, the read method of the InputStream class throws an exception of type
IOException if an exception occurs while the read method is executing. In this case,
you are responsible only for the code in the catch block and optionally for the code in the
finally block.
(This is the reason that you must surround the invocation of System.in.read() with a try
block followed by a catch block, or optionally declare that your method throws an
exception of type IOException.)
Here is part of what Sun has to say about the Throwable class:
"The Throwable class is the superclass of all errors and exceptions in the Java language.
Only objects that are instances of this class (or one of its subclasses) are thrown by the
Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this
class or one of its subclasses can be the argument type in a catch clause."
"Instances of two subclasses, Error and Exception, are conventionally used to indicate
that exceptional situations have occurred. Typically, these instances are freshly created in
the context of the exceptional situation so as to include relevant information (such as
stack trace data)."
You may have concluded from the Sun quotation given above that you can define and
throw exception objects of your own design, and if you did, that is a correct conclusion.
(Your new class must extend Throwable or one of its subclasses.)
• Error
• Exception
What is an error?
"An Error is a subclass of Throwable that indicates serious problems that a reasonable
application should not try to catch. Most such errors are abnormal conditions."
For example, one of the subclasses of Error is named VirtualMachineError. This error
is "Thrown to indicate that the Java Virtual Machine is broken or has run out of resources
necessary for it to continue operating. "
What is an exception?
"The class Exception and its subclasses are a form of Throwable that indicates
conditions that a reasonable application might want to catch."
As of JDK 1.4.0, there are more than fifty known subclasses of the Exception class.
Many of these subclasses themselves have numerous subclasses, so there is quite a lot of
material that you need to become familiar with.
One subclass of Exception is the class named RuntimeException As of JDK 1.4.0, this
class has about 30 subclasses, many which are further subclassed. The class named
RuntimeException is a very important class.
Unchecked exceptions
The RuntimeException class, and its subclasses, are important not so much for what
they do, but for what they don't do. I will refer to exceptions instantiated from
RuntimeException and its subclasses as unchecked exceptions.
Basically, an unchecked exception is a type of exception that you can optionally handle,
or ignore. If you elect to ignore the possibility of an unchecked exception, and one
occurs, your program will terminate as a result. If you elect to handle an unchecked
exception and one occurs, the result will depend on the code that you have written to
handle the exception.
Checked exceptions
All exceptions instantiated from the Exception class, or from subclasses of Exception
other than RuntimeException and its subclasses must either be:
In other words, checked exceptions cannot be ignored when you write the code in your
methods. According to Flanagan, the exception classes in this category represent routine
abnormal conditions that should be anticipated and caught to prevent program
termination.
Your code must anticipate and either handle or declare checked exceptions. Otherwise,
your program won't compile. (These are exception types that are checked by the
compiler.)
As mentioned above, all errors and exceptions are subclasses of the Throwable class. As
of JDK 1.4.0, the Throwable class provides four constructors and about a dozen
methods. The four constructors are shown in Figure 1.
Throwable()
Throwable(String message)
Throwable(String message,
Throwable cause)
Throwable(Throwable cause)
Figure 1
The first two constructors have been in Java for a very long time. Basically, these two
constructors allow you to construct an exception object with, or without a String message
encapsulated in the object .
Abstraction mechanism
Abstraction is an emphasis on the idea, qualities and properties rather than the particulars
(a suppression of detail). The importance of abstraction is derived from its ability to hide
irrelevant details and from the use of names to reference objects. Abstraction is essential
in the construction of programs. It places the emphasis on what an object is or does rather
than how it is represented or how it works. Thus, it is the primary means of managing
complexity in large programs.
Abstraction and generalization are often used together. Abstracts are generalized through
parameterization to provide greater utility. In parameterization, one or more parts of an
entity are replaced with a name which is new to the entity. The name is used as a
parameter. When the parameterized abstract is invoked, it is invoked with a binding of
the parameter to an argument.
Abstract classes, which declared with the abstract keyword, cannot be instantiated. It can
only be used as a super-class for other classes that extend the abstract class. Abstract
class is the concept and implementation gets completed when it is being realized by a
subclass. In addition to this a class can inherit only from one abstract class (but a class
may implement many interfaces) and must override all its abstract methods/ properties
and may override virtual methods/ properties.
Abstract classes are ideal when implementing frameworks. As an example, let’s study the
abstract class named LoggerBase below. Please carefully read the comments as it will
help you to understand the reasoning behind this code.
/// <summary>
/// protected, so it only visible for inherited class
/// </summary>
protected LoggerBase()
{
// The private object is created inside the constructor
logger = log4net.LogManager.GetLogger(this.LogPrefix);
// The additional initialization is done immediately after
log4net.Config.DOMConfigurator.Configure();
}
/// <summary>
/// When you define the property as abstract,
/// it forces the inherited class to override the LogPrefix
/// So, with the help of this technique the log can be made,
/// inside the abstract class itself, irrespective of it origin.
/// If you study carefully you will find a reason for not to have “set” method here.
/// </summary>
protected abstract System.Type LogPrefix
{
get;
}
/// <summary>
/// Simple log method,
/// which is only visible for inherited classes
/// </summary>
/// <param name="message"></param>
protected void LogError(string message)
{
if (this.logger.IsErrorEnabled)
{
this.logger.Error(message);
}
}
/// <summary>
/// Public properties which exposes to inherited class
/// and all other classes that have access to inherited class
/// </summary>
public bool IsThisLogError
{
get
{
return this.logger.IsErrorEnabled;
}
}
}
The idea of having this class as an abstract is to define a framework for exception
logging. This class will allow all subclass to gain access to a common exception logging
module and will facilitate to easily replace the logging library. By the time you define the
LoggerBase, you wouldn’t have an idea about other modules of the system. But you do
have a concept in mind and that is, if a class is going to log an exception, they have to
inherit the LoggerBase. In other word the LoggerBase provide a framework for exception
logging.
Like any other class, an abstract class can contain fields, hence I used a private field
named logger declare the ILog interface of the famous log4net library. This will allow the
Loggerbase class to control, what to use, for logging, hence, will allow changing the
source logger library easily.
The access modifier of the constructor of the LoggerBase is protected. The public
constructor has no use when the class is of type abstract. The abstract classes are not
allowed to instantiate the class. So I went for the protected constructor.
The abstract property named LogPrefix is an important one. It enforces and guarantees to
have a value for LogPrefix (LogPrefix uses to obtain the detail of the source class, which
the exception has occurred) for every subclass, before they invoke a method to log an
error.
The method named LogError is protected, hence exposed to all subclasses. You are not
allowed or rather you cannot make it public, as any class, without inheriting the
LoggerBase cannot use it meaningfully.
Let’s find out why the property named IsThisLogError is public. It may be important/
useful for other associated classes of an inherited class to know whether the associated
member logs its errors or not.
Apart from these you can also have virtual methods defined in an abstract class. The
virtual method may have its default implementation, where a subclass can override it
when required.
All and all, the important factor here is that all OOP concepts should be used carefully
with reasons, you should be able to logically explain, why you make a property a public
or a field a private or a class an abstract. Additionally, when architecting frameworks, the
OOP concepts can be used to forcefully guide the system to be developed in the way
framework architect’s wanted it to be architected initially.