Flylib.com

Books Software

 
 
 

Section 3.1. Principles of Object-Oriented Programming


3.1. Principles of Object-Oriented Programming

Object-oriented programming is a software development architecture that uses the objecta "black box" of data and related functionalityas its focus. These objects are built on four main facets of OOP design: abstraction , encapsulation , inheritance , and polymorphism . This section introduces each of these concepts and also the notion of an interface as the means of interaction with the contents of an object's black box.

3.1.1. Objects and Classes

An object is a software-based collection of data elements and related procedures that act on those data elements. Obviously, objects are the central theme of "object-oriented" programming. In Visual Basic and other similar OOP languages, a class is the source code design of an object. An object is an in-memory instance of a class in a running program. Multiple object instances based on a single class can exist in memory at the same time.

Although the terms "class" and "object" have distinct meanings, the terms are used somewhat interchangeably in this chapter, at least in those cases where the distinction is not necessarily important.

3.1.2. Abstraction

An abstraction is a view of an entity that includes only those aspects that are relevant for a particular situation. It takes something from the real worldan employee, a book, a chart of accounts, a galaxy, a grain of sandand breaks it down into individual elements that can be managed with software. Consider a software component that provides services for tracking an employee's information. The first step in designing such a component is to identify the items or features that would be managed by the component. Some of these items may be:

  • Employee full name

  • Employee home address

  • Company ID for the employee

  • Current salary

  • Length of employment

  • Features to adjust the salary based on a rule

This list includes not only basic data values, or properties , but also common actions to be taken on the data, or methods . Properties of the class, such as the employee's full name, are sometimes called fields, and they may have limits on the type or range of data allowed. Methods may require additional information (such as a table of salary adjustment rules for the salary adjustment feature) to work properly. These actions are sometimes referred to as operations or behaviors. Together, the properties and methods are known as members of the abstraction.

The properties and methods of a class are relevant to that class. Although the Employee class could have included properties for IQ or the number of hairs on the employee's head, these data values have no relevance to the purpose of the class. Even though they are part of each employee, they provide no value to the class and are therefore excluded.

In short, the true employee has been abstractedthe class includes only those properties and methods of employees that are relevant to the needs of the class. Once the abstraction is complete, the properties and methods can be built into a software component.

3.1.3. Encapsulation

Encapsulation is the process of converting an abstraction into a usable software componentthe black boxand exposing to the public only those portions of the abstraction that are absolutely necessary. The complete logic needed to manage each public property or method is fully contained ("encapsulated") inside the black box.

Encapsulation serves three useful purposes:

  • It permits the protection of these properties and methods from any outside tampering.

  • It allows the inclusion of validation code to help catch errors in the use of the public interface. For instance, the encapsulation can be programmed to prevent a negative number from being used for an employee's salary.

  • It frees the user from having to know (or worry about) the details of how the properties and methods are implemented.

High-level programming languages already perform some encapsulation to simplify the work required by the programmer. For instance, the SByte data type, introduced in Visual Basic 2005, is an 8-bit integer data type that supports a range of numbers from -128 to 127. But how exactly does it record those 128 negative numbers ? If you are familiar with binary representation, you know that each bit of the integer number represents a power of 2: the right-most bit (bit 0) represents 2 , the bit just to the left of that (bit 1) represents 2 1 , and so on up to the left-most bit (bit 7), which represents 2 7 . Setting each of these bits results in a different number. For instance, the binary number 00100110 sets bits 1, 2, and 5, and the sum of 2 1 , 2 2 , and 2 5 is 38 (decimal). In unsigned data, the binary number 11111111 equals 255 decimal. But that's all the bits. How do you get a negative number?

Visual Basic uses a system named two's-complement representation to handle negative numbers. Basically, any time the leftmost bit is set to 1, the number is negative. Then there are various rules used to interpret the remaining bits, depending on whether the leftmost bit is set or not.

Do you want to know those rules? Do you really need to know those rule, or how negative values are managed at all? The great answer is: no! In most programming, you don't have to worry about how Visual Basic stores negative numbers at the binary level. Who cares? You only need access to negative numbers, not to the complex rules about how they are processed in the computer. Visual Basic wraps up all of this functionality for you automatically in the SByte data type. This is the essence of encapsulation: just the right amount of visible functionality, all of the messy details hidden from view.

Moreover, encapsulation protects programmers from making errors. For instance, if every programmer had to do the negating by setting each bit manually and following all of the various and sundry rules, some important step would be forgotten. The encapsulated data type takes care of this automatically.

Encapsulation has yet another important feature. Any code written using the exposed interface of the SByte data type remains valid, even if the internal workings of the SByte data type are changed for some reason. If Microsoft decided to have the SByte data type use one's complement representation (another method for managing negative numbers), it wouldn't matter to programs that used SByte , as long as the interface to the data type did not change.

3.1.4. Inheritance

Inheritance makes it possible for OOP code to build classes that extend or restrict features in other existing classes, without the need to fully rewrite the original class. For instance, a class of Pet may have generic data fields such as Name , Age , and Color . This single class could be extended into other, more specific classes through inheritance . A class named Dog that is derived from Pet would automatically include the Name , Age , and Color members, but it may add additional canine-specific members such as Breed and a ShedsHair flag. In this situation, the Dog class inherits from the Pet class.

Inheritance used in this manner certainly reduces duplication of code, since the derived class does not have to rewrite the code for the existing base class 's members. But inheritance also makes interactions between these objects easier, since an object of type Dog is also a true object of type Pet . Objects of a derived class are also objects of the base class, and they can be used in code as if they were actually members of the base class. (The reverse is not true; objects of type Pet are not necessarily objects of type Dog ).

Some languages allow a class to inherit from multiple base classes at the same time. Visual Basic does not support this feature.

3.1.5. Interfaces

The public members of an object are known as its interface (or public interface ). Usually, an object has a single public interface, since its class was designed with a single purpose in mind. But sometimes it is useful for a class to have multiple interfaces . For instance, along with the Pet class, consider another class called House . These two classes have some common aspects and tasks that apply to both, one of which is a cleaning strategy. While you could add distinct CleanNow , CleanserName , and CleaningTimeRequired members to each class, it would be more convenient to have a separate interface, called the Cleaning interface , that could then be applied to both Pet and House . Then your code could call the cleaning-related members on any object that implemented the Cleaning interface .

Interfaces are simply templates of desired functionality. To make these templates a functional reality, they must be implemented through a class. Implementing is a little different from inheriting. With inheritance, the new class receives the existing functionality of the base class; the new class doesn't have to reinvent this functionality. When implementing an interface, the new class is responsible for providing all of the functionality of the interface.

While Visual Basic classes cannot inherit from multiple base classes, a single class can implement multiple interfaces at the same time.

3.1.6. Polymorphism

The term polymorphism means having or passing through many different forms. The Dog class, derived from the Pet class, automatically receives the prewritten members of the Pet class. However, if one or more of these members needs to be extended in a special way to meet the needs of the new derived class ( Dog ), special Dog -specific versions of those members can be added to the Dog class. Any Dog object that calls these methods will use the Dog -specific versions; any general Pet object will use the default Pet -specific versions. If your code is currently treating a Dog object as a more generic Pet object, it will still use the Dog -specific versions, since the object is still a Dog .

Sound confusing? Welcome to polymorphism. Fortunately, the Visual Basic compiler figures out all of these relationships for you; you just need to write your code to enable the class-specific actions you require.

3.1.7. Overloading

Sometimes it is useful to have more than one way of performing the same action in a single class. For instance, if your Dog class has a TakeForWalk action, you might require several ways of taking this action to mimic real-world actions. For instance, you might want to call TakeForWalk with a time duration ("30 minutes") for a generic time-based walk, or call it with instructions for a specific path-based exercise plan. You would need one version of this action that takes a number (time-based) and one that takes a path plan ( path -based), perhaps sent as a string.

When a class includes multiple versions of the same member that differ by their argument signatures (that is, by the parameters and return values of those members), that is overloading . This allows the member to take an action, but with different types of input data. Overloading most often occurs with actions taken on the object's data. The ability to provide differing sets of supporting data to an action can greatly expand the functionality of a class.

New in 2005 . The original .NET release of Visual Basic did not include operator overloading . This form of overloading allows you to provide custom meanings to the standard language operator symbols, such as the + (addition) and <> (not equal to) operators. The 2005 release of Visual Basic adds this form of overloading to the language. See the Chapter 5 " section of Chapter 5 for information on this enhancement, including examples.