A2. Object-Oriented Basics


In this section, you will learn about basics of object-oriented programming:
  • Identify the 2 parts of an object.
  • Identify the 2 elements of the C language that correspond to the 2 parts of an object.
  • List 4 components of an object-oriented system.
  • Give an example of a class and compare it with an instance.
  • Identify the major use of classes; of instances.
  • Give an example of inheritance.
  • Give an example of encapsulation.
  • Give an example of polymorphism.
  • Describe the difference between interface and implementation.
  • Describe the process by which an object is created.
  • Describe the process by which an object is destroyed.

Preview

Describe a car without using the word "car."

What's the difference between a plan for a car and an actual car that you can drive?

Isn't OO Something New?

Object-oriented programming has been around since the 70's.
It was developed on the best computers of its day, mainframes.
Objects are a natural outgrowth of the tool becoming more like the task.
Computers evolved as their resources allowed them to.
Initially all design had to center on maximizing machine efficiency, even at the expense of the most natural expression of the problem.
As machine efficiency increased, it could be used to provide more abstraction from the computer.
This evolution has allowed design and representation to move from tool-centered to task-centered.
Personal computers initially lacked the power to run OO programs efficiently.
Personal computers stalled the deployment of OO systems because once again, the systems were resource poor.

Isn't Procedural More Efficient?

Procedural code is fast but it is brittle.
It is typically single-use code: an exact, made-to-order fit between problem and solution.
The fastest code is assembler: why don't we use assembler exclusively? Because it is too close to the machine, which implies too far from the problem.
Procedural code has a short lifespan.
It is difficult to adapt or abstract, even if today's new task is generally very similar to yesterday's.
Maintenance of procedural code often leads to the question of whether it would be easier to rewrite it from scratch rather than try to modify it.

Isn't OO Hard?

Only Object-Oriented design is a complex art.
Any large project will require a designer.
It takes a long time to develop sound OO design skills.
The result can be better designs: the OO design cycle is longer than that of procedural code and typically more thorough because of the number of iterations the design receives.
Object-oriented implementation is typically easier than procedural implementation.
The design is normally stronger, with clear definitions and constraints.
Code tends to be simple, and often just specializes existing behavior.
Details of the system are better hidden.
Objects are naturally modular: the system can be implemented and tested as separate components.
Code can be team built.

Isn't Code Reuse the Most Important Thing to OO People?

Code reuse is a benefit of OO systems, but it is not the most important one.
In many cases reuse has been over-emphasized.
Code use is foremost.
The real point of any body of code is to provide a high-fidelity solution to a problem.
The ability of object-oriented code to accurately and completely reflect the problem space is a key strength.
Code maintenance and lifespan are equally important.
Code needs to be robust and yet pliant when change is needed: the more critical the code, the more often it is modified and changed.
The cost of a line of code goes well beyond the cost to initially produce it.
Reuse has many forms: it does not have to mean designing and creating your own system of reusable objects.

A Procedural Programmer Actually Invented Object-Oriented Programming

Good programmers have always tried to reuse important data structures and functions.
Data structures and functions are separate in the C language.
Reuse is difficult because data structures and functions have to be managed, tracked and included separately, which decreases their reliability and portability.
Libraries of functions are limited in their ability to represent persistent state.
Data structures and functions are normally deeply intertwined in C programs.
Data structures typically need to be manipulated by their own set of tailored functions.
Functions typically need their own set of data structures on which to act.
Object-oriented programming is a formalization of the reuse of data structures and their functions.
Objects provide a way to manage data structures and their functions as single programming units, increasing their portability.

Shifting the Paradigm from Structured to Object-Oriented

"But I already know how to program!".
The biggest hurdle to learning object-oriented techniques is simply that it's different.
Many people take the shortcut of just wrapping functions in a class.
To be effective, a solid OO design must be developed first.
OO programming requires a true shift in mindset.
Rather than thinking "what functions do I need, and what data," you must think "what objects best represent the physical problem, and what can I do with those objects?".

What's an Object?

An object is a representation of a physical aspect of the problem being modeled.
Think of a description of the problem. Anytime you use a noun in that description, that might be a good candidate for an object!
Objects have state.
What does the object look like?
What is the object currently doing?
Where is the object?
What other objects are part of this object?
Objects have behavior.
What can the object do?
How does the object respond to outside stimuli (messages).
Objects can talk to one another.
They can ask questions.
They can request actions.
They can report their status.
Objects can be secretive.
They only need to tell what they want to tell.
They can filter how others view them.
They can hide things they don't want others to know or care about.

State and Behavior

Abstraction provides a way to separate raw experience into categories.
We use abstraction to select and emphasize certain aspects of experience while ignoring others: important similarities over unimportant details.
Grouping things into categories of shared similarities allows us to reduce the complexity of everyday experience.
The categorization is based on the state and behavior you perceive each thing to have.
The state and behavior of the thing lets you group it with other things of the same type.
Depending on how you look at the world, the categories and their contents may change.
Abstractions are choices that you make based on situation and need, not absolutes inherent in the things themselves.

The 2 Parts of an Object

Objects are made of 2 parts.
Data - a set of named variables or constants (which could be other objects); they hold state.
Methods - functions that typically act on the data structure; they provide behavior.
These data and methods are sometimes called the object's members.
An object combines these 2 elements into a unified component, a thing.
The resulting software thing can be used to represent a real-world or imagined thing.
Objects add representation to software: the ability to represent discretely the "actors" in a problem.
These 2 parts of the unified object correspond to separate elements found in most C programs.
A C struct is like the data members in an object.
C functions are like the object's methods.
However, an object has one implicit feature that C programs do not; the data and methods are explicitly connected, packaged into an object.

Hiding Data

Objects can keep their data private.
You can't always access the data directly as you can a struct in C.
Hiding data allows the object to provide its own quality control.
The object can make sure its data always contains reasonable values.
The object can watch what data access requests are made.
The object provides methods to allow controlled access to its state.
These methods may expose some, none, or all of the object's data structure.
The set of publicly-available methods can limit what data an external object can view or modify.
The object may further limit the access to its internal state and behavior.
Programmers can express very fine control over how internal data and methods can be seen by families of objects, specializations of objects, and libraries of objects.

What Does Object-Oriented Mean?

Object-oriented programs have three characteristics.
Encapsulation - the objects combine data and methods into a convenient bundle.
Inheritance - object types, known as classes, can obtain their traits from parent classes.
Polymorphism - references of a parent class type can act as a proxy for an object, delaying decisions about their behavior until runtime.
Object-oriented programs focus on objects.
The objects play a role in the problem, and perform actions to solve that problem.
A structured program concentrates on the actions to be performed; the data are second-class citizens.

Class and Instance

Each different kind of object represents a different data type.
The new data type comes with its own set of methods.
Object types are used in much the same way that primitive and user-defined types are used in C.
Each new object type is called a class.
A class definition is like a struct definition that also contains the declaration and definition of a group of methods.
The class is used like a struct: it defines a mold that can be later used to allocate objects of that type.
Each object created from an object type is called an instance of that type.
Creating objects is called instantiating the class.
Creating the instance allocates memory.
The new instance has access to the single copy of methods in the class.
The new instance gets its own fresh copy of the data declared by its class.

Defining by Difference

Each new class is created by basing it on some existing class.
The base class is called the superclass.
The new class is called the subclass.
This is also called extending a class.
The new class gets a copy of the data definition and access to the methods of the existing class.
The new class only has to define how it is different from the old class.
It can be used anywhere the old class can be used.
The subclass can extend the state and replace or refine the behavior of the superclass.
Creating the class does not create any objects of that class.
The class can be thought of as a mold for creating instances of that class.

Inheritance, Overriding and Refining

A subclass can add to its superclass' data.
The subclass' data is a concatenation of the data of all of its superclasses.
These inherited data cannot be removed.
A subclass can add new methods.
The subclass has access to the most recently defined versions of all of the methods in its superclasses.
Inherited methods cannot be removed, although they can be replaced by versions with empty implementations.
A subclass can replace or refine existing, inherited methods.
A method is overridden by creating a new implementation in the subclass with the same declaration as the existing method.
When the method is invoked on a object of the subclass, the new version will be performed.
The overridden method may completely replace the inherited version, or it can incorporate the old version by calling it.

Types of Inheritance

Single inheritance means that each object has only a single parent type.
A single superclass makes the implementation of the subclass clearer and easier to maintain.
Multiple inheritance means that an object can have more than one direct parent.
Multiple superclasses are very helpful in solving design-time problems but can cause problems in implementation and reuse.
OO is design-centric: it frowns on strategies that opt for easier early design choices at the cost of hiding late implementation problems.

Messages and Methods

The methods of the object are invoked indirectly.
Rather than being called directly, an object's methods are called using a message.
The message contains the name of the method and an identifier for the object that should perform it: the receiving object.
The name of the method is used to look up the identified object's implementation for that name, its response to the message.
The names of the methods can shared by classes.
Each class can have its own version of a method for the shared name, or use the one it inherited from its parent class.
Functions versus methods.
A function has a single interface and a single implementation.
A method has a single interface and potentially many implementations.

Interface and Implementation

The separation of message and method allows for public interfaces and private implementations.
The public API (Application Programming Interface) describes the contract between the creator of a class and its potential users.
The internal mechanisms behind that contract are hidden: only the public interface is guaranteed.
The messages can be generic and shared.
Each object that performs a similar task can be designed to respond to the same generic message.
The interface is simple for the programmer to know and use.
The version of implementation you get is selected based on the acual object that receives the message.
The implementations are private, hidden and specific to a class.
Each receiving object performs the behavior the message requests in its own way, the way that makes sense for the type of object it is.

Dynamic Binding

In C, the names in your code are bound to their implementations at compile time.
This early binding means the code must be recompiled or relinked to be changed.
In an object-oriented system, the names and the code they point to can be bound later, at run time.
New versions, as well as extended versions of the code can be added without recompiling.
This dynamic binding allows the system to better reflect the dynamics of the system's use, both in real-time and over time.

The Class is Also an Object

The class is an object with its own state and behavior.
Just as instances have instance data and instance methods, the class can have class data and class methods.
The class' data are used for values of general interest and shared access.
Constants are often stored as class data.
Class data are useful for information that no instance could contain, such as the total number of instances created so far.
There is only a single copy of the class' data-unlike each instance's data, which are allocated dynamically for each instance when it is created.
The class' methods typically used to make instances of the class.
The method for creating new instances is often a class method called new.
In addition, classes that provide utility functions will often define them as methods of the class.
The receiving object for a class method is the identifier for the class.

Protocols

Protocols are a set of function names that describe some behavior.
Protocols are used as a way of communicating the design of a system, how objects interact.
Protocols provide a means of publishing generic messages that can be shared.
Protocols are also known as interfaces.
Protocols are more abstract than classes.
No implementation is supplied with a protocol.
Each new object that implements a protocol is responsible for upholding the contract that is described by the protocol.
A protocol helps an implementer make sure a new object will fit smoothly into an existing system of objects.
Java calls these protocols interfaces.

Garbage Collection

Object systems by definition use shared code, complicating the problems of deallocation.
When dynamically allocated memory is shared, it is not possible for any of its users to know which of them is the last one using the shared resource, the one that should free it.
Only at the system level can the memory allocation and use be traced.
Garbage collection frees the programmer from concentrating on details and timing of deallocation.
In a system with garbage collection, the programmer does not explicitly deallocate memory.
When finished with a particular object, the programmer drops all references to that object.
When there are no more references to an object-because finally no one is using it-its memory is deallocated by the system.

Language and Library

The OO basics combine to create a system that allows the programmer's focus to shift from language to library.
Objects allow libraries to represent state as well as behavior, dramatically increasing their range.
Abstraction helps to represent the real objects from the problem space as software objects in the solution space, increasing the fidelity of the library.
Encapsulation allows the implementation to be hidden and change as needed as long as the library's interface remains consistent.
Polymorphism reduces the surface area of the library, making it easier to use and extend, because a small number of messages can be used to invoke an unlimited range of methods.
Inheritance provides the library with reliable extensibility: only what is new has to be defined, the balance of the behavior is unchanged.

Libraries Expand a Programmer's Range

Extensive libraries allow the programmer to concentrate on the specialized aspects of the task.
The ability to reuse the generic elements of a solution allows a programmer to spend more time solving the problem that is novel and the real reason for doing the work.
Each solution's new objects also represent additional code equity for future projects.

OO Benefits

High-fidelity
Objects are representative, closer to the language of the problem.
OO systems are designed on a longer design cycle that stresses iterative refinement.
Maintainable
OO systems are modular and encapsulated-a change to an implementation detail is genuinely transparent to the balance of the system.
Dynamic OO systems allow you to incorporate changes more easily.
Extensible
Building a new version of a working object by modification is easier than creating the new object from scratch: extending the objects in a working system does just that.
The set of messages can remain stable while allowing behavior to change by adding new types of receiving objects that respond in new ways to the same messages.
Reusable
The common elements of your work can become a collection of reusable, standard objects that reduce the total surface area of the system, while increasing its fidelity and consistency.
Team-built
OO systems allow many programmers separated by both time and distance to contribute to a project.

Downsides

Learning curve
Learning objects can be daunting, especially because the process is more about learning a different way of seeing the problem and less about the details of the language.
Sometimes, the most successful procedural programmers have the most difficulty with the paradigm shift.
Standards
OO represents an investment in code: yet, there are few standards to guarantee long code life or inter-operability for the objects you use and create.
Design
OO systems are design heavy: they typically take longer to initially create.
Good OO design is still an art: it takes experience to learn to do it well.
Efficiency
OO systems are getting faster all the time, but they tend to be larger, more general and more dynamic, all of which come at a price.

Terms and Examples

object
A programming unit that combines state and behavior into a component; the software version of a noun.
class
A mold for creating objects of a certain type: a place to define the state and behavior; a blueprint, a cookie cutter, a data type; also an object in its own right, with its own state and behavior.
class Ball extends Toy {
  private static String type = "rubber"; // class data
  String color = "red";                  // instance data
  static String getType() {              // class method
    return Ball.type;
  }
  Sound bounce(int howHigh) {            // instance method
      return super.bounce(howHigh);      // return sound that bounce makes?
  }
}
instance
An object of a certain class; a cookie made from a class' cookie cuter; an object with the state and behavior defined by its class.
Ball myBall = new Ball();
members
The collective name for the internal elements of an object; the things in the object that represent state: its class data, instance data, and behavior: its class methods and instance methods.
type
color
				
getType
bounce
instance data
Members of an instance that hold typed values; elements of the instance's data structure; each instance object gets its own named slot to hold its value for the variable.
String color = "red";                    // instance variable
...
String ballColor = myBall.color;
class data
Members of a class that hold typed values; elements of its data structure; there is only one copy of a class datum, stored in the class object.
private static String type = "rubber";   // class variable
...
return Ball.type
encapsulation
Having a boundary between the public part of the object (its interface) and the private part of the object (its implementation).
private static String type = "rubber";   // implementation detail
...	
public static String getType() { ...     // interface
message
An object-oriented function call; a generic method name plus the object that should perform it; an expression that results in a behavior, the specifics of which are based on the class of the receiver of the message.
myBall.bounce(23);
receiver
The object named in a message expression; the object whose version of the function will be performed-the receiver's method for the message.
myBall
method
The actual function that is performed in response to a message; each class can have a different actual function for a particular shared function name; the receiver's class is used to select the method used when the message is received.
bounce
instance method
A member of an instance that acts like a function; instance methods are defined in the class; each instance of a class shares the same implementation for a particular method; an instance is the receiver of a message to invoke an instance method.
Sound bounce(int howHigh) {              // instance method
  return super.bounce(howHigh);
}
...
Sound boing = myBall.bounce(23);
boing.play();
class method
A member of an class that acts like a function; class methods are defined in the class; either the class or an instance of the class can be the receiver of a message to invoke a class method.
static String getType() {                // class method
  return Ball.type;
}
...
String ballType = Ball.getType();
polymorphism
The ability of each object in a system to respond in its own appropriate way to a generic message.
Toy myToy = new Toy();
myToy.bounce(10);
myBall.bounce(10);
inheritance
The creation of new classes by basing them on existing classes, and then describing the difference.
class Ball extends Toy { ...
superclass
The class that is the basis for specialization; the class that is extended.
Toy
subclass
The class that is the specialized version of the superclass; the extended version.
Ball

Review

Object-oriented programming uses bundles of state and behavior to represent things - objects.

New classes of objects can be created from existing classes of objects by describing the difference.

Each object class can respond with its own method for a generic message.

Large libraries of tested, trusted code can be created to handle the generic tasks.

Java

Java is an object-oriented language with its own built-in libraries.
Java libraries are called packages.
Objects are created dynamically.
Class objects are created when they are first encountered.
Instance objects are created by the programmer as needed.
Object creation uses a special function called a constructor to initialize the new object's state.
The implementation for a method in Java is looked up the first time the message is sent.
The version selected is cached and used thereafter for the same message, receiver, and call site.
This provides a good balance between dynamics and execution speed.
Java provides single inheritance.
A class can only have a single superclass.
Protocols in Java are called interfaces.
An interface has no attached implementation.
A class can multiply inherit interfaces.
Java methods are selected based on the class of the receiver and then on the arguments to the method.
Each method name can have multiple implementations.
Each of the implementations accept different data types for their parameters.
The caller indicates which version to perform by passing arguments that match the type expected by the implementation they want invoked.
Java allows for very fine control over the access to an object's members.
Access to the members of a class can be private, protected, shared within its package, or public.

Copyright © 1996-1997 MageLang Institute. All Rights Reserved.