(syllabus and calendar)

Ch. 4. Introducing Classes, Objects, and Methods

zip4 of examples 2010

 

Session 4

Overview and glossary

Vehicle class and objects of type vehicle

object creation

reference variables and assignment

methods

returning from a method

returning a value

parameters for a method

constructors

parameterized constructors

new operator

garbage collection and finalize

this - a keyword that refers to the current object


Quiz

Mid-course Evaluation

Overview and glossary

A procedural programming language, such as C, has its own advantages (such as performance) and disadvantages (non-portability, need for careful memory management). Java does not perform as fast as native C. However, Java does have the advantages of object-oriented programming over procedural programming for code reuse and customization (including the custom data types known as classes): encapsulation, inheritance, and polymorphism.

An object is an instance of a class. A class is a template for instantiating (and initializing) objects. A class has methods and fields.

HelloWorld.java is mostly procedural. We did not instantiate an object of type HelloWorld:

HelloWorld hw = new HelloWorld();

The only method we used was println(), which is on the static output stream, out

and out is a static field of System, which is part of the java.lang package

http://java.sun.com/javase/6/docs/api/java/lang/System.html

which is automatically available to every program. This means that HelloWorld does not reveal all the typical tasks of writing an object-oriented program.

For example, if we want to use a non-static method, we must first instantiate an object of the class that defines the method we want to call. It is not necessary to assign a name (or identifier) to the newly created object.

The two phases involving a method are:

  1. method definition
  2. method invocation

The necessity of two phases is already familiar to us:

  1. declare and assign a value to a variable
  2. use the variable

What is new is that whereas a variable can be declared and assigned a value is a single statement, a method definition requires considerably more, including a code block.


Object-Oriented Glossary

class

The class defines the behavior and attributes of the object. An object is an instance of a class. A class is a template that defines the form of an object.

When I visit a retail store, each employee might have a unique name tag and be a unique "object", but I expect them to follow the role of RetailEmployee, that is, to be instances of the class RetailEmployee.

In the real world, we deal with objects. Who has eaten Food today? No one. But we all ate some food objects. Each McHeartAttack's french fry is an object of type FrenchFry that fits the template and has attributes of length, width, color, and temperature.

A class is, in effect, a custom data type. Even the primitive data types, such as int, can be represented by a corresponding class, such as Integer. When you create classes for your applications, you create your own custom data types. (Much of the value of object-oriented programming is the ability to create the custom data types or classes that serve your business needs or fit the problem domain.)

class members

The members of a class are its

main()

The main() method is the point of entry for execution. Your application must have a main method in a file named for the class that contains the main method. Your application can have other classes, and they do not have a main method. (An applet does not have a main method because the Java virtual machine is already available for executing byte code within a web browser.)

dot operator

The dot operator enables you to access a class member through an instance of the class. I get the food value of Food by accessing myFrenchFry.calories or myFrenchFry.flavor. Use this syntax:

object.member

Note: In the case of System.out.println() the syntax is:

class.static_field.method


Encapsulation

The class is a unit for encapsulation.

A class has methods and attributes 

In Java, the unit of encapsulation is the class. Each object is an instance of a class. The class is a template for making objects. The class is similar to a recipe, rule book, set of laws, cookie cutter, or a mold, for making things of a certain shape, things with certain attributes. If I define a class called Dog, it might have an attribute for number of legs, which might be set to four:

int numberOfLegs = 4; // this attribute could be private or public - if hidden, it's more encapsulated

A string is implemented inside Java as an object of the class String. Therefore, a string object has the length method. This example shows using that method on a string object with the identifier (or name) s.

I don't need to know how the length method works. The details are encapsulated in the class that defines the method. Encapsulation has the benefit that Sun can improve the performance of the method without breaking my code that uses this method.

Similarly, if you know how to drive an automobile with the encapsulated acceleratorPedal, the manufacturer can improve the engine (implementing an electric engine in place of a petro-chemical engine), and your method of pedalToTheMetal() still works. Unfortunately, the term "gas pedal" has a non-encapsulated implementation attached to it: it assumes a gasoline-powered engine. It would be poor design to designate either a batteryPedal or gasPedal. The attribute is acceleration.

Encapsulation supports re-use of code (or patterns), independent of implementation, especially when I combine encapsulation with inheritance.

Inheritance

The subclass is a unit for inheritance (from its superclass). The subclass only need to code its deltas, its differences from the inherited norm, its specialization of the general. For example, ElectricCar, HybridCar, GasolineCar, DieselCar can inherent the majority of their methods and fields from Car.

Another example: In the Old Testament, dark waters precede the invention of light, so light must inherit darkness, and there is some darkness in even the most delighted/enlighted persons. In the New Testament, light is considered prior to, and independent of, darkness, so the concept of pure goodness can exist, even if co-mingled with human imperfection.

Polymorphism

The method is a unit for polymorphism. Overloaded constructors are another polymorphic aspect.


Example of a Class: Help

What is a switch statement about? What is it an alternative for?

What datatype does the isvalid boolean method of line 57 require? 

Why does the return value of the read method undergo a cast in line 74?

Where does the hlpobj object get the showmenu method?

Which method is being called in line 74? Is that method name overloaded with multiple signatures? Is this an example of polymorphism?

http://java.sun.com/j2se/1.4.1/docs/api/java/io/InputStream.html#read()


Overview of OOP

So we know that an array can store many values of one, and only one, type.
What if we want a way to associate values of different types?
An object is not an array, and not even a multi-type array, but an object does allow us to get and set a multiple types.
An object is surely less primitive than a "primitive", and perhaps closer to real-world objects insofar as it can be more complex.
An object is a custom data-type that can have both data and behavior.

Sun's tutorial on object-oriented programming concepts: http://java.sun.com/docs/books/tutorial/java/concepts/index.html

[A good, easy-to-read introductory book with many diagrams: Object Technology: A Manager's Guide by David Taylor.  http://www.bookpool.com/.x/49jdnnq9t0/sm/0201309947 ]

Procedural languages, such as C, center around code, and what the code does. To write procedurally, you have to think like a computer.

Object-oriented languages, such as Java, center around objects, which is more like how human beings understand the world. For example, you can model your program on how you model your business, with "real world" objects such as

Objects are at a higher level than routines. Objects involve the abstraction of details. You design an object-oriented system by thinking about self-enclosed, discrete entities (objects) that send messages to each other.

Some Java applications serve a business workflow based on a business model of business objects. Corresponding to each business object (Customer, Salesperson, Order) can be a database table, which in  term corresponds to a Java object that contains the business logic for that business object. In such a scenario, a database field (table column), such as Name or ZipCode can correspond to an object attribute or property. In this sense, the term field can have a common meaning in database design and programming.

This also helps us understand why object-oriented programming is not as fast a programming with primitive types: a class can have as much complexity as a large database table.

The three key concepts of object-oriented programming are:

Encapsulation

Encapsulation is like a capsule: the doctor tells you to take a medicinal capsule or pill. Far too small for you to see is the structure of the compound or molecule that does work in your bloodstream or organs to cure your disease. You don't even see the components of the mixture, which might be gray bitter-tasting medicine mixed with white sugar and blue flour. The complexity is hidden from you. Your orders are simple and external to the encapsulation: take one blue pill each day with water.

Encapsulation is like a black box. When you purchase a television set, you do not need to know the details of the electronics inside

Instead, you only need to know how to plug in the UNIT, attach the cable, turn the on switch, and press buttons on the remote control. You have a UNIT that sends visual and audio messages to you, and you do not care about the hidden actions within the unit.

In Quality Assurance, the phrase "black box testing" means observing the behavior of the unit from outside, without having access to the internal source code.

Similarly, cccording to Behaviorism, a school of psychology, even if we say we "know" a person, we do not know the details that are internal to that person, only the messages that the self-encapsulated "person unit" makes accessible or public in some way, such as through words or deeds.

Even within the electronics (or electro-chemtronics) of our own nervous system, an encapsulated program regulates our heartbeat (and while sleeping, our breathing) without our conscious control. The messaging between brain and cardiac muscle is hidden from us. The same is true with the coordination of muscles involved in sneezing, speaking,  swallowing, digesting food, walking, contracting and dilating the pupils to adjust to ambient light, and 99.9% of what we do. This encapsulation is essential to avoid information overload from background processes so we can focus on conscious decisions, such as whether to use a for loop or a do while loop.

A class has methods and attributes 

In Java, the unit of encapsulation is the class. Each object is an instance of a class. The class is a template for making objects. The class is similar to a cookie cutter, or a mold, for making things of a certain shape, things with certain attributes. If I define a class called dog, it might have an attribute for number of legs, which might be set to four:

int numberOfLegs = 4; 

(When I go to the pet store to buy a dog, I do not purchase the class of Dog. Rather, I purchase an instance (an embodiment) of the class Dog.
I purchase Fido, Rover, Lassie or another actual dog to whom I might have not yet have assigned a name.)

Back to the class of Dog (that is, to dogs in general).
Unless I only want a statue of a dog, I want the dog to be able to do things.
There is kind of static statue called taxidermy, but only the dynamic state prior to taxidermy can make use of behavior (methods).

The dog class might have an action (or behavior, or method) for:

These distinguish the class Dog from the class Cat that has:

I do not care about the bio-electro-chemistry that makes the tail muscles contract and produce tail wagging. I just want to see my dog happy, tail a-wagging.
I do not care about the intricate machinery in the dog's nose that enables the dog's identifyAnythingWithinTwoSecondsBySent() method. I just want my dog to recognize me at night, even in darkness, without barking at me or biting me.

if (myDog.identifyAnythingWithinTwoSecondsBySent("stranger")
{
   bark();
   bite();
}
if (myDog.identifyAnythingWithinTwoSecondsBySent("owner" || "strangerOfferingMeat")
{
   wagTail();
}  

Encapsulation supports re-use of code (or patterns)

Encapsulation simplifies things for whatever communicates with the encapsulated object. The internals can change without affecting the overall behavior. For example, the interface to a piano is a set of piano keys and three pedals. Behind the scenes, inside the black box of the piano, are sophisticated mechanical hammers, springs, and strings. If you can play a cheap, honky-tonk, out-of-tune piano, you can also play the world's most expensive Steinway concert piano, and without having to understand Steinway's patented hammer action. Indeed, I can then also play an electric or electronic piano (or even pick out a tune on a vibraphone, xylophone, or glockenspiel), which might be a unit that encapsulates different methods for making the strings vibrate, yet offer me the same user interface of a set of PianoKey or PianoKey-Like objects.

Where is the messaging in this piano metaphor?

  1. The pianoKey object,
  2. upon the event of being pressed,
         event = pianoKey.keyPressed(middleCKey);
  3. sends a message to the hammer object,
         message = pianoKey.prepareToHitString(middleCString);
  4. which in turn sends a message to the pianoString object
         message = hammer.bangOnString(middleCString);
  5. and the pianoString object sends a message to the pianoPlayer object
         sound = middleCString.Ouch();

Indeed, I can re-use my code that tracks a particular pattern, such as the notes of scale, no matter which keyboard instrument I play. I might even be able to transfer knowledge of the piano scale to the guitar fretboard.

Piano major scale with 3-4 and 7-1 being half-steps:

Guitar fretboard major scale with 3-4 and 7-1 being half-steps:

Inheritance

Inheritance enacts the reuse of code. For example, now that I have a messaging system for the middle C key, I can reuse that logic for all 88 keys on the piano. Each key can inherit attributes (properties) and behavior (methods) from the PianoString class, the template or mold for all strings.

When you design a more complicated system, your class hierarchy will have more levels. For example, if you were designing a library catalog, you might layers such as these:

Business rules are enforced by inheritance:

Therefore, whatever object is a member of the JapaneseMonthlyPeriodical class, will automatically inherit the logic common to LoanObject, that is, the ability to be "checked out". I do not have to rewrite the logic for the procedure of checking out a JapaneseMonthlyPeriodical and make it different from the procedure for checking out a EuropeanLanguageMonthlyPeriodical. It is like inheriting money or kingship: I do not have to do work to get the money or the crown.

Inheritance as Specialization

However, it might WANT to over-ride what an object inherits. For example, I might want the

In other words, I might want to have different styles or forms of checkout rules. The ability to have many (poly) forms (morphs) is called polymorphism.

Suppose you have a class hierarchy involving three classes, Circle, Square, and Rectangle, which all inherit the calculateArea() method from the Shape class (or, as we shall see later, interface). Polymorphism enforces that each class implementation has a calculateArea() method, but allows each implementation class redefine the inherited or required method to fit the shape. For example,

class Circle implements Shape  {
   public double calculateArea()   {
      circleArea = pi * radius * radius;
      return circleArea;
   }
}

class Triangle implements Shape  {
   public double calculateArea()   {
      triangleArea = base * (height/2);
      return triangleArea;
   }
}

Polymorphism

Polymorphism means "many forms". A behavior or method can have more than one form.

eatFood(wooden chopsticks); // typical of China
eatFood(metal chopsticks); // typical of Korea
eatFood(fork, knife); // typical of French nobility
eatFood(rightHand); // typical of Morocco
eatFood(rightHand, leftHand); // typical of baseball stadium hotdog devotees
eatFood(intravenous tube); // typical if digestive system does not function

A case of polymorphism could be in banking. Suppose that my bank allows me to open two kinds of accounts: a standard account that only requires a minimum balance of one cent (but charges service fees), or a deluxe account requires a minimum of one thousand dollars (and provides services without fee). Therefore, the openAccount() method has two forms or two signatures.

if (deposit => standardMinimum | deposit <=deluxeMinimum)
{
     StandardAccount.openAccount();
}
else
{
     DeluxeAccount.openAccount();
}


Let's Discuss OOP and do some review

  1. Name the three concepts (or buzzwords) in object-oriented programming?
  2. A Java class is the unit of which major feature of object-oriented programming?
  3. True or False: A class is an instance of an object?
  4. What are the "reserved words" in the HelloWorld program?
  5. Which aspect of OOP is hierarchical?
  6. Which aspect of OOP specializes a method so that it can have varied signatures?
  7. Which aspect of OOP "hides" data and behavior?
  8. Match the word with the correct definition:

    (1) block
    (2) parse
    (3) compile
    (4) comment

    (a) to process the syntax of tokens in source code
    (b) to convert source code to byte code
    (c) the section of code to treat as a single statement, even if it has multiple lines
    (d) the part of the source code that does not become byte code

Object-Oriented Programming -- with more examples

Class: its form and examples

INTRODUCTION: A class is the basic form of encapsulating the logic of an object-oriented program. The compilation unit assumes the existence of a class. The compiler outputs a class file. Let's look at what is a class by looking at the example of a box.

Just as integer (int) and boolean are data types, so each object is an instance of a particular class.
The class to which an object belongs is its type.
When you define a class, you are essentially creating a custom data type.
(In this sense, object-oriented programming allows you to extend the programming language!)

Each an every object is an instance of a class. A class is a template for creating objects.

A class has attributes (properties) and behavior (methods).

The Unified Modeling Language (UML) is an industry-standard set of conventions for designing and analyzing classes.
Note in the diagram below the convention of putting the class name at the top, followed by a section for properties (nouns), and at the bottom a section for methods (verbs).

http://www.agilemodeling.com/style/classDiagram.htm

(If you are interested in UML, see http://www.rational.com/uml/leaders/index.jsp)

What does the following code snippet do?

class Box {
   double width;
   double height;
   double depth;
}

In the class declaration, we create no object! There is only logic, no embodiment, no instance.

Because Java is a strongly-typed language, we need to declare the data type of each instance variable in a class.
And, each instance (each object) of the class has its own copy of the classes instance variables.
Think of it this way: if I have a blueprint for a house with three bedrooms and two bathrooms, each house I build with the blueprint will have three bedrooms and two bathrooms.

Declaring Objects

Box myBox; // declares an instance variable that holds the value null
mybox = new Box(); // calls the constructor and allocates memory to a new object (instance)
                   // that inherits the properties and methods of the class template

Note: The primitive data types, such as int, do not require the new operator because they are not objects. Indeed, they store their value directly.
However, a string is an object, yet you have declared String myString without having to use the new operator.
This is a convenience to you.

Just as primitive variables can be declared, and later assigned values, so object types can be declared, and later instantiated.

Assign Object Reference Variables

We saw already that two String objects are two separate objects, even if they hold the same value.

Comparing objects

This like saying:

Box b1 = new Box():
Box b2 = new Box();

On the other hand, if we say

Box b1 = new Box();
b2 = b1;

then b2 refers to the same single box object that b1 does.
Because there are two references to one object, either "handle" can modify the object they both point to.
What happens if we now say this:

Circle b2 = new Circle();

Do b2 and b1 still point to the same object, or has the most recent assignment pointed the two instance variables to different objects?
Do b2 and b2 still refer to objects of the same type or class?

Let's examine this example.

The output is:

Volume is 3000.0
Volume is 162.0

What happens in line 12? Line 13? How does mybox1 get a width variable?

Methods

This example both defines a class and a method for that class.
Which instances of the class inherit the method?

What is going on in this example?

Let's examine the formal parameters to the method that sets the dimensions of the box as runtime arguments.

Note: formal parameters involve declarations of type while runtime arguments involve concrete assignments.


Example of a Vehicle

Different instances of the same class can have different data. To create a second instance of the same class, you must re-use the new operator.


object creation

The new operator dynamically allocates memory for the newly-created object. Objects are created in memory at run-time not compile-time.

What enables me to call methods on the hw object?


 Main: Driver for Other Classes

 

 

 

 


Reference Variable Assignment (p. 121)

The primitive types have copy by value by object types have copy by reference (additional assignment results in two references pointing to the same place in memory)

int myInt = 14;
int yourInt = myInt; // independent copy

car myCar = new Car();
car yourCar = myCar; // no new object created

myCar and yourCar are two reference variables, two handles on the same object, like two horns on the same bull.

Another example of how the value of a field follows the object reference.

Copy by value (primitive) versus copy by reference (object)

Java stores each primitive type in a fixed amount of memory and Java directly manipulates the values for primitives. 

However, objects and arrays do not have a standard size, and they can become large, complex, and slow to initialize.
Java economizes memory and boosts performance by manipulating these "reference types" (objects) by reference.
(Unlike C or C++, Java does not have pointers, but a variable is a named location in memory and is internally implemented by a pointer.)

Although the reference types do not have a standard size, the references to reference types do have a standard size.

Reference types differ from primitives in the way values are copied and compared.

Let's look at a diagram: http://www.cse.ucsc.edu/~charlie/classes/60g/fall96/notes/node16.html


methods, return values, parameters

Methods are often used to get and set the value of properties.

It is logical that the range() method be encapsulated within the Vehicle class rather than located in the main of the driver class. The class with main should drive the application and let each of the other classes take care of their own logical business. The range() method has a return type of void because it does not return any object or primitive data type. Instead, it makes a call to a method: println().

We can rewrite this method to have a return type of integer.


return keyword

The flow of execution returns to the caller of a method when all the lines of the method have been executed or the return keyword is encountered.
The range() method returns a value, so the keyword return is necessary.
The Java compiler enforces your intention to get a value from the method you declare.

Return with a void method

The return keyword can also be used with a void method. The same effect occurs in the flow of execution: back to the caller of the method. If the method is void, no return value is delivered to the caller, but the caller is still the location for execution to execution to flow from.

This topic is also covered at http://java.sun.com/docs/books/tutorial/java/nutsandbolts/branch.html


adding parameters to a method

A method can be defined to take zero, one, or many formal parameters (line 3).
At runtime, the arguments passed to the method (lines 13, 15, 17) must match the formal parameter definition.

Here, a method is defined with two parameters.

Let's apply the concept of the parameterized method to the Vehicle class.


Review and summary example


constructors

The constructor is for initialization at object-creation time. It looks like a method but it has no return type and it must have the same name and case (capitalization) as the class for which it is used to initialized objects. The default constructor takes no runtime argument is available automatically.

However, if you define a constructor, the default constructor is no longer available. You can, however, define a custom constructor that has no formal parameter.


parameterized constructors

Although a constructor is NOT a method, constructors and methods are two kinds of class members that can be defined with formal parameters and that can take arguments at runtime.

Let's apply the concept of a parameterized constructor to the Vehicle class.


new operator for objects and stack versus heap

HelloWorld hw = new HelloWorld();

The new operator allocates a new area of memory for the newly created object to use. The constructor does initialization for the newly created object.

Stack = primitive and fast

We do not need the constructor or the new operator for primitive operations. It is faster to work with primitive types. They reside in a last-in/first-out (LIFO) data structure called the stack.

Heap = complex and slow

Objects live in a different type of memory area called the heap. The overhead for creating and managing objects might be considered similar to the overhead of creating a spreadsheet or table to track all the members of the class. We might consider each object to be a row in the spreadsheet or table.


garbage collection and finalize

Demonstrate the periodic process of the JVM freeing memory if an object no longer has a reference to it. It would not be efficient to clean up memory constantly. The JVM might wait until ten thousand or twenty thousand objects are ready for clean up. A use case for the finalize() method is to close a file or database connection so that object destruction is clean.


this keyword is a reference to the current object

Typically, within an object's method body you can refer directly to the object's member variables.
However, sometimes you need to specify the member variable name if one of the arguments to the method has the same name.

For example, the following constructor for the HSBColor class initializes some of an object's member variables according to the arguments passed to the constructor.
Each argument to the constructor has the same name as the object's member variable whose initial value the argument contains.

class HSBColor {
    int hue, saturation, brightness;
    HSBColor (int hue, int saturation, int brightness) { // arguments
        this.hue = hue;  // this.hue refers to the member variable
        this.saturation = saturation;
        this.brightness = brightness;
    }

You must use the this keyword in this constructor because you have to distinguish the argument hue from the member variable hue (and so on with the other arguments). Writing hue = hue; makes no sense. Argument names take precedence and hide member variables with the same name. So to refer to the member variable you must do so through the current object--using the this keyword to refer to the current object--explicitly (and using the dot operator).

Some programmers prefer to always use the this keyword when referring to a member variable of the object whose method the reference appears. In their view, this makes the intent of the code explicit and reduces errors based on name sharing.

You can also use the this keyword to call one of the current object's methods. Again this is only necessary if there is some ambiguity in the method name and is often used to make the intent of the code clearer.

The keyword this is used implicitly by Java to refer to the current object.

Here, we use this explicitly to distinguish between a class property and a local variable


Quiz: Session 4

  1. A string has the length() method to represent that number of characters, but an array has the ________ field to represent the number of elements.

  2. Another name for an instance variable is data, attribute, field, or p______________.

  3. Other languages use the term "function" or "procedure", but the term in Java for the code that defines behavior on an object is method, and the method name should not be a noun but rather a ___________.

  4. A constructor's name must match that of the ___________ for which it performs initialization.

  5. By convention, a method name begins with a ___________ letter while a constructor name begins with a _________ letter.

  6. What does the keyword return do to the execution of a method that is void? What if the method is not void?

  7. True or False: Like a void method, a constructor must specify a return value of void.

  8. If a formal parameter is specified in a method definition, a call to that method must include a runtime _____________ of a matching data type.

  9. The new operator allocates memory for a newly created __________.

  10. To call a method on an object (or of a class), or to access the instance variables of an object (or static variables of a class), use the _____ operator.


In-Class Exercise

Use the following class as a template to experiment with making your own classes.
One possibility: Shape, and then “class Circle extends Shape” to calculate area and perimeter.

// This program uses a parameterized method.

class Box {
   double width; // declare
   double height;
   double depth;

   // compute and return volume
   double volume() { // declare a method
   return width * height * depth;
   }

   // sets dimensions of box
   void setDim(double w, double h, double d) { // defining
   width = w;
   height = h;
   depth = d;
   }
}

class BoxDemoParam {
   public static void main(String args[]) {
   Box mybox1 = new Box(); // create a box object
   Box mybox2 = new Box(); // create another box object
   double vol;

   // initialize each box
   mybox1.setDim(10, 20, 15);
   mybox2.setDim(3, 6, 9);

   // get volume of first box
   vol = mybox1.volume();
   System.out.println("Volume is " + vol);

   // get volume of second box
   vol = mybox2.volume();
   System.out.println("Volume is " + vol);
   }
}