2. What are Classes?
In the real world, you'll often find many individual objects all
of the same kind. There may be thousands of other bicycles in
existence, all of the same make and model. Each bicycle was
built from the same set of blueprints and therefore contains
the same components. In object-oriented terms, we say that
your bicycle is an instance of the class of objects known as
bicycles. A class is the blueprint from which individual objects
are created.
Theandroid-mania.com
3. Declaring a class
class Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
void changeGear(int newValue) {
gear = newValue;
}
Theandroid-mania.com
5. Object-Oriented Programming consists of 3 primary ideas:
Data Abstraction and Encapsulation
Operations on the data are considered to be part of the data type
We can understand and use a data type without knowing all of its
implementation details
Neither how the data is represented nor how the operations are
implemented
We just need to know the interface (or method headers) – how to
“communicate” with the object
Compare to functional abstraction with methods
Theandroid-mania.com
6. Inheritance
Properties of a data type can be passed down to a sub-type – we can
build new types from old ones
We can build class hierarchies with many levels of inheritance
We will discuss this more in Chapter 8
Polymorphism
Operations used with a variable are based on the class of the object
being accessed, not the class of the variable
Parent type and sub-type objects can be accessed in a consistent way
Theandroid-mania.com
7. Consider primitive types
Each variable represents a single, simple data value
Any operations that we perform on the data are external to that
data
X + Y
Theandroid-mania.com
8. Objects and Data Abstraction
Consider the data
In many applications, data is more complicated than just a simple
value
Ex: A Polygon – a sequence of connected points
The data here are actually:
int [] xpoints – an array of x-coordinates
int [] ypoints – an array of y-coordinates
int npoints – the number of points actually in the Polygon
Note that individually the data are just ints
However, together they make up a Polygon
This is fundamental to object-oriented programming (OOP)
Theandroid-mania.com
9. Objects and Data Abstraction
Consider the operations
Now consider operations that a Polygon can do
Note how that is stated – we are seeing what a Polygon CAN DO rather than
WHAT CAN BE DONE to it
This is another fundamental idea of OOP – objects are ACTIVE rather than
PASSIVE
Ex:
void addPoint(int x, int y) – add a new point to Polygon
boolean contains(double x, double y) – is point (x,y) within the boundaries of the
Polygon
void translate(int deltaX, int deltaY) – move all points in the Polygon by deltaX and
deltaY
Theandroid-mania.com
10. Objects and Data Abstraction
These operations are actually (logically) PART of the Polygon itself
int [] theXs = {0, 4, 4};
int [] theYs = {0, 0, 2};
int num = 2;
Polygon P = new Polygon(theXs, theYs, num);
P.addPoint(0, 2);
if (P.contains(2, 1))
System.out.println(“Inside P”);
else
System.out.println(“Outside P”);
P.translate(2, 3);
We are not passing the Polygon as an argument, we are calling the methods
FROM the Polygon
Theandroid-mania.com
11. Objects and Data Abstraction
• Objects enable us to combine the data and operations of a type
together into a single entity
xpoints [0,4,4,0]
ypoints [0,0,2,2]
npoints 4
addPoint()
contains()
translate()
Thus, the operations
are always implicitly
acting on the
object’s data
Ex: translate means
translate the points
that make up P
Theandroid-mania.com
12. Encapsulation and
Data Abstraction
Recall that we previously discussed data abstraction
We do not need to know the implementation details of a data type in
order to use it
This includes the methods AND the actual data representation of the object
This concept is exemplified through objects
We can think of an object as a container with data and operations inside
We can see some of the data and some of the operations, but others are kept
hidden from us
The ones we can see give us the functionality of the objects
Theandroid-mania.com
13. Encapsulation and
Data Abstraction
As long as we know the method names, params and how to
use them, we don’t need to know how the actual data is
stored
Note that I can use a Polygon without knowing how the data is stored
OR how the methods are implemented
I know it has points but I don’t know how they are stored
Data Abstraction!
Theandroid-mania.com
14. Instance variables
Let’s look again at StringBuffer
Instance Variables
These are the data values within an object
Used to store the object’s information
As we said previously, when using data abstraction we don’t need to know
explicitly what these are in order to use a class
For example, look at the API for StringBuffer
Note that the instance variables are not even shown there
In actuality it is a variable-length array with a counter to keep track of how
many locations are being used and is actually inherited from
AbstractStringBuilder
Theandroid-mania.com
15. Instance variables
Many instance variables are declared with the keyword private
This means that they cannot be directly accessed outside the class itself
Instance variables are typically declared to be private, based on the data
abstraction that we discussed earlier
Recall that we do not need to know how the data is represented in order to
use the type
Therefore why even allow us to see it?
In AbstractStringBuilder the value variable has no keyword modifier
This makes it private to the package
Theandroid-mania.com
16. Class Methods
vs. Instance Methods
Recall that methods we discussed before were called class methods
(or static methods)
These were not associated with any object
Now, however we WILL associate methods with objects (as shown
with Polygon)
These methods are called instance methods because they are
associated with individual instances (or objects) of a class
StringBuffer B = new StringBuffer(“this is “);
B.append(“really fun stuff!”);
System.out.println(B.toString());
Theandroid-mania.com
17. Class Methods
vs. Instance Methods
Class methods have no implicit data to act on
All data must be passed into them using arguments
Class methods are called using:
ClassName.methodName(param list)
Instance methods have implicit data associated with an Object
Other data can be passed as arguments, but there is always an underlying
object to act upon
Instance methods are called using:
VariableName.methodName(param list)
Theandroid-mania.com
18. Constructors,
Accessors and Mutators
Instance methods can be categorized by what they are
designed to do:
Constructors
These are special instance methods that are called when an object is first
created
They are the only methods that do not have a return value (not even void)
They are typically used to initialize the instance variables of an object
StringBuffer B = new StringBuffer(“hello there”);
B = new StringBuffer(); // default constructor
B = new StringBuffer(10); // capacity 10
Theandroid-mania.com
19. Constructors,
Accessors and Mutators
Accessors
These methods are used to access the object in some way without changing it
Usually used to get information from it
No special syntax – categorized simply by their effect
StringBuffer B = new StringBuffer(“hello there”);
char c = B.charAt(4); // c == ‘o’
String S = B.substring(3, 9); // S == “lo the”
// note that end index is NOT inclusive
int n = B.length(); // n == 11
These methods give us information about the StringBuffer without revealing the
implementation details
Theandroid-mania.com
20. Constructors,
Accessors and Mutators
Mutators
Used to change the object in some way
Since the instance variables are usually private, we use mutators to change the
object in a specified way without needing to know the instance variables
B.setCharAt(0, ‘j’); // B == “jello there”
B.delete(5,6); // B == “jello here”
B.insert(6, “is “); // B == “jello is here”;
These methods change the contents or properties of the StringBuffer object
We use accessors and mutators to indirectly access the data, since
we don’t have direct access – see ex12.java
Theandroid-mania.com
21. Simple Class Example
We can use these ideas to write our own classes
Let’s look a VERY simple example:
A circle constricted to an integer radius
IntCircle
Instance variable: private int radius
Cannot directly access it from outside the class
Constructor: take an int argument and initialize a new circle with the given
radius
Accessors:
public double area();
public double circumference();
public String toString();
Mutator:
public void setRadius(int newRadius);
Theandroid-mania.com
22. More on Classes and Objects
Classes
Define the nature and properties of objects
Objects
Instances of classes
Let’s learn more about these by developing another example
together
Goal:
Write one or more classes that represent a CD (compact disc)
Write a simple driver program to test it
Theandroid-mania.com
23. Wrappers
Much useful Java functionality relies on classes / objects
Inheritance (Chapter 8)
Polymorphic access (Chapter 9)
Interfaces (Chapter 6)
Unfortunately, the Java primitive types are NOT classes, and
thus cannot be used in this way
If I make an array of Object or any other class, primitive types cannot
be stored in it
Theandroid-mania.com
24. Wrappers
Wrapper classes allow us to get around this problem
Wrappers are classes that “wrap” objects around primitive values, thus making
them compatible with other Java classes
We can't store an int in an array of Object, but we could store an Integer
Each Java primitive type has a corresponding wrapper
Ex: Integer, Float, Double, Boolean
Ex: Integer i, j, k;
i = new Integer(20);
j = new Integer(40);
Theandroid-mania.com
25. Wrappers
The wrapper classes also provide extra useful functionality for
these types
Ex: Integer.parseInt() is a static method that enables us to convert from a
String into an int
Ex: Character.isLetter() is a static method that tests if a letter is a character
or not
Theandroid-mania.com
26. However, arithmetic operations are not defined for wrapper
classes
So if we want to do any “math” with our wrappers, we need to get the
underlying primitive values
If we want to keep the wrapper, we then have to wrap the result back up
Logically, to do the following:
k = i + j;
The actual computation being done is
k = new Integer(i.intValue() + j.intValue());
In words: Get the primitive value of each Integer object, add them, then
create a new Integer object with the result
Theandroid-mania.com
27. However, arithmetic operations are not defined for wrapper classes
So if we want to do any “math” with our wrappers, we need to get the
underlying primitive values
If we want to keep the wrapper, we then have to wrap the result back up
Logically, to do the following:
k = i + j;
The actual computation being done is
k = new Integer(i.intValue() + j.intValue());
In words: Get the primitive value of each Integer object, add them, then create a
new Integer object with the result
Theandroid-mania.com
28. In Java 1.4 and before:
Programmer had to do the conversions explicitly
Painful!
In Java 1.5 autoboxing was added
This does the conversion back and forth automatically
Saves the programmer some keystrokes
However, the work STILL IS DONE, so from an efficiency point of view we are
not saving
Should not use unless absolutely needed
We will see more on how wrappers are useful after we discuss
inheritance, polymorphism and interfaces
Theandroid-mania.com