Object-oriented programs exhibit three main characteristics:
* Encapsulation
* Inheritance
* Polymorphism
We use these three concepts extensively as we attempt to model the real-world problems that we are trying to solve with our object-oriented programs. I will provide brief descriptions of these concepts in the remainder of this lesson and explain them in detail in future lessons.
Encapsulation example
Consider the steering mechanism of a car as a real-world example of encapsulation. During the past eighty years or so, the steering mechanism for the automobile has evolved into an object in the OOP sense.
Only the interface is exposed
In particular, most of us know how to use the steering mechanism of an automobile without having any idea whatsoever how it is implemented. All most of us care about is the interface, which we often refer to as a steering wheel. We know that if we turn the steering wheel clockwise, the car will turn to the right, and if we turn it counterclockwise, the car will turn to the left.
How is it implemented?
Most of us don't know, and don't really care, how the steering mechanism is actually implemented
"under the hood." In fact, there are probably a number of different implementations for various brands and models of automobiles. Regardless of the brand and model, however, the human interface is pretty much the same. Clockwise turns to the right, counterclockwise turns to the left.
As in the steering mechanism for a car, a common approach in OOP is to "hide the implementation"
and "expose the interface" through encapsulation.
Inheritance example
Another important aspect of OOP is inheritance. Let's form an analogy with the teenager who is building a hotrod. That teenager doesn't normally start with a large chunk of steel and carve an engine out of it. Rather, the teenager will usually start with an existing engine and make improvements to it.
In OOP lingo, that teenager extends the existing engine, derives from the existing engine, inherits from the existing engine, or subclasses the existing engine (depending on which author is describing the process).
Just like in "souping up" an engine for a hotrod, a very common practice in OOP is to create new improved objects by extending existing class definitions.
Reuse, don't reinvent
One of the major arguments in favor of OOP is that it provides a formal mechanism that encourages the reuse of existing programming elements. One of the mottos of OOP is "reuse, don't reinvent."
Polymorphism example
A third important aspect of OOP is polymorphism. This is a Greek word meaning something like one name, many forms . This is a little more difficult to explain in non-programming terminology. However, we will stretch our imagination a little and say that polymorphism is somewhat akin to the
automatic transmission in your car. In my Honda, for example, the automatic transmission has four different methods or functions known collectively as Drive(in addition to the functions of Reverse, Park, and Neutral).
Select Drive to go forward
As an operator of the automobile, I simply select Drive (meaning go forward). Depending on various conditions at runtime , the automatic transmission system decides which version of the Drive function to use in every specific situation. The specific version of the function that is used is based on the current conditions (speed, incline, etc.). This is somewhat analogous to what we will refer to in a subsequent tutorial lesson as runtime polymorphism.
In addition to the three explicit characteristics of encapsulation, inheritance, and polymorphism, an object-oriented program also has an implicit characteristic of abstraction.
What is abstraction?
Abstraction is the process by which we specify a new data type, often
referred to an abstract data type or ADT.
How does abstraction relate to encapsulation?
Encapsulation is the process of gathering an ADT's data representation and behavior into one encapsulated entity. In other words, encapsulation converts from the abstract to the concrete.
Some analogies
You might think of this as being similar to converting an idea for an invention into a set of blueprints from which it can be built, or converting a set of written specifications for a widget into a set of drawings that can be used by the machine shop to build the widget.
Automotive engineers encapsulated the specifications for the steering mechanism of my car into a set of manufacturing drawings. Then manufacturing personnel used those drawings to produce an object where they exposed the interface (steering wheel) and hide the implementation (levers, bolts, etc.)
In all likelihood, the steering mechanism object contains a number of other more-specialized embedded objects, each of which has state and behavior and also has an interface and an implementation.
The interfaces for those embedded objects aren't exposed to me, but they are exposed to the other parts of the steering mechanism that use them.
Abstraction
Abstraction is the specification of an abstract data type, which includes a specification of the type's data representation and its behavior. In particular,
* What kind of data can be stored in an entity of the new type, and
* What are all the ways that the data can be manipulated?
A new type
For our purposes, an abstract data type is a new type (not intrinsic to the ActionScript language). It is not one of the primitive data types that are built into the programming language (such as Boolean, int, Number, String, and uint).
Already known to the compiler
The distinction in the previous paragraph is very important. The data representation and behavior of the intrinsic or primitive types is already known to the compiler and cannot normally be modified by the programmer.
Not known to the compiler
The representation and behavior of an abstract type is not known to the compiler until it is defined by the programmer and presented to the compiler in an appropriate manner.
Define data representation and behavior in a class
ActionScript programmers define the data representation and the behavior of a new type (present the specification to the compiler) using the keyword class. In other words, the keyword class is used to convert the specification of a new type into something that the compiler can work with; a set of plans as it were. To define a class is to go from the abstract to the concrete.
Create instances of the new type
Once the new type (class) is defined, one or more objects of that type can be brought into being (instantiated, caused to occupy memory).
Objects have state and behavior
Once instantiated, the object is said to have state and behavior. The state of an object is determined by the current values of the data that it contains and the behavior of an object is determined by its methods.
The state and behavior of a GUI Button object
For example, if we think of a GUI Button as an object, it is fairly easy to visualize the object's state and behavior.
A GUI Button can usually manifest any of a number of different states: size, position, depressed image, not depressed image, label, etc. Each of these states is determined by data stored in the instance variables of the Button object at any given point in time. (The combination of one or more instance variables that determine a particular state is often referred to as a property of the object.)
Similarly, it is not too difficult to visualize the behavior of a GUI Button. When you click it with the mouse, some specific action usually occurs.
An ActionScript class named Button
If you dig deeply enough into the ActionScript class library, you will find that there is a class named Button. Each individual Button object in a Flex application is an instance of the ActionScript class named Button.
The state of Button objects
Each Button object has instance variables, which it does not share with other Button objects. The values of the instance variables define the state of the button at any given time. Other Button objects in the same scope can have different values in their instance variables. Hence they can have a different state.
The behavior of a Button object
Each Button object also has certain fundamental behaviors such as responding to a mouse click event or responding to a mouseOver event.
The ActionScript programmer has control over the code that is executed in response to the event. However, the ActionScript programmer has no control over the fact that a Button object will respond to such an event. The fact that a Button will respond to certain event types is an inherent part of the type specification for the Button class and can only be modified by modifying the source code for the Button class.
Encapsulation
If abstraction is the design or specification of a new type, then encapsulation is its definition and implementation.
A programmer defines the data representation and the behavior of an abstract data type into a class, thereby defining its implementation and its interface. That data representation and behavior is then encapsulated in objects that are instantiated from the class.
Expose the interface and hide the implementation
According to good object-oriented programming practice, an encapsulated design usually exposes the interface and hides the implementation. This is accomplished in different ways with different languages.
Just as most of us don't usually need to care about how the steering mechanism of a car is implemented, a user of a class should not need to care about the details of implementation for that class.
The user of the class (the using programmer) should only need to care that it works as advertised. Of course this assumes that the user of the class has access to good documentation describing the interface and the behavior of objects instantiated from the class.
Should be able to change the implementation later
For a properly designed class, the class designer should be able to come back later and change the implementation, perhaps changing the type of data structure used to store data in the object, and the using programs should not be affected by the change.
Class member access control
Object-oriented programming languages usually provide the ability to control access to the members of a class. For example, ActionScript, C++ and Java all use the keywords public, private, and protected
to control access to the individual members of a class. In addition, ActionScript and Java add a fourth level of access control, which is called internal in ActionScript and is called package-private in Java.(See Class property attributes in a companion document on ActionScript Resources.)
Public, private, and protected
To a first approximation, you can probably guess what public and private mean. Public members are accessible by all code that has access to an object of the class. Private members are accessible only by members belonging to the class.
The protected keyword is used to provide inherited classes with special access to the members of their base classes.
A public user interface
In general, the user interface for a class consists of the public methods. (The variables in a class can also be declared public but this is generally considered to be bad programming practice unless they are actually constants.)
For a properly designed class, the class user stores, reads, and modifies values in the object's data by calling the public methods on a specific instance (object) of the class. (This is sometimes referred to as sending a message to the object asking it to change its state).
ActionScript has a special form of method, often called an implicit setter method or an implicit getter method that is specifically used for this purpose.(You will see several implicit setter methods in the program that I will explain later in this lesson.)
Normally, if the class is properly designed and the implementation is hidden, the user cannot modify the values contained in the instance variables of the object without going through the prescribed public methods in the interface.
Not a good design by default
An object-oriented design is not a good design by default. In an attempt to produce good designs, experienced object-oriented programmers generally agree on certain design standards for classes. For example, the data members(instance variables) are usually private unless they are constants. The user interface usually consists only of public methods and includes few if any data members.
Of course, there are exceptions to every rule. One exception to this general rule is that data members that are intended to be used as symbolic constants are made public and defined in such a way that their values cannot be modified.
The methods in the interface should control access to, or provide a pathway to the private instance variables.
Not bound to the implementation
The interface should be generic in that it is not bound to any particular implementation. Hence, the class author should be able to change the implementation without affecting the using programs so long as the interface doesn't change.
In practice, this means that the signatures of the interface methods should not change, and that the interface methods and their arguments should continue to have the same meaning.
No comments:
Post a Comment