
- •Contents at a Glance
- •Contents
- •About the Authors
- •About the Technical Reviewer
- •Acknowledgments
- •Introduction
- •Oracle Java Certifications: Overview
- •FAQ 1. What are the different levels of Oracle Java certification exams?
- •FAQ 4. Is OCPJP 7 prerequisite for other Oracle certification exams?
- •FAQ 5. Should I take the OCPJP 7 or OCPJP 6 exam?
- •The OCPJP 7 Exam
- •FAQ 7. How many questions are there in the OCPJP 7 exam?
- •FAQ 8. What is the duration of the OCPJP 7 exam?
- •FAQ 9. What is the cost of the OCPJP 7 exam?
- •FAQ 10. What are the passing scores for the OCPJP 7 exam?
- •FAQ 11. What kinds of questions are asked in the OCPJP 7 exam?
- •FAQ 12. What does the OCPJP 7 exam test for?
- •FAQ 13. I’ve been a Java programmer for last five years. Do I have to prepare for the OCPJP 7 exam?
- •FAQ 14. How do I prepare for the OCPJP 7 exam?
- •FAQ 15. How do I know when I’m ready to take the OCPJP 7 exam?
- •Taking the OCPJP 7 Exam
- •FAQ 16. What are my options to register for the exam?
- •FAQ 17. How do I register for the exam, schedule a day and time for taking the exam, and appear for the exam?
- •The OCPJP 7 Exam: Pretest
- •Answers with Explanations
- •Post-Pretest Evaluation
- •Essentials of OOP
- •FunPaint Application: An Example
- •Foundations of OOP
- •Abstraction
- •Encapsulation
- •Inheritance
- •Polymorphism
- •Class Fundamentals
- •Object Creation
- •Constructors
- •Access Modifiers
- •Public Access Modifier
- •Private Access Modifier
- •Protected and Default Access Modifier
- •Overloading
- •Method Overloading
- •Constructor Overloading
- •Overload resolution
- •Points to Remember
- •Inheritance
- •Runtime Polymorphism
- •An Example
- •Overriding Issues
- •Overriding: Deeper Dive
- •Invoking Superclass Methods
- •Type Conversions
- •Upcasts and Downcasts
- •Casting Between Inconvertible Types
- •Using “instanceof” for Safe Downcasts
- •Java Packages
- •Working with Packages
- •Static Import
- •Summary
- •Abstract Classes
- •Points to Remember
- •Using the “final” Keyword
- •Final Classes
- •Final Methods and Variables
- •Points to Remember
- •Using the “static” Keyword
- •Static Block
- •Points to Remember
- •Flavors of Nested Classes
- •Static Nested Classes (or Interfaces)
- •Points to Remember
- •Inner Classes
- •Points to Remember
- •Local Inner Classes
- •Points to Remember
- •Anonymous Inner Classes
- •Points to Remember
- •Enum Data Types
- •Points to Remember
- •Summary
- •Interfaces
- •Declaring and Using Interfaces
- •Points to Remember
- •Abstract Classes vs. Interfaces
- •Choosing Between an Abstract Class and an Interface
- •Object Composition
- •Composition vs. Inheritance
- •Points to Remember
- •Design Patterns
- •The Singleton Design Pattern
- •Ensuring That Your Singleton Is Indeed a Singleton
- •The Factory Design Pattern
- •Differences Between Factory and Abstract Factory Design Patterns
- •The Data Access Object (DAO) Design Pattern
- •Points to Remember
- •Summary
- •Generics
- •Using Object Type and Type Safety
- •Using the Object Class vs. Generics
- •Container Implementation Using the Object Class
- •Container Implementation Using Generics
- •Creating Generic Classes
- •Diamond Syntax
- •Interoperability of Raw Types and Generic Types
- •Generic Methods
- •Generics and Subtyping
- •Wildcard Parameters
- •Limitations of Wildcards
- •Bounded Wildcards
- •Wildcards in the Collections Class
- •Points to Remember
- •The Collections Framework
- •Why Reusable Classes?
- •Basic Components of the Collections Framework
- •Abstract Classes and Interfaces
- •Concrete Classes
- •List Classes
- •ArrayList Class
- •The ListIterator Interface
- •The LinkedList Class
- •The Set Interface
- •The HashSet Class
- •The TreeSet Class
- •The Map Interface
- •The HashMap Class
- •Overriding the hashCode() Method
- •The NavigableMap Interface
- •The Queue Interface
- •The Deque Interface
- •Comparable and Comparator Interfaces
- •Algorithms (Collections Class)
- •The Arrays Class
- •Methods in the Arrays Class
- •Array as a List
- •Points to Remember
- •Summary
- •Generics
- •Collections Framework
- •Processing Strings
- •String Searching
- •The IndexOf() Method
- •The regionMatches() Method
- •String Parsing
- •String Conversions
- •The Split() Method
- •Regular Expressions
- •Understanding regex Symbols
- •Regex Support in Java
- •Searching and Parsing with regex
- •Replacing Strings with regex
- •String Formatting
- •Format Specifiers
- •Points to Remember
- •Summary
- •Reading and Writing from Console
- •Understanding the Console Class
- •Formatted I/O with the Console Class
- •Special Character Handling in the Console Class
- •Using Streams to Read and Write Files
- •Character Streams and Byte Streams
- •Character Streams
- •Reading Text Files
- •Reading and Writing Text Files
- •“Tokenizing” Text
- •Byte Streams
- •Reading a Byte Stream
- •Data Streams
- •Writing to and Reading from Object Streams: Serialization
- •Serialization: Some More Details
- •Points to Remember
- •Summary
- •A Quick History of I/O APIs
- •Using the Path Interface
- •Getting Path Information
- •Comparing Two Paths
- •Using the Files Class
- •Checking File Properties and Metadata
- •Copying a File
- •Moving a File
- •Deleting a File
- •Walking a File Tree
- •Revisiting File Copy
- •Finding a File
- •Watching a Directory for Changes
- •Points to Remember
- •Summary
- •Introduction to JDBC
- •The Architecture of JDBC
- •Two-Tier and Three-Tier JDBC Architecture
- •Types of JDBC Drivers
- •Setting Up the Database
- •Connecting to a Database Using a JDBC Driver
- •The Connection Interface
- •Connecting to the Database
- •Statement
- •ResultSet
- •Querying the Database
- •Updating the Database
- •Getting the Database Metadata
- •Points to Remember
- •Querying and Updating the Database
- •Performing Transactions
- •Rolling Back Database Operations
- •The RowSet Interface
- •Points to Remember
- •Summary
- •Define the Layout of the JDBC API
- •Connect to a Database by Using a JDBC driver
- •Update and Query a Database
- •Customize the Transaction Behavior of JDBC and Commit Transactions
- •Use the JDBC 4.1 RowSetProvider, RowSetFactory, and RowSet Interfaces
- •Introduction to Exception Handling
- •Throwing Exceptions
- •Unhandled Exceptions
- •Try and Catch Statements
- •Programmatically Accessing the Stack Trace
- •Multiple Catch Blocks
- •Multi-Catch Blocks
- •General Catch Handlers
- •Finally Blocks
- •Points to Remember
- •Try-with-Resources
- •Closing Multiple Resources
- •Points to Remember
- •Exception Types
- •The Exception Class
- •The RuntimeException Class
- •The Error Class
- •The Throws Clause
- •Method Overriding and the Throws Clause
- •Points to Remember
- •Custom Exceptions
- •Assertions
- •Assert Statement
- •How Not to Use Asserts
- •Summary
- •Introduction
- •Locales
- •The Locale Class
- •Getting Locale Details
- •Resource Bundles
- •Using PropertyResourceBundle
- •Using ListResourceBundle
- •Loading a Resource Bundle
- •Naming Convention for Resource Bundles
- •Formatting for Local Culture
- •The NumberFormat Class
- •The Currency Class
- •The DateFormat Class
- •The SimpleDateFormat Class
- •Points to Remember
- •Summary
- •Introduction to Concurrent Programming
- •Important Threading-Related Methods
- •Creating Threads
- •Extending the Thread Class
- •Implementing the Runnable Interface
- •The Start( ) and Run( ) Methods
- •Thread Name, Priority, and Group
- •Using the Thread.sleep() Method
- •Using Thread’s Join Method
- •Asynchronous Execution
- •The States of a Thread
- •Two States in “Runnable” State
- •Concurrent Access Problems
- •Data Races
- •Thread Synchronization
- •Synchronized Blocks
- •Synchronized Methods
- •Synchronized Blocks vs. Synchronized Methods
- •Deadlocks
- •Other Threading Problems
- •Livelocks
- •Lock Starvation
- •The Wait/Notify Mechanism
- •Let’s Solve a Problem
- •More Thread States
- •timed_waiting and blocked States
- •waiting State
- •Using Thread.State enum
- •Understanding IllegalThreadStateException
- •Summary
- •Using java.util.concurrent Collections
- •Semaphore
- •CountDownLatch
- •Exchanger
- •CyclicBarrier
- •Phaser
- •Concurrent Collections
- •Apply Atomic Variables and Locks
- •Atomic Variables
- •Locks
- •Conditions
- •Multiple Conditions on a Lock
- •Use Executors and ThreadPools
- •Executor
- •Callable, Executors, ExecutorService, ThreadPool, and Future
- •ThreadFactory
- •The ThreadLocalRandom Class
- •TimeUnit Enumeration
- •Use the Parallel Fork/Join Framework
- •Useful Classes of the Fork/Join Framework
- •Using the Fork/Join Framework
- •Points to Remember
- •Summary
- •Using java.util.concurrent Collections
- •Applying Atomic Variables and Locks
- •Using Executors and ThreadPools
- •Using the Parallel Fork/Join Framework
- •Chapter 3: Java Class Design
- •Chapter 4: Advanced Class Design
- •Chapter 5: Object-Oriented Design Principles
- •Chapter 6: Generics and Collections
- •Chapter 7: String Processing
- •Chapter 8: Java I/O Fundamentals
- •Chapter 9: Java File I/O (NIO.2)
- •Chapter 10: Building Database Applications with JDBC
- •Chapter 11: Exceptions and Assertions
- •Chapter 12: Localization
- •Chapter 13: Threads
- •Chapter 14: Concurrency
- •OCPJP7 Exam (1Z0-804 a.k.a. Java SE 7 Programmer II) Topics
- •OCPJP 7 Exam (1Z0-805, a.k.a. Upgrade to Java SE 7 Programmer) Topics
- •Answers and Explanations
- •Answer Sheet
- •Answers and Explanations
- •Index

Chapter 3 ■ Java Class Design
Essentials of OOP
To get a sense of the world of object-oriented programming, take a mental stroll around the television department of your local consumer electronics retailer. A television is an abstraction that offers certain functionality through the
proper interface (a TV remote). As a viewer, you need not understand how the TV works; the TV abstracts all the finergrain details of its operation from the viewer (abstraction). A television object encapsulates properties of the television (such as brightness, channel number, and volume) and associated behavior to control these properties in a single entity (encapsulation). In other words, the access to these properties is restricted to the associated operations. There are different types of televisions, such as CRT television, LED television, and LCD television; they belong to a single family forming an inheritance hierarchy. Although all types of televisions support “display” functionality, the internal technology enabling the display of content may differ (polymorphism).
With this television analogy in mind and with the help of the programming example introduced in the next section, let’s review the essential OOP concepts.
FunPaint Application: An Example
Let’s assume that you are implementing a simple drawing program for children called FunPaint (Figure 3-1). Users can drag and drop basic shapes like circles and squares, color them, and create drawings using those shapes.
Figure 3-1. A children’s drawing application implemented using OOP concepts
We’ll use this example throughout this chapter to illustrate how OOP concepts can be used effectively for real-world programming and problem solving. For now, assume that the shapes such as Circle and Square are implemented as classes. A user can click on the circle icon and draw a circle in the drawing pane. With a circle, you need to remember associated information like center of the circle, radius of the circle, etc. To enable the user to color a circle, you need to calculate its area. Next you’ll look at how OOP concepts can be used to implement FunPaint functionality.
Foundations of OOP
Object orientation is built on the foundations of encapsulation, abstraction, inheritance, and polymorphism. The following sections refresh your understanding of each of these four concepts.
46

Chapter 3 ■ Java Class Design
Abstraction
The Latin root of abstraction means “taking away”—you take away everything except the specific aspect you wish to focus on. In other words, abstraction means hiding lower-level details and exposing only the essential and relevant details to the users.
For example, in order to drive a car, it is sufficient for a driver to have an essential repertoire of skills enabling her to interface with the car’s steering, gear shifting, dashboard, braking, and accelerator systems. For the driver, it is
superfluous to know the internal implementation details, such as how fuel is injected into the combustion chamber or how batteries are charged indirectly by the engine. The driver as such is concerned only about using the car and not about how the car works and provides functionality to the driver. In other words, a car abstracts the internal details and exposes to the driver only those details that are relevant to the interaction of the driver with the car.
In the FunPaint example, you define operations such as draw() and fillColor(). The user of the class Circle does not need to know how the class is drawing a circle or filling the circle with a specific color. In other words, you are abstracting the details of the class by hiding the implementation details.
Encapsulation
Structured programming decomposes the program’s functionality into various procedures (functions), without much concern about the data each procedure can work with. Functions are free to operate and modify the (usually global and unprotected) data.
In OOP, data and functions operating on that data are combined together to form a single unit, which is referred to as a class. The term encapsulation refers to combining data and associated functions as a single unit. For example, in the Circle class, radius and center are defined as private fields. Now you can adduce methods draw() and fillColor() along with fields radius and center, since the fields and methods are closely related to each other. All the data (fields) required for the methods in the class are available inside the class itself. In other words, the class encapsulates its fields and methods together.
encapsulation combines data (fields) and logically-related operations (methods). abstraction hides internal implementation level details and exposes only the relevant details of the class to the users. abstraction is achieved through encapsulation.
Inheritance
Inheritance is a reusability mechanism in object-oriented programming in which the common properties of various objects are exploited to form relationships with each other. The abstract and common properties are provided in the superclass, which is available to the more specialized subclasses. For example, a color printer and a black-and-white printer are kinds of a printer (single inheritance); an all-in-one printer is a printer, scanner, and photocopier (multiple inheritance). It should be noted that Java does not support multiple inheritance but does support multiple-interface inheritance (discussed in detail in Chapters 4 and 5).
When we say that a class B is inherited from another class A, then class B is referred to as a derived class
(or subclass) and class A is called as a base class (or superclass). By inheritance, the derived class receives the behavior of the base class, such that all the visible member methods and variables of the base class are available in the derived class. Apart from the inherited behavior, the derived class specializes its behavior by adding to or overriding base class behavior.
In FunPaint, the user can draw different shapes. Though the shapes are different, all shapes support similar functionality—for instance, color-filling and finding the area of the shape. Since these methods are common to all the shape classes, you can have a base class called Shape and declare these methods in this class. Other classes such as Circle and Triangle inherit from Shape and implement their specialized behavior.
47