java primer

187
A Java Primer Author: Banji Lawal October 22, 2011

Upload: john-piercy

Post on 07-Oct-2014

221 views

Category:

Documents


8 download

TRANSCRIPT

A Java Primer

Author: Banji Lawal

October 22, 2011

2

Contents

1 Configuring Eclipse 13

1.1 Downloading And Installing Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141.1.1 Downloading & Installing Eclipse For Linux . . . . . . . . . . . . . . . . . . . . . . . . 14

1.2 Writing Your First Java Program With Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . 141.3 Layout Of Eclipse Workbench . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

1.3.1 Perspectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171.3.2 Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171.3.3 Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1.4 Commonly Used Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171.4.1 Views Dealing Directory Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171.4.2 Navigator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171.4.3 Views Dealing With Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171.4.4 Views Dealing With Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.4.5 Views Dealing With Program Components . . . . . . . . . . . . . . . . . . . . . . . . 181.4.6 Views Dealing With Execution/Testing . . . . . . . . . . . . . . . . . . . . . . . . . . 181.4.7 Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.4.8 Customizing Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

1.5 Some Helpful Editor Customizations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.5.1 Setting Autocompletion Time out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.5.2 Setting Word Wrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.5.3 Folding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

1.6 Eclipse Keyboard Shortcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.7 Saving Your Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.8 Eclipse Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2 Introduction 21

2.1 What is Java? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.1.1 Java Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.2 Components Of Java Standard Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.2.1 Tools & Tool APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.2.2 Java Runtime Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.3 Java Objects, Classes & Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3

2.4 Layout of a Java Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.5 Java Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.5.1 Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.5.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.6 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262.7 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2.7.1 Precedence Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272.8 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3 Basic Console Input/Output 29

3.1 Java Print Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293.1.1 Print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293.1.2 Printf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313.1.3 Println . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.2 The Scanner Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4 Flow of Control 35

4.1 Java Branching Mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354.1.1 The If Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354.1.2 If-Else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364.1.3 Boolean Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384.1.4 Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4.2 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444.2.1 While Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444.2.2 Do-While Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454.2.3 For Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

5 Methods 51

5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.2 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545.3 The Method Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

5.3.1 Modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545.3.2 Return Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545.3.3 Method Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555.3.4 Parameter List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

5.4 The Method Body . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555.5 Invoking Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565.6 Scope Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575.7 Function Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

5.7.1 How The Interpreter Evaluates Overloaded Functions . . . . . . . . . . . . . . . . . . 645.8 Documenting Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

5.8.1 Using Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655.9 Tips For Using Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

4

5.9.1 One Task Per Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.9.2 Brevity Is Best . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.9.3 Don’t Overdo Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.9.4 Debug As You Go . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.9.5 Provide Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.9.6 When There Is Repetition Use A Function . . . . . . . . . . . . . . . . . . . . . . . . 68

5.10 Advantages Of Using Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

6 Objects And Classes 71

6.1 Components Of A Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716.1.1 Instance Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756.1.2 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756.1.3 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

6.2 Creating An Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766.3 Static versus Nonstatic Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786.4 Pass By Value Versus Pass By Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

6.4.1 Pass By Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786.4.2 Pass By Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

6.5 Anonymous Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806.6 Packages & Classpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

6.6.1 Classpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816.6.2 Making Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816.6.3 Marking Classes As Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

7 Arrays 85

7.1 Declaring Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 857.1.1 IndexOutBounds Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867.1.2 Char Versus String Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

7.2 Initializing arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867.3 Array Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

7.3.1 Comparing Arrays For Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 937.3.2 Copying Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 937.3.3 Methods With Variable Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

7.4 Referencing Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 947.5 Passing Arguments To Main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 947.6 Enumerated Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 997.7 Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

8 Inheritance 103

8.1 Properties Of Subclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1098.2 Invoking Super Class Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

8.2.1 Reference Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1098.2.2 Protected Instance Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

5

8.3 Invoking A Superclass’ Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

8.3.1 Overriding Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

8.4 The Final Modifier And Its Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

8.4.1 Final Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

8.4.2 Final Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

8.5 Effects of The Static Modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

8.5.1 Static Methods Cannot Be Inherited . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

8.5.2 Static Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

8.6 Accessors That Return Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

9 Polymorphism 117

9.1 Method Binding In Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

9.1.1 Early Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

9.1.2 Late Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

9.2 Upcasting Versus Downcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

9.2.1 Upcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

9.2.2 Downcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

9.2.3 Upcasting/Downcasting Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

9.3 Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

9.3.1 Guidelines For Making A Method Abstract . . . . . . . . . . . . . . . . . . . . . . . . 138

9.3.2 Properties Of Abstract Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

9.3.3 Properties Of Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

9.4 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

9.5 Inner Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

10 Exceptions 153

10.1 Generalized Exception Handling Mechanism . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

10.1.1 Termination Versus Resumption Models Of Exception Handling . . . . . . . . . . . . 153

10.2 Handling Exceptions With If-Else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

10.3 Handling Exceptions With Try-Catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

10.3.1 Try Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

10.3.2 Catch Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

10.4 Handling Exceptions With Try-Catch-Finally . . . . . . . . . . . . . . . . . . . . . . . . . . . 159

10.4.1 Finally Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159

10.4.2 The Difference Between A Try Block & A Try Statement . . . . . . . . . . . . . . . . 161

10.5 Overview Of The Throwable Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

10.6 The Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

10.6.1 Exception’s Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

10.6.2 Exception’s Mutators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

10.6.3 Exception’s Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

10.6.4 Exception’s Commonly Used Subclasses . . . . . . . . . . . . . . . . . . . . . . . . . . 163

10.7 throw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

6

10.7.1 Scope Of Thrown Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16410.8 Using Throws In Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16510.9 Exception Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

10.9.1 Excepetion’s Message Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16610.10Rethrowing Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16710.11Stack Unwinding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16710.12Chained Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16710.13Rolling Your Own Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16810.14Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

11 Debugging 171

11.1 The Debugging Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17111.2 Doing Code Walk Throughs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17111.3 Using Print To Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

11.3.1 Advantages Of Print Statement Debugging . . . . . . . . . . . . . . . . . . . . . . . . 17111.3.2 Disadvantages Of Print Statement Debugging . . . . . . . . . . . . . . . . . . . . . . . 171

11.4 Using Assert To Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17111.5 Debuggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

11.5.1 Stack Tracer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17211.5.2 Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17211.5.3 Profilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17211.5.4 Code Analysis Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

11.6 Using The Eclipse Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17211.6.1 Setting Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17211.6.2 Running The Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17211.6.3 Viewing The Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17211.6.4 Watching Values Of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

12 Unit Testing 173

13 Files 175

14 I/O Streams 177

15 Generics 179

16 Collectors & Iterators 181

17 Threads 183

18 Basic GUI Input/Output 185

19 UML Basics 187

7

8

List of Figures

9

10

List of Tables

2.1 Java Reserved Words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242.2 Java Primitive Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242.3 Binary Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272.4 Arithmetic Operator Precedence Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3.1 Java Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303.2 Java Format Specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4.1 Table4.1: Java Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384.2 Table 4.2: Complete Precedence Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

5.1 GetArea.java’s Layout in RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575.2 Main’s Initial Address Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575.3 Final State Of Area.java’s Method Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

7.1 charArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 857.2 Best Little Joloff Rice House In Texas Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

8.1 Allowed Child Class Access Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

10.1 Unchecked Exceptions Found in RuntimeException . . . . . . . . . . . . . . . . . . . . . . . . 16310.2 Checked Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

11

12

Chapter 1

Configuring Eclipse

Most of the time programmers do not use plain text editors for creating code. The reason why is that mostdevelopment projects entail the following tasks.

• Editing code.

• Compiling the code.

• Maintaining different versions of the source code.

• Tracking changes made by different people.

• Debugging

• Tracing the program’s execution.

Frequently a developer has to do all these things continuously and most text editors do not have the capabilityof doing all these tasks. So many editors such as Notepad, TextEdit, MS Word or are completely unsuitable.There are other editors which such as TextPad, Vim, Emacs, and TextMate which are more appropriate forprogramming and they have numerous plugins that make all the latter group of editors very popular amongprogrammers. However they have some limitations. The main limitations have to deal with standardizationof behaviour and ease of use for a specific language.

The standardization and ease of use can come down to things like the editor doing autocompletion of commonwords, commands and phrases that occur in a language, linking to libraries and placing stubs into code sothat the developer do not have to keep typing the same things over and over again. Most programmer editorssuch as Vim, Emacs, TextPad can do all these things. I actually use Vim for almost everything. Howeverits easier to write Java code using an Integrated Development Environment (IDE). With IDEs you are ableto spend more time on writing actual new code and maintaining your code than with nonIDEs. Also in alarge shop with many programmers its easier to have a standard template and configuration that everyonecan use. The two most popular IDEs for Java are NetBeans and Eclipse. For this class we shall be usingEclipse as the IDE.

13

1.1 Downloading And Installing Eclipse

To get Eclipse goto http://eclipse.org/downloads and select the link Eclipse IDE for Java Develop-

ers. As of this writing the size of the download is 98MB. The website should detect your operating systemand automatically start the download of the appropriate binary.

Installing Eclipse In Windows Or MacOSX

The binaries should be fairly straightforward to install I would recommend consulting the documentationthat comes with your binary and looking at the Eclipse FAQs if you have problems installing the IDE.

1.1.1 Downloading & Installing Eclipse For Linux

Most modern Linux distributions will come bundled with Eclipse. And if they do not your distributionshould have a means of downloading and installing Eclipse and any needed Java packages. If you are usinga RedHat based distro such as Fedora or CentOS its likely that Eclipse can be downloaded via Yum orPackageKit. For Ubuntu use Apt. Its a bad idea to download the Eclipse binaries or tarballs ans installthem since it will make it harder to manage all the packages on your system when you manually install apps.If there are problems consult the documentation for your distro on installing Eclipse.

1.2 Writing Your First Java Program With Eclipse

Once you have installed Eclipse we can create our first Java program to do this we start Eclipse. For nowyou can use the default settings for the workspace. In the future you might decide to change your workspacebut do not worry about that right now.Once the Eclipse is launched click on File → New Java Project then in the Project Name bar put inHelloWorld and click Next and Finish buttons. After doing this you should see the HelloWorld project inthe Project Window list. Right click on HelloWorld project and select New → Class. In the Name field putHelloWorld and check the box for public static void main(String[] args). If you have done everythingcorrectly the only line you will have to add to the program is System.out.println(‘‘Hello world.‘‘);

as seen in

1 /**

2 *

3 */

45 /**

6 * @author griot

7 */

8 public class HelloWorld {

910 /**

11 * @param args

12 */

14

13 public static void main(String [] args) {

14 System.out.print("Hello world.");

1516 }

1718 }

Program 1.1: HelloWorld.java

To run the program you can click on Run → Run and select the Java Application checkbox. In theConsole Window the output will be displayed as seen in Figure 1.1. Instead of clicking on the menu itemsyou can also click on the green play button.

15

1.3 Layout Of Eclipse Workbench

When you start Eclipse, after it has launched and opened your workspace its window is called the workbench.The workbench has the following components;

• Perspectives

• Views

• Editor

16

1.3.1 Perspectives

A collection of Views and an Editor window. A particular perspective is good for creating, testing, main-taining, and running applications made under a language.

1.3.2 Views

These show us information about the program or the results of running an Eclipse command.

1.3.3 Editor

This is where you type the code for your program. Like all editors the program editor does spellcheckingbut it also has some nice features that you will find helpful as you create you programs.

1.4 Commonly Used Views

You can have your views grouped in a section of the workbench by tabs. There are so many views that hereI shall simply describe some of the most frequently used ones by programmers. Which are;

1.4.1 Views Dealing Directory Structure

These have to do with lay out of the program files in the Eclipse workspace.

Package Explorer

Generally all your related programs will be grouped in package. This view shows the things in the package.

Project Explorer

1.4.2 Navigator

1.4.3 Views Dealing With Output

Though we could classify other views under output for now we shall only consider the following.

Console

When the Java program is run without a GUI the output is shown here.

Progress

Shows how the execution is progressing.

17

1.4.4 Views Dealing With Errors

Problems

Things that might keep the program from working. Some of these will be easy to fix and Eclipse will suggestquick fixes for you.

Error Log

Errors are things that happen during compilation.

1.4.5 Views Dealing With Program Components

There are two of these.

Outline

Shows all the functions and the variables that are in the code.

Type Hierarchy

There are differing types of data and this shows the things that make up the data type.

1.4.6 Views Dealing With Execution/Testing

The two main one that we shall deal with are;

JUnit

Used for looking at results of unit tests.

Ant

Used for running Java programs as Ant apps.

1.4.7 Javadoc

Shows the documentation for the program.

1.4.8 Customizing Views

You can customize the layout of your views by moving them, resizing, grouping them, deattaching, andreattaching them to the perspective. For a description on how to do all these things look at the appropriatesections in the Eclipse Help manual that comes with your install.

18

1.5 Some Helpful Editor Customizations

As you use the editor you might find some customizations helpful two of the ones you might like the mostare autocompletion and word wrapping.

1.5.1 Setting Autocompletion Time out

There are lots of words duplicated when we program and they can be fairly long to type. Eclipse willautocomplete for you. It will also autocomplete commands that you invoke.

1.5.2 Setting Word Wrapping

Sometimes when a line is too long Eclipse might decide to break it up. This can cause problems for you sowe can set how word wrapping is done.

1.5.3 Folding

Since programs can be fairly long and we usually only on one section of code many editors will minimizecode blocks, functions or other things to make it easier for us to focus on the section we need to deal with.

1.6 Eclipse Keyboard Shortcuts

The less you use the mouse the faster and more fun you will have developing programs with Eclipse. To dothis it will be helpful to learn the shortcuts for common task such as saving files, compiling. The table belowshows them.

1.7 Saving Your Perspective

After you have made any changes to the layout of your perspective you will want to save it so that when itstarts up again it will display all the Views in the layout that you found best for your workflow. To do thisclick on Window → Save Perspective As → Java .

1.8 Eclipse Resources

The purpose of this chapter is not to be an exhaustive guide to Eclipse, but simply a guide to help you getstarted. There are many fine documents and videos on using Eclipse, and the best place to find them isat http://help.eclipse.org/helios/index.jsp, http://www.eclipse.org/resources/resource.php?id=532, and http://www.eclipse.org/resources/?category=Getting%20Started.

19

20

Chapter 2

Introduction

2.1 What is Java?

Java is an object oriented language that generates platform independent executables that are interpretedby the computer byte by byte instead of being compiled into machine specific instructions. Java programsare run by the Java Virtual Machine (JVM) which interprets Java instructions and pass them on to theoperating system for execution. The fact that Java code is interpreted makes it more portable so code canbe run on differing systems and architectures without having out be compiled from source. Now that wehave briefly talked about Java as an interpreted language we can look at its object oriented nature.

2.1.1 Java Versions

Java is a rich family of languages that has differing versions and can run under differing types of environments.The different versions of Java are:

Java Standard Edition

For desktops current version is 7.

Java Enterprise Edition

Meant for servers.

Java Micro Edition

For devices like cellphones, game controllers and other electronics.

Java Card

For smart cards.

21

2.2 Components Of Java Standard Edition

We will be using Java Standard Platform Edition in this book. The parts of JSE6 are:

2.2.1 Tools & Tool APIs

This includes all the programming tools and their Application Programming INterfaces (APIs) which specifyhow other programs can interact with them.

2.2.2 Java Runtime Environment

This consists of the Java Virtual Machine, and the libraries.

Java Virtual Machine

A simulation of a machine, runs the Java bytecode.

Libraries

These are all the libraries, they are stored in class files.

2.3 Java Objects, Classes & Methods

When we are trying to solve a problem frequently our solution depends and the nature of the things involvedwith the problem or categories that the solution applies to. For example certain attributes define what acar is; some of these properties are that all cars have are metal doors, windows, chairs, seatbelts, an engine,radiator, and the ability to accelerate, slow down, or stop. On the other hand a person has arms, legs, ahead, and can do things like walk, talk, sleep, eat.

From looking at the class of objects that is motor vehicles we see that there are certain action associatedwith a car and that these actions as well as its physical properties determine its state at any point in time.Another example is that an bag is an object that can go from the states full and empty. We can movebetween these states by either putting things in the bag or taking things out. Therefore we see a bag objectwhich has properties such as filled volume, empty volume, total volume can have all of those values changedwhenever we put an item in the bag or take one out.

In Java we also deal with objects and each object is a member of a class similar to the way Peugeots aremember of the class of cars and Rotimi’s Peugeot 305 is a particular instance of the Peugeot object. In Javathe operations that we can perform on a Peugeot such as accelerating, rolling down the window, stooping,opening a door are called methods. We can consider a method as being an operation that changes the stateof an object.

22

2.4 Layout of a Java Program

Java programs are in the following format;

1 public class HelloWorld {

23 public static void main(String [] args) {

4 System.out.println("Hello world!");

5 System.out.println("The square of " + 3 + " is " + (3 * 3));

6 }

7 }

Program 2.1: HelloWorld.java

To execute the program we must save the code into a file named HelloWorld.java. All Java program namesmust match their class name. Later on we shall use Eclipse but for now we will compile from the commandline by typing javac HelloWorld.java, javac converts the source into object code. After compiling it wecan use the java interpreter, which is called java, to execute the bytecode. The commands that we type inthe console to get the compile and run the program are shown highlighted in yellow.

$ javac HelloWorld.java

$ java HelloWorld

Hello world!

The square of 3 is 9

$

The command prompt on my laptop is a $ sign, so, that character in the output can be ignored.

2.5 Java Expressions

Java programs consist of a series of statements where we either declare a variable, assign a value to an object,evaluate an expression or call a method. To do these things we use identifiers.

2.5.1 Identifiers

An identifier is the name of a variable, object class, or method. There are four rules to follow when namingidentifiers.

i An identifier cannot begin with a number.

ii Identifier names can only consist of alphanumeric characters and underscore.

iii It is illegal to use Java keywords as identifiers. To see what Java’s reserved words are look at http:

//java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html as well as Table2.1.

iv Some words such as println are not reserved but if you use them as identifiers in your code your applicationmay become unstable.

23

absract final publicassert finally return

boolean float shortbreak for staticbyte goto strictfpcase if supercatch implements switchchar import synchronizedclass instanceof thisconst int throw

continue interface throwsdefault long transient

do native truedouble new try

else null voidenum package volatile

extends private whilefalse protected

Table 2.1: Java Reserved Words

2.5.2 Variables

In Java all variables must be declared prior to being used, variable declarations are in the format;

variable-type variableName1, ....., variableNameN;

The variable can be either one of Java’s builtin primitives, standard objects, or user defined objects. Table2.2shows the Java primitive data types.

Type Kind of Value Size in Bytesboolean true or false 1

char single unicode characters 2byte integer number 1short integer number 2int integer number 4

long integer number 8float real number 4

double real number 8

Table 2.2: Java Primitive Data Types

Some examples of variable declarations are;

float speed;

char gender;

int count , year , age;

24

Variable Assignment

The assignment operator, = , is used to give a variable a value. It is used as follows;

variable = expression;

Examples of variable assignment are;

int count = 0;

float height = 5.0;

letter = ’a’;

area = length * height;

The assignment operator evaluates left right to left so the expression x = y = 45; will be evaluated in theorder;

i The value 45 is stored in y.

ii the value of y is stored in x.

Variable Initialization

It is good programming practice to initialize your variables after they have been declared. If you do notinitialize them the values stored in them will be arbitrary and contain whatever information had in thatmemory location previously. Furthermore to make your code readable put each variable declaration on itsown line.

Implicit and Explicit Typecasting

Sometimes we might want to store an integer in a float, or vice versa. Or we might want to do convert aninteger to a character. Generally a variable of smaller size can be assigned to one of type that uses morebytes, therefore the following code fragment is perfectly acceptable in Java.

int size = 3;

float delta = 0f;

delta = size;

But putting avogadroNumber in roundedAvogadro will give an error.

double avogadroNumber = 6.023 e23;

int roundedAvogadro = avogadroNumber;

We can assign values of one type to another when they are in the following precedence;

byte → short → int → long → float → double

25

For assigning an integer to an char,

int → char, long → char

Typecasting from char to integer is also legal,

char → int, char → long

Since Java uses unicode instead of ASCII refrain from switching between integers and characters so thatany incompatibilities are avoided. If want to typecast a larger sized data type into a smaller one we mustexplicitly tell Java to do this byte using the typecast command. The syntax for the typecast operations is.

(target data-type) variable

In the code fragment below we can see how explicit typecasting is done.

float weightInKilos = 72.3f; //Must put "f" after the number for

floats.

int aNumber = 5;

aNumber = (int) weightInKilos;

Whenever we typecast a larger data type to a smaller one the larger one will get truncated. If on the otherhand we typecast a smaller data type to a larger one the smaller one will get rounded up.

2.6 Constants

Sometimes we need a variable’s value to be fixed, for example p = 3.1459. To make sure that you do notinadvertently change the value of a constant use the keywords public, static, final as shown below

public static final float PI = 3.1459;

public static final int BUFFER_SIZE = 1024;

Best practices recommend when using constants is that you declare your constants outside the maid methodas shown in GetDistanceFallen.java.

1 public class GetDistanceFallen {

23 // unit of acceleration is metres per second per second.

4 public static final double FREE_FALL_ACCELERATION = 9.8;

56 public static void main(String [] args) {

7 double timeInSeconds = 53.0;

8 double distanceInMetres = 0.0;

9 double finalSpeed = 0.0;

1011 finalSpeed = FREE_FALL_ACCELERATION * timeInSeconds;

12 distanceInMetres = finalSpeed * timeInSeconds;

26

1314 System.out.print("The object fell " + distanceInMetres + " metres");

15 System.out.print(" in " + timeInSeconds + " seconds .\n");

16 }

17 }

Program 2.2: GetDistanceFallen.java

When we run GetDistanceFallen.java we get output shown below; the $ is simply the console prompt on mycomputer.

$ javac GetDistanceFallen.java

$ java GetDistanceFallen

The object fell 27528.200000000004 metres in 53.0 seconds.

$

2.7 Arithmetic Operators

In Java there are a number of unary and binary arithmetic operators, at this time we shall only discuss thebinary arithmetic operators are displayed in Table2.3

Operator Action Operator Action+ addition = assignment- subtraction -= assign result of subtraction* multiplication += assign result of addition/ division *= assign result of multiplication% modulo %= assign result to of modulus

++ increment by 1 – decrement by 1

Table 2.3: Binary Arithmetic Operators

2.7.1 Precedence Rules

Whenever an arithmetic expression is evaluated the operations that comprise the expression are evaluatedin terms of their order of importance. If two operations are of equal precedence the left most operationis evaluated first. Though there are more precedence rules for this class we will only deal with the binaryarithmetic operators shown in Table2.4. To make your code easier to read always use braces to show whatthe precedence is supposed to be.

2.8 Strings

languages such as C, C++, and Fortran have a string primitive, however, Java does not. To use string inJava we used the String class, string are declared in Java with statements of the form,

27

Precedence OperatorHighest ++ –

typecast* / %+ -

Lowest = *= /= %= += -=

Table 2.4: Arithmetic Operator Precedence Rules

String variable-name;

for example,

String firstName = "Banji";

We can concatenate string with the + operator as shown in the code fragments,

String firstName = "Banji";

String lastName = "Lawal";

String fullName = firstName + lastName;

There are a number of string methods that belong to the String class, these methods are invoked by using. notation. For example to find the length of the string lastName we would do,

1 public class PrintStringLength

2 {

3 public static void main(String [] args)

4 {

5 String aString = "Obatala and Shiva are both gods.";

67 int stringLength = aString.length ();

89 System.out.print("The string; \"" + aString + "\"");

10 System.out.println(" is " + stringLength + " characters long.");

11 }

12 }

Program 2.3: PrintStringLength.java

On running PrintStringLength.java through interpreter we see .........

$ java PrintStringLength

The string; "Obatala and Shiva are both gods." is 32 characters long.

$

Later on in the course we shall examine Strings in more detail.

28

Chapter 3

Basic Console Input/Output

Other names for the console are the command line, or terminal. The terminal is the simplest interface betweenthe user and the operating system which is responsible for running all the programs. For programs thatare interactive, that get input from a person then show a response to the user’s input, using the terminalfor I/O is the easiest way of doing this. Java has many functions, classes, and libraries for dealing withinput/output; some of those for console I/O are in the System class and further divided into the daughterclasses out and in.:

3.1 Java Print Functions

For printing output we can use the functions print, println, and printf. These functions display output onthe terminal, they do not have anything to do with sending a file to a printer. All three of these are methodsin class System.out; you can find out more about this from looking at http://java.sun.com/javase/6/

docs/api/index.html

3.1.1 Print

This method takes a String as an argument. Print does not add a carriage return to the string when it’sdisplayed on the terminal. The syntax of this command is;

System.out.print(String);

Below we see an example of print being used.

29

1 public class UsesPrint {

23 public static void main(String [] args) {

4 int number = 5;

56 System.out.print("The number is " + number);

7 }

8 }

Program 3.1: UsesPrint.java

The output that ShowsPrintfUsage.java generates is shown below. You can see that when runs that there isno carriage return after the message is printed on the screen.

$ java UsesPrint

The number is 5$

If we want to have a newline (carriage return) also sent to the console we use the escape sequence \n as seenbelow.

System.out.print("The number is " + number + "\n");

After adding the newline to our string we get the more readable output that we see here.

$ java UsesPrint

The number is 5

$

\n is one of the common control sequences, some other common ones are;

Escape Sequence Action\t prints tab\r carriage return\’ single quote\” double quote\\ backslash\b bell\n newline

Table 3.1: Java Escape Sequences

Please note that when we are using the single quote,‘, in a string we do not need to escape it, however, ifwe want to set a char to be the single quote we will have to escape it as seen in the declaration below.

char glyph = ’\’’;

If on the other hand you had tried to do;

char glyph = ’’’;

You would get a syntax error.

30

3.1.2 Printf

To get formatted output for a variable we use System.out.printf. Printf takes as its arguments a string,format specifier and the variable to be printed. The program ShowsPrintfUsage.java will give you an ideaof how to printf works.

1 public class ShowsPrintfUsage {

2 public static void main(String [] args) {

3 int anInteger = 56;

4 double aDouble = 1236849.00085382794;

5 float aFloat = -34.67f;

6 char glyph = ’d’;

7 String quote = "Bongos Ikwe likes hearing cockrows at dawn.";

89 System.out.printf("anInteger = %1d\n", anInteger);

10 System.out.printf("formatted double = %3.5f\n", aDouble);

11 System.out.printf("exponential double = %1.2e\n", aDouble);

12 System.out.printf("formatted float = %1.12f\n", aFloat);

13 System.out.printf("formatted glyph = %4c\n", glyph);

14 System.out.printf("formatted string = %10s\n", quote);

15 System.out.printf("anInteger = %12d\n", anInteger);

16 }

17 }

Program Program3.2: ShowsPrintfUsage.java

Note that for We see that the format specifier’s layout is %x.yT where:

• % → shows beginning of the format specifier

• x → number of spaces to print in front of decimal point

• y → number of spaces to print after the decimal point

• . → decimal point for real numbers

• T → indicates type of data

Table 3.2 shows the Java format specifiers.The printf function does not append the newline by default so we need to always add the \n characterto get carriage returns. Lastly, though there are other methods for getting formatted output such as thebuiltins; DecimalFormat and NumberFormat their use is outside the scope of this class.

3.1.3 Println

The difference between print, printf, & println is that println will automatically append a carriage returnto the string. We have already seen println being used.

31

Format Specifier Data Type%f Floating Point%d Integer%e Exponential%g General Floating Point%s String%c Character

Table 3.2: Java Format Specifiers

3.2 The Scanner Class

To get input from the keyboard we use the Scanner object. Before we can invoke Scanner we must add itslibraries to our program with the import statement,

import java.util.Scanner;

In Java libraries are usually called packages. To actually use the scanner we declare a Scanner object inour program with a statement similar to Scanner myInput = new Scanner(System.in); The statementcreates a new instance of the object Scanner called myInput . MyInput gets its value from standard input,which is the keyboard. However to get the input that was typed at the keyboard we need to tell our Scannerobject what type of data it’s getting. To do this Scanner class uses the following methods.

• nextInt() → Returns an integer.

• nextLong() → Returns a long.

• nextByte() → Returns a byte.

• nextShort() → Returns a short.

• nextDouble() → Returns a double.

• nextFloat() → Returns a float.

• nextLine() → Returns the line until there is a carriagereturn.

• nextBoolean() → Returns a boolean.

• next() → Returns all characters till the next delimiter. The default the delimiter is white space.

In GetStaticForce.java we can see how the Scanner class is used to get input from the user.

1 /* GetStaticForce.java is used to calculate the magnitude of

2 the Coloumbic attraction between two charged bodies. The

3 formula for this is;

4 * F = k* (Q1 * Q2)/(r^2)

5 * where Q1 -- First charge

6 * Q2 -- Second charge

32

7 * k -- Coloumbic constant

8 * r -- distance

9 */

1011 import java.util.Scanner;

1213 public class GetStaticForce

14 {

15 public static final double COLOUMBIC_CONSTANT = 8.987551787e+9;

1617 public static void main(String [] args)

18 {

19 double distance = 0.0; // Distance between charges in metres.

20 double chargeOne = 0.0; // Charge one’s magnotude in coloumbs.

21 double chargeTwo = 0.0; //The second charge ’s magnitude , also in

coloumbs.

2223 //Use numerator & denominator to make electrostatic magnitude

24 // calculation easier to read.

25 double numerator = 0.0;

26 double denominator = 0.0;

2728 double electroStaticMagnitude = 0.0; //

2930 Scanner input = new Scanner(System.in);

3132 System.out.print("Distance between charges (metres): ");

33 distance = input.nextDouble ();

3435 System.out.print("Charge One magnitude (coulombs): ");

36 chargeOne = input.nextDouble ();

3738 System.out.print("Charge Two magnitude (coulombs): ");

39 chargeTwo = input.nextDouble ();

4041 numerator = COLOUMBIC_CONSTANT * chargeOne * chargeTwo;

42 denominator = distance * distance;

4344 electroStaticMagnitude = numerator/denominator;

45

33

46 System.out.printf("\n\nFor charges of %.3f and %.3f coloumbs",

chargeOne , chargeTwo);

47 System.out.printf("\nthat are %.3f metres from each other ,\n",

distance);

48 System.out.printf("the electrostatic magnitude: %.3g\n\n",

electroStaticMagnitude);

49 }

50 }

Program 3.3: GetStaticForce.java

On running the program we get the output shown below.

$ java GetStaticForce

Distance between charges (metres): 23

Charge One magnitude (coulombs): 9.67

Charge Two magnitude (coulombs): 5.43

For two charges with 9.670 and 5.430 coloumbs

that are 23.000 metres from each other ,

the electrostatic magnitude: 8.92e+08

$

34

Chapter 4

Flow of Control

All programming languages mange the flow of logic in an algorithm by using repetition and branchingmechanisms. Repetition is achieved either by using iterative or recursive operations while branching hastraditionally been done with some variant of the if statement. Let us start by examining Java’s branchingmechanisms.

4.1 Java Branching Mechanisms

In Java like most programming languages flow of control goes from the start to the stop in a linear sequenceof steps. However in all algorithms we need to make choices about the which option to follow out of severalpossible ones, each of these paths will change the program’s flow of execution. To decide which path to takeJava has a number of branching constructs, these constructs are;

• if

• if-else

• switch

In the remainder of this section we shall look at each construct in more detail.

4.1.1 The If Statement

The format of an if statement is;

if (boolean expression) statements for true

The statement that immediately follows an if is executed when the if statement’s condition is true. If wewant to execute multiple statement we group them with curly braces. A code fragment has been shown togive you an idea of how the if statement is used.

35

if (bloodPressure >= 120.0) {

alarm = "on";

System.out.print("\n");

}

It can be seen from the code fragment that if we want to execute multiple commands with the if statementwe place curly braces around them.

4.1.2 If-Else

A limitation of the if statement is that we do not explicitly state what will be done if the boolean conditionin parenthesis is not met. To choose between two options we use the if-else construct, its syntax is;

if (boolean expression) statements for true else statements for false

GetsPenStatistics.java uses if-else statements in deciding which logic to execute.

1 /* If the number of pens in inventory falls below 10 boxes

GetPenStatistics

2 * will print a message saying taht more need to be ordered , otherwise it

3 * will report that no new pens should be ordered.

4 */

5 public class GetsPenStatistics

6 {

7 public static void main(String [] args)

8 {

9 int numOfPens = 6;

10 int orderThreshold = 10;

11 int amountToOrder = 0;

1213 if (numOfPens <= orderThreshold)

14 {

15 amountToOrder = orderThreshold - numOfPens;

16 System.out.println("Order " + amountToOrder + " pens");

17 }

1819 else

20 System.out.println("Since there are " + numOfPens + " no new

orders of pens are necessary");

21 }

2223 }

Program 5.1: GetsPenStatistics.java

36

Nested If-else Statements

We can nest if-else statements as shown in AssignsLetterGrade.java which is shown below.

1 /* AssignsLetterGrade will give a letter grade based on the percentage

2 * that the student recieved out of the total possible points.

3 */

45 import java.util.Scanner;

678 public class AssignsLetterGrade

9 {

10 public static void main(String [] args)

11 {

12 char letterGrade;

13 double percentage = 0.0; //The percentage of points recieved.

1415 Scanner input = new Scanner(System.in);

1617 //Get the percentage from the user.

18 System.out.print("Enter the percentage: ");

19 percentage = input.nextDouble ();

2021 /* Depending on the value of percentage we assign a specific grade

.

22 * If there is a problem assigning a grade then we print an error

23 * message that says invalid score and assigns ’N’ to letterGrade.

24 */

25 if (percentage >= 90)

26 letterGrade = ’A’;

27 else if (( percentage <= 89) && (percentage >= 80))

28 letterGrade = ’B’;

29 else if (( percentage <= 79) && (percentage >= 70))

30 letterGrade = ’C’;

31 else if (( percentage <= 69) && (percentage >= 60))

32 letterGrade = ’D’;

33 else if (( percentage <=59) && (percentage >= 0))

34 letterGrade = ’F’;

35 else

36 {

37 letterGrade = ’N’;

38 System.out.println("Invalid score.");

37

39 }

4041 if (letterGrade != ’N’)

42 {

43 System.out.printf("For a score of %2.2f percent ", percentage)

;

44 System.out.printf(" the grade is %1c.\n", letterGrade);

45 }

4647 }

48 }

Program 5.2: AssignsLetterGrade.java

4.1.3 Boolean Operators

Decisions in Java are made using boolean logic and we have a certain number of comparison operatorsavailable. Java’s comparison operators are shown in the table below.

Operator Function== Equality!= Not equal¡ Less than> Greater than

<= Less than or equal to>= Greater than or equal to&& Partial logical and| Partial logical or& Complete logical and| Complete logical or

Table 4.1: Table4.1: Java Comparison Operators

The difference between the && and & operators is that && does not evaluate the whole logical expressionbefore returning either true or false instead the first time it sees a false case it returns false. On the otherhand & will evaluate the whole expression before it returns its result. Since && and — give a false thefirst time one of their options fails we say they use lazy evaluation. Consider the code fragment

x = 5;

if ((x < 6) || (x == 2))

result = x + 23;

Since the first condition is true Java will return true without checking the x == 2 condition. A second caseis;

38

angle = 45.0f;

speedInMetresPerSec = 14.5f;

if (( angle >= 48.5f) && (speed > 135))

damage = mass * speed * speed * 403;

damage = mass * speed * 12.4;

Since the angle is less than 48.5 the if statement will not check the second condition and return false withoutchecking that the speed is greater than 135 so it will calculate damage with the formula,

damage = mass× speed× 12.4

If we used the & operator instead it would not use lazy evaluation. The boolean operators also have

precedence so now we can expand our precedence table that we discussed earlier.

4.1.4 Switch

We have seen that multiple branches can be done with nested if statements, however this method can bedifficult to follow without indentation. Another construct that can be used for selecting among severaloutcomes is the switch statement.

Precedence FunctionHighest ++ –

typecast* / %+ -

<><=>=== !=

&||

&&|

Lowest = *= /= %= += -=

Table 4.2: Table 4.2: Complete Precedence Rules

The format of a switch statement is:

switch(variable)

{

case value1:

statement;

break;

case value2:

statement;

39

break;

case valueN:

statement;

break;

default:

statement;

break;

}

The default case is optional and is executed if the variable’s current value is not handled by any of the othercase statements. Best practices are to always have a default statement in a switch since it can be used forerror checking. One of the limitations of switch is that can only take single integers or possibly characters.To see how switch and nested if-else statements compare look at the following two implementations of asso-ciating numbers with names of months, ConvertsNumberToMonth.java & ConvertsNumberToMonth2.java.

1 import java.util.Scanner;

23 public class ConvertsNumberToMonth

4 {

5 public static final int NUM_OF_MONTHS = 12;

67 public static void main(String [] args)

8 {

9 int number = 0;

10 String nameOfMonth = "";

1112 Scanner input = new Scanner(System.in);

1314 System.out.print("ConvertsNumberToMonth2 displays the month that")

;

15 System.out.print(" corresponds to the number that the user entered

.");

16 System.out.print("\nIf the value input is larger than 12");

17 System.out.print(" then only an error message is displayed .\n");

1819 System.out.print("Number: ");

20 number = input.nextInt ();

2122 switch (number)

23 {

24 case 1:

25 nameOfMonth = "January";

26 break;

40

27 case 2:

28 nameOfMonth = "February";

29 break;

30 case 3:

31 nameOfMonth = "March";

32 break;

33 case 4:

34 nameOfMonth = "April";

35 break;

36 case 5:

37 nameOfMonth = "May";

38 break;

39 case 6:

40 nameOfMonth = "June";

41 break;

42 case 7:

43 nameOfMonth = "July";

44 break;

45 case 8:

46 nameOfMonth = "August";

47 break;

48 case 9:

49 nameOfMonth = "September";

50 break;

51 case 10:

52 nameOfMonth = "October";

53 break;

54 case 11:

55 nameOfMonth = "November";

56 break;

57 case 12:

58 nameOfMonth = "December";

59 break;

60 default :

61 System.out.println("Invalid number");

62 System.exit (2);

63 break;

64 }

6566 System.out.printf("%d corresponds to the month named", number);

67 System.out.printf(" %s.\n", nameOfMonth);

41

68 }

69 }

Program 5.3: ConvertsNumberToMonth.java

If we had run the same program with nested if-else it would have been as follows;

1 import java.util.Scanner;

23 public class ConvertsNumberToMonth2

4 {

5 public static final int NUM_OF_MONTHS = 12;

67 public static void main(String [] args)

8 {

9 int number = 0;

10 String nameOfMonth = "";

1112 Scanner input = new Scanner(System.in);

1314 System.out.print("ConvertsNumberToMonth2 displays the month that")

;

15 System.out.print(" corresponds to the number that the user entered

.");

16 System.out.print("\nIf the value input is larger than 12");

17 System.out.print(" then only an error message is displayed .\n");

1819 System.out.print("Number: ");

20 number = input.nextInt ();

2122 if (number == 1)

23 nameOfMonth = "January";

2425 else if (number == 2)

26 nameOfMonth = "February";

2728 else if (number == 3)

29 nameOfMonth = "March";

3031 else if (number == 4)

32 nameOfMonth = "April";

3334 else if (number == 5)

42

35 nameOfMonth = "May";

3637 else if (number == 6)

38 nameOfMonth = "June";

3940 else if (number == 7)

41 nameOfMonth = "July";

4243 else if (number == 8)

44 nameOfMonth = "August";

4546 else if (number == 9)

47 nameOfMonth = "September";

4849 else if (number == 10)

50 nameOfMonth = "October";

5152 else if (number == 11)

53 nameOfMonth = "November";

5455 else if (number == 12)

56 nameOfMonth = "December";

5758 else

59 {

60 System.out.println("Invalid number");

61 System.exit (2);

62 }

6364 System.out.printf("%d corresponds to the month named", number);

65 System.out.printf(" %s.\n", nameOfMonth);

66 }

67 }

Program 5.4: ConvertsNumberToMonth2.java

The Switch statement can only be used with integers and chars. We also cannot use it for a range of numbersas was seen in AssignsLetterGrade. One thing that you may notice about ConvertsNumberToMonth

is that it appears cleaner than ConvertsNumberToMonth2 so it may be easier to follow the formerprogram’s logic. However, both programs produce the same output as seen in below.

$ java ConvertsNumberToMonth2

ConvertsNumberToMonth2 displays the month that corresponds to the number

43

that the user enters.

If the value input is larger than 12then an error message is printed.

Number: 56

Invalid number

$ java ConvertsNumberToMonth

ConvertsNumberToMonth2 displays the month that corresponds to the number

that the user entered.

If the value input is larger than 12 then only an error message is

displayed.

Number: 56

Invalid number

$ java ConvertsNumberToMonth

ConvertsNumberToMonth2 displays the month that corresponds to the number

that the user entered.

If the value input is larger than 12 then only an error message is

displayed.

Number: 6

6 corresponds to the month named June.

$ java ConvertsNumberToMonth2

ConvertsNumberToMonth2 displays the month that corresponds to the number

that the user enters.

If the value input is larger than 12then an error message is printed.

Number: 6

6 corresponds to the month named June.

$

4.2 Iteration

The second group of control structures in Java is used for repeating a set of tasks until a condition is metin the literature you will read that iterative structures are also referred to as loops. Java has the followingconstructs for looping;

• while

• do-while

• for

4.2.1 While Loop

The format of a while loop is

while (boolean expression) statement;

44

Without brace the while loop only does the one statement immediately after the while. So for the codefragment

int count = 0;

while (count < 22)

System.out.println("Count is " + count);

count ++;

will print Count is 0 an infinite amount of times. If we ever get out of the loop it will then increment countto 1. So to get both the print statement and the count of be incremented we will use curly braces.

int count = 0;

while (count < 22) {

System.out.println("Count is " + count);

count ++;

}

With a while loop the boolean expression is evaluated before the statements are executed so it is possiblethat the statements in the loop body are never executed when the boolean evaluates to false.

4.2.2 Do-While Loop

The format of a do-while loop is

do { statements; } while (boolean expression);

An example of a do-while loop is

do {

letter = scannerObject.nextString ();

} while (( letter != "\t") || (letter !="");

We see that in a do-while loop the statements are executed at least since since the test is at the bottom ofthe do-while construct.

4.2.3 For Loop

The traditional use of a for loop was for accessing the elements of an array or incrementing a counter. Forloops only work with numbers, ideally you should only use integers with a for loop while the while anddo-while can work with all data types. The for loop’s syntax is,

for (initialization; boolean expression; update expression) vspace5mm statements;

45

for (initialization; boolean_test; update_expression)

statements;

An example of a for statement is shown in the code fragment below.

for (index = 0; index < 10; index ++)

System.out.println("Index: " + index);

If we look at ChecksBalance.java we can see how all the flow control elements can be used in a program.

1 /* Name: Banji Lawal

2 * Lab: 1

3 * Class: CSC101

4 * Date: 23/10/2009

5 *

6 * Filename: ChecksBalance.java

7 * Program Function: ChecksBalance reports if there is any available

credit for an account.

8 */

910 import java.util.Scanner;

1112 public class ChecksBalance

13 {

14 public static final float INTEREST_RATE = 0.052f;

1516 private static void PrintsAppInfo ()

17 {

18 System.out.println("ChecksBalance prints out what the customer ’s

current balance is.");

19 System.out.println("Its inputs are;\nthe six digit account number ,

previous balance , payments , charges , and the credit limit.");

20 System.out.println("To stop ChecksBalance types N to quit.");

21 System.out.println("As output it displays the current balance and

available credit");

22 System.out.println("When the credit limit is exceeded the message ,

\" credit limit exceeded \" is printed.");

23 }

24252627 public static void main(String [] args)

28 {

29 int accountNumber = 0;

46

30 String answer = "y";

3132 float oldBalance = 0.0f;

33 float newBalance =0.0f;

3435 float charges = 0.0f; // Amount of money borrowed

36 float payments = 0.0f; //How much was paid in the last month

3738 float creditLimit = 0.0f;

39 float availableCredit = 0.0f;

404142 // We need two Scanners , one for getting numbers ,

43 // the other for Strings.

44 Scanner getsNumber = new Scanner(System.in);

45 Scanner getsAnswer = new Scanner(System.in);

4647 // Print statements explaining what ChecksBalance.java does. and how

the

48 // user interacts with it.

49 PrintsAppInfo ();

5051 // Priming read for our loop.

52 System.out.print("\n\nContinue (y/n)? ");

53 answer = getsAnswer.nextLine ();

5455 while (answer.equalsIgnoreCase("y"))

56 {

57 System.out.print("\nSix Digit Account Number: ");

58 accountNumber = getsNumber.nextInt ();

5960 // Here we are making sure that account numbers are 6 digits long.

61 // we only enter this loop when account numbers are wrongly

formatted.

62 while (( accountNumber >= 0) && (accountNumber < 100000))

63 {

64 System.out.println("Invalid account number");

65 System.out.print("Account Number: ");

66 accountNumber = getsNumber.nextInt ();

67 }

68

47

69 // Get information about payments , charges , balances , and the

credit limit.

70 System.out.print("Old Balance: ");

71 oldBalance = getsNumber.nextFloat ();

7273 System.out.print("Charges: ");

74 charges = getsNumber.nextFloat ();

7576 System.out.print("Payments: ");

77 payments = getsNumber.nextFloat ();

7879 System.out.print("Credit Limit: ");

80 creditLimit = getsNumber.nextFloat ();

8182 // Calculating the new balance and availabe credit.

83 newBalance = (( oldBalance * INTEREST_RATE) + oldBalance + charges)

- payments;

84 availableCredit = creditLimit - newBalance;

8586 // Display information about the account

87 System.out.println("\n*********** Current Account Summary

***********");

88 System.out.printf("\nAccount Number: " + accountNumber + "\n");

89 System.out.printf("Credit Limit: %.2f\n", creditLimit);

90 System.out.printf("New Balance: %.2f\n", newBalance);

91 System.out.printf("Available Credit: %.2f\n", availableCredit);

9293 if (newBalance >= creditLimit)

94 System.out.println("Credit limit exceeded.");

9596 // User is given the chance to exit the loop.

97 System.out.print("\n\nContinue (y/n)? ");

98 answer = getsAnswer.nextLine ();

99 }

100101 // When the user indicates that they want to stop exit the program.

102 if (( answer == "n") || (answer == "N"))

103 {

104 System.exit (0);

105 }

106 }

48

107108 }

Program 5.5: ChecksBalance.java

From this we have now looked the three elements of all algorithms in Java, since we have looked at simpleJava statements, decisions, and loops.

49

50

Chapter 5

Methods

5.1 Introduction

One of the things that happens frequently in a program is repetition, We might repeat a code block becausea variable meets certain conditions as in the code fragment below.

1 while ( !(name.equals("I want to stop")) {

2 if (name.equals("George McBundy"))

3 System.out.println("Another Watergate conspiracist !!");

45 name = aScanner.next();

6 }

we could create a subroutine that would evaluate the if statement. This is necessary because there are manyWatergate conspirators. For another example to find the square root of a number with Hero’s formula as isdone in GetSquareRoot.java.

1 package src;

23 /**

4 * GetSquare class will find the square of a number.

5 */

6 public class GetSquareRoot {

78 /**

9 * Main method finds the square by using the Babylonian method. For

10 * information about the algorithm see

11 * http ://en.wikipedia.org/wiki/Methods_of_computing_square_roots , The

12 * arguments are an double and an it that are passed from the command

line.

13 *

51

14 * @param number

15 * the value whose root will be found.

16 * @param numOfPasses

17 * how many iterations of the method will be done.

18 */

19 public static void main(String [] args) {

20 double seed = 0; // We start our square root approximation with

this.

21 double approxRoot;

22 double number = 0; // Get from command line

2324 int index = 0; // This is used in finding the seed.

25 int tempNumber = 0; // A holding value.

26 int numOfPasses = 0; // Get from command line

2728 // The following code block is used to get our arguments and

29 // does some basic error checking.

30 if (args.length == 2) {

31 try {

32 number = Double.parseDouble(args [0]);

33 numOfPasses = Integer.parseInt(args [1]);

34 } catch (NumberFormatException e) {

35 System.out.println("Arguments are not numbers.");

36 System.exit (5);

37 }

38 }

3940 else {

41 System.out.println("Invalid number of arguments");

42 System.exit (2);

43 }

4445 // Explain what the program is doing at this stage.

46 System.out.print("Trying to find the square root of " + number);

47 System.out.print(" in " + numOfPasses + " passes .\n");

4849 // We are doing the steps below to calculate the seed. The size

50 // of the seed depends on the number of digits that our number

51 // has.

52 tempNumber = (int) number;

53

52

54 int numOfDigits = 0;

55 int remainder = 0;

56 int sum = 0;

5758 // Using this while loop to count the number of digits in number.

59 // This can probably be done in a simpler way.

60 while (tempNumber > 0) {

61 remainder = tempNumber % 10;

62 sum += remainder;

63 tempNumber /= 10;

64 System.out.print(".");

6566 numOfDigits ++;

67 }

6869 // Now that we know numOfDigits we can find the seed. The seed’s

70 // value differs if numOfDigits is even or odd.

71 if (( numOfDigits % 2) == 0) {

72 index = (numOfDigits - 2) / 2;

73 seed = 6 * Math.pow(10, index);

74 }

7576 else {

77 index = (numOfDigits - 1) / 2;

78 seed = 2 * Math.pow(10, index);

79 }

8081 // Initial value of our square root is the value of the seed.

82 approxRoot = seed;

8384 // Iterate using the formula;

85 // current approxRoot = 0.5 (last approxRoot + (number /(last

86 // approxRoot))

87 //

88 for (int i = 0; i < numOfPasses; i++) {

89 // System.out.print("pass #: " + i );

90 // System.out.print(" Current square root: " + approxRoot + "\

n");

9192 System.out.print(".");

93 approxRoot = 0.5 * (approxRoot + (number / approxRoot));

53

94 }

9596 // Display the final result.

97 System.out.printf("\n%.3f is the square root of %.3f\n ",

approxRoot ,

98 number);

99 }

100 }

Program 6.1: GetSquareRoot.java

Again we see that there are certain operations that are run multiple times and we can easier to understandand maintain by using methods, also know as functions, procedures, or subroutines, in a larger Java program.Now we can define what a method is an explore how they are used.

5.2 Definition

A method is a block of code in a program that has its own address space in main memory, its own variables.The beginning of a function is designated by the method header and an opening curly brace, the close isindicated by a closing curly brace.

5.3 The Method Header

The method header gives us information about the type of data that is sent to the calling program; as wellas the function’s name, how the method is accessed, and what it needs as inputs.

modifier returnType methodName(parameter list)

Now we can examine each field in the method header.

5.3.1 Modifier

The modifier deals with how the function is accessed by other Java programs or functions. At the currenttime shall only deal with the public modifier. This modifier means that other programs, classes and methodscan access and use the subroutine.

5.3.2 Return Type

Subroutines are called from a larger program that they are a part of; or by a completely separate application.When a subroutine is called it either returns a value to whatever entity invoked it; or it will conduct anoperation that does not generate a value such as displaying a message, sort a list, or open a file. For thelatter type of functions we use the keyword void to show that nothing is returned.

54

On the other hand subroutines that pass a value back to their invoker will specify what type of data will bepassed back to the caller when method has completed its run. In this case the return type corresponds toeither the primitive data type or object that is needed by the invoker.

5.3.3 Method Name

Method names should describe what the function does, so a name like GetsMailingAddres is a good,descriptive function name, whereas func1 is not. If a subroutine’s name captures what is hoped to beaccomplished in the subroutine then it makes it easier for the reader to intuitively grasp what is happening.Its a good idea to avoid using the letter l I, or O in all method and identifier names since these can beconfused with 1 and 0 on some displays. Whenever possible put the word get in a function’s name if itsreturning a value. Lastly, unction names should always begin with a lowercase letter so that they are notconfused with class names.

5.3.4 Parameter List

These are the inputs that the method needs to complete its task, these inputs are enclosed within braces.The parameters can either be primitive or abstract data types. The parameter list is composed of eachinput’s data type as well as its identifier. If there is more than one parameter they are separated by commasas seen in the examples below.

public int getsMax(int x1 , int x2 , int x3)

public void displaySocketInfo(Socket s)

public String getsInput ()

5.4 The Method Body

As was stated earlier the statements that are used to accomplish a subroutine’s goal are enclosed withingcurly braces. If the subroutine returns a value then the last statement executed in it must be a return asseen in getTime.

public String getTime () {

String time = System.exec(time);

return time;

}

While printsTime is a void function.

public void printTime () {

Process p = null;

Runtime runner;

55

try {

runner = Runtime.getRuntime ();

p = runner.exec("time");

} catch(Exeception e) {

System.out.println("Error get proccess .);

System.exit (22);

}

System.out.print("The current time is ");

System.out.print("System.out.(p);

}

5.5 Invoking Functions

The way a procedure is called depends on its return type. If its a void method then we can invoke theprocedure with a statement similar to,

methodName(arguments)

On the other hand subroutines that pass a value back to their caller need a palce to store their value, sothese subroutines are always invoked with an assignment operator,

variable = methodName(arguments)

For examples of both classes of function call look at Area.java

1 package src;

23 public class Area {

45 public static double getsCircleArea(double radius) {

6 return (Math.PI * radius * radius);

7 }

89 public static double getsTriangleArea(double height , double base) {

10 double area = 0.5 * base * height;

1112 return area;

13 }

1415 public static void PrintsArea(String shape , double area) {

16 System.out.printf("The %s has an area of %.2f\n", shape , area);

17 }

56

1819 public static void main(String [] args) {

20 double triangleArea = 0;

21 double circleArea = 0;

2223 String shape = new String ();

2425 circleArea = getsCircleArea (5);

26 shape = "circle";

2728 PrintsArea(shape , circleArea);

2930 triangleArea = getsTriangleArea (6, 14);

31 shape = "triangle";

3233 PrintsArea(shape , triangleArea);

34 }

35 }

Program 6.2: Area.java

5.6 Scope Rules

Programs are stored in the computer’s hard drive as files. When we execute a program they get moved tomain memory (the RAM) where its assigned some slices of the memory address space to store its values.The only time that the central processing unit can fetch the program to execute its instructions is when theprogram is in RAM. In the RAM a certain amount of the space is assigned to each variable and method. Sofrom this we can surmise that Area.java’s memory layout is as follows.

getsTriangleAreagetsCircleArea

main

Table 5.1: GetArea.java’s Layout in RAM

Table5.1 shows that the each section of Area’s address space is assigned toa function, if there were globalvariables those would also be in the address space. The next table shows main’s address space.

Variable ValuecircleArea 0

triangleArea 0

Table 5.2: Main’s Initial Address Space

57

Later the other two methods are called by main and then the program’s call stack changes to what we seein the next diagram.

Then when the processor has executed all the instructions in Area.java the program’s functions will be inthe final state shown in table 5.3. You will notice that main and getsCircleArea have different valuesassigned to radius.

maincircleArea 78.5714

triangleArea 42.0radius 7

getsCircleArearadius 5

getsTrianleAreabase 13

height 6area 42

Table 5.3: Final State Of Area.java’s Method Stacks

This shows us that a function’s variables only exist in the method’s address space furthermore, all of method’svariables are completely independent and unrelated to another function’s variables. Another way of explain-ing the relations between a method and its variables is to say that generally the scope of its existence andoperations are restricted to the subroutine that created it. ScopeIllustrator.java also shows how scope ruleswork.

1 package src;

23 public class ScopeIllustrator {

58

45 public static void swap(int neroValue , int yhwhValue) {

6 int temp = neroValue;

7 neroValue = yhwhValue;

8 yhwhValue = temp;

910 System.out.print("From swap nero’s number is " + neroValue + "

while ");

11 System.out.println("yhwh’s value is " + yhwhValue);

12 }

1314 public static void main(String [] args) {

15 int neroValue = 666;

16 int yhwhValue = 777;

1718 swap(neroValue , yhwhValue);

19 System.out.print("\n From main nero’s number is " + neroValue

20 + " while ");

21 System.out.println("yhwh’s value is " + yhwhValue);

22 }

23 }

Program 6.3: ScopeIllustrator.java

Scope rules also apply to code blocks that are surrounded by curly braces. So in following code fragmentthere are two variables named x. The one inside the loop is completely unrelated to the one outside it.

x = 5;

for (int x = 1; x < MAX_VALUE; x++) {

System.out.print("x is " + x + "\n");

}

If you put the next fragment into a Java program you will see that the inner and out as have different scopes.

int a = 12;

char aChar = ’d’;

if ( aChar == ’d’) {

int a = 6;

while ( a < 20 ) {

System.out.println("Inner a: " + a);

a++;

}

59

}

System.out.println("Outer a: " + a);

It is possible to create variables that can be changed any where in the program. These variables are globalin scope. If you look at ConvertsTemperature.java you will see that its only global variable is answer.

1 package src;

23 import java.util.Scanner;

45 public class ConvertsTemperature {

6 static double answer = 0.0;

78 public static void farenheitToCelsius(double celsiusTemp) {

9 answer = (9.0 * celsiusTemp / 5.0) + 32.0;

10 }

1112 public static void celsiusToFarenheit(double farenheitTemp) {

13 answer = (5.0 * farenheitTemp / 9.0) - 32.0;

14 }

1516 public static void main(String [] args) {

17 double temp = 0.0;

1819 String scale = new String ();

20 String oppositeScale = new String ();

2122 Scanner getTemp = new Scanner(System.in);

23 Scanner getScale = new Scanner(System.in);

2425 System.out

26 .print("Scale (Type \"F\" for Farenheit or \"C\" fo

Celsius): ");

27 scale = getScale.next();

2829 System.out.print("Temperature: ");

30 temp = getTemp.nextDouble ();

3132 if (scale.equalsIgnoreCase("F")) {

33 scale = "Farenheit";

34 oppositeScale = "Celsius";

35 celsiusToFarenheit(temp);

60

36 }

3738 else if (scale.equalsIgnoreCase("C")) {

39 scale = "celsius";

40 oppositeScale = "Farenheit";

41 farenheitToCelsius(temp);

42 } else {

43 System.out.println("Invalid temperature scale.");

44 System.exit (55);

45 }

4647 System.out.printf("%.2f in %s is %.2f in %s.\n", temp , scale ,

answer ,

48 oppositeScale);

49 }

50 }

Program 6.4: ConvertsTemperature.java

$ java ConvertsTemperature

Scale (Type "F" for Farenheit or "C" fo Celsius): f

Temperature: 212

212.00 in Farenheit is 85.78 in Celsius.

$

5.7 Function Overloading

In the natural and abstract world we frequently add things together. For example the procedure for addingintegers differs from the one used for real numbers; If we want to make a new word by joining two old onesthe rules for adding the two words depends on the language; Tailors spend their days adding pieces of clothtogether; Lastly video editors and bittorrent fiends will spend time splicing video and audio files. If youthink about this it becomes very clear that even all these operations deal with addition the procedure forjoining the two components are all very different.

In procedural languages such as C we would create a separate adder for each datatype but with objectoriented languages such as Java we will put all these differing methods into a class called Adder.

1 package src;

23 public class Adder {

4

61

5 public static Complex add(Complex a, Complex b) {

6 Complex answer = new Complex ();

78 answer.setReal(a.getReal () + b.getReal ());

9 answer.setImaginary(a.getImaginary () + b.getImaginary ());

1011 return answer;

12 }

1314 public static String add(String a, String b) {

15 return (a + b);

16 }

1718 public static double add(double angleA , double angleB) {

19 double sum = degreesToRadians(angleA) + degreesToRadians(angleB);

2021 return (radiansToDegrees(sum));

22 }

2324 public static double degreesToRadians(double angleInDegrees) {

25 return (180.0 * angleInDegrees / Math.PI);

26 }

2728 public static double radiansToDegrees(double angleInRadians) {

29 return (angleInRadians * Math.PI / 180.0);

30 }

3132 public static void main(String [] args) {

33 Complex a = new Complex(5, 3);

34 Complex b = new Complex(2, 6);

3536 double angleOne = 280.0;

37 double angleTwo = 73;

3839 String firstBookTitle = "Flow My Tears The Policeman Said";

40 String secondBookTitle = "Burning Grass";

4142 double result = add(angleOne , angleTwo);

43 Complex answer = add(a, b);

4445 System.out.printf("%.2f degrees to %.2f degrees", angleOne ,

62

angleTwo);

46 System.out.printf(" gives a sum of %.2f dgerees .\n", result);

4748 System.out.print(a.toString () + " + " + b.toString ());

49 System.out.println(" = " + answer.toString ());

5051 System.out.print(add(firstBookTitle , secondBookTitle) + "\n");

52 }

5354 }

Program 6.5: Adder.java

Inside Adder there are three methods named add. Whenever subroutines have the same name we call thisphenomena overloading. Despite add being overloaded three times Java is able to tell all the methods apartbecause they all have differing return types as well as different types of arguments.

$ javac Adder.java

$ java Adder

280.00 degrees to 73.00 degrees gives a sum of 353.00 dgerees.

(3.0, 5.0) + (6.0, 2.0) = (9.0, 7.0)

Flow My Tears The Policeman SaidBurning Grass

$

While the first add returns a Complex object the second returns a String, while the last one returns a double.As for their arguments; the first add takes two Complex numbers, the second one two Strings, and the lastadd method requires to doubles.

The Java interpreter first looks at return types to see distinguish between overloaded functions. If the returntypes are the same then parameter list is used.

printsChar("A Fish , a barrel , and a smoking gun.");

printsChar(’H’);

Even though both printsChar functions do not return anything the interpreter can easily tell them apartbecause one takes a String while the other needs a char. If the overloaded methods have differing number ofarguments but of the same type Java can still tell them apart.

public int max(int x, int y) {

int result = x;

if ( y >= x )

result = y;

return result;

63

}

public int max(int x, int y, int z) {

if ( ( x >= y ) && ( x >= z) )

int result = x;

else if (( y >= x) && ( y >= z) )

int result = y;

else

int result = z;

return result;

}

5.7.1 How The Interpreter Evaluates Overloaded Functions

Since one max takes three arguments and the other takes two the Java can easily differentiate between bothsubroutines. To summarize the interpreters rules for distinguishing between overloaded functions:

1. Look at the return types to see which method should be invoked.

2. If inspecting the return types does not give an answer then look at how many arguments were passed.

3. If the methods have the same return type and same number of arguments then look at the data typesof the arguments from left to right.

4. If none of the preceding tests worked then the interpreter will implicitly typecast arguments to see ifit can get a match.

5. When all the other steps have failed Java will invoke the one that appears earliest in the class.

6. If all the steps failed then the compilation will fail.

5.8 Documenting Methods

An unwary programmer can make the mistake of invoking an overloaded method with the wrong arguments.This is one of the reasons why its a very important to document our functions. If you look at the literaturethere is a great deal of information on differing function documentation styles. One popular style involvesputting comments about the pre & post condition of the method as well as discussing boundary conditions.However this is not the best documentation style for Java,

64

To avoid confusion and make it easier for colleagues to read and understand what you are doing use the samedocumentation style that is in the Java APIs. On your system the documentation is at /javadoc/java1.6.0-opendjdk/api/index.html. If you take a look at the concat method for String class the API explains whatconcat returns, describes its function and tells u what data types concat’s parameters need to be.

/* getsVanderWaalsPressure calculates the pressure of a gas using the Van

* der Waals equation P = RT/(Vm - b) - (a/(Vm * Vm)).

*

* Precondition: Gets passed Van der Waals coefficients a & b, molar

* volume , & temperature. The variables are all doubles.

*

* Postcondition: Returns pressure as a double.

*/

public static double getsVanderWaalsPressure(double bCoeff , double aCoeff ,

double molarVol , double kelvinTemp) {

double pressure = (( GAS_CONST * kelvinTemp) / (molarVol - bCoeff)) - (

aCoeff /( molVol * molVol));

return pressure;

}

getsVanderWaalsPressure is one of GasModel’s subroutines. It turns out that the development shopthat owns this code prefers to use pre & post conditions to document their code.

5.8.1 Using Javadoc

As was mentioned before its best to follow Java’s recommended best practices to write documentation. Thiscan be done very easily with Javadoc.

1 package src;

23 import java.util.Random;

45 /**

6 * Displays a bar chart in ascending order of an array ’s contents.

7 *

8 * @param ARRAY_SIZE

9 * the size of the array.

10 * @param anArray

11 * global int array

12 */

13 public class BarCharter {

14 public static final int ARRAY_SIZE = 10;

65

15 private static int[] anArray;

1617 /**

18 * Get the largest value in intArray.

19 *

20 * @param intArray

21 * array to be searched for largest value.

22 * @param pos

23 * where the search starts in the array.

24 * @return the highest value found in the array.

25 */

26 public static int max(int[] intArray , int pos) {

27 int largest = intArray[pos];

2829 for (int i = pos + 1; i < intArray.length; i++)

30 if (intArray[i] > largest)

31 largest = intArray[i];

3233 return largest;

34 }

3536 /**

37 * Prints n stars.

38 *

39 * @param n

40 */

41 public static void printStars(int n) {

42 System.out.print(n + " | ");

4344 for (int i = 0; i < n; i++)

45 System.out.print("*");

4647 System.out.println ();

48 }

4950 /**

51 * Fills myArray with random numbers. Then calls max() and printStars

().

52 */

53 public static void main(String [] args) {

54 Random rander = new Random ();

66

55 int number;

5657 int[] myArray = new int[ARRAY_SIZE ];

5859 for (int i = 0; i < ARRAY_SIZE; i++) {

60 number = rander.nextInt (100);

61 myArray[i] = number;

62 }

6364 for (int j = 0; j < ARRAY_SIZE; j++) {

65 int currentMax = max(myArray , j);

66 printStars(currentMax);

67 }

68 }

69 }

Program 6.6: BarCharter.java

Somethings to notice are:

• The block comments are the same as what we have seen elsewhere.

• Each function parameter is described in the comment block.

• Each parameter’s description is separated from the function’s description by a blank line.

• Para,eter descriptions must be in the format; @param parameterName description of parameter.

• To describe what the method returns we use the @return tag.

• The main method does not have any parameter description.

There are many more tags available for avadoc but these will be sufficient for what is necessary at this time.After putting in the documentation now we need to generate a html file similar to what we saw in the JavaAPI. To create the html doc we run the command;

javadoc -d < documentaionDirectoryPath > fileName.java

So for BarCharter.java the command was;

$ javadoc -d /home/afura/java/docs/ BarCharter.java

$

5.9 Tips For Using Methods

Methods can make it much easier to write and debug programs. Some things that you should think aboutbefore writing will be discussed in this section.

67

5.9.1 One Task Per Method

If you try and accomplish more than one task in a function your body will be harder to debug and understand.So do not combine two tasks into one. Remember that functions are free but the debugging them is paid inblood. Furthermore functions have one return type not two for a reason.

5.9.2 Brevity Is Best

If I spend more than 20 minutes thinking about the steps in my subroutine I tend to assume that I am doingtoo much and might need to spawn other functions. As a result of this most of my methods are under 15lines. Making methods short aids in comprehending what is happening.

5.9.3 Don’t Overdo Overloading

Overloading is very useful to programmers. However care must be taken since on some occasions Java willimplicitly typecast a variable. If you are no paying attention to your code this implicit typecasting canintroduce subtle errors.

5.9.4 Debug As You Go

To make sure that each method works properly debug and test it once its written. Later on when we coverunit testing we shall look at the benefits of writing tests before implementing the methods. All methodsshould be debugged separately. One of the things that will make debugging easier for you is using Junitwhich we will discuss at a later time.

5.9.5 Provide Documentation

All your subroutines should have documentation about what they do. The documentation comments shouldbe terseness too much information, or redundant information can be confusing and takes time to read whileit does not give the programmer anything new. Apart from using javadoc make your identifiers, class andvariable names descriptive so that the program is self documenting.

5.9.6 When There Is Repetition Use A Function

If an operation is performed more than once in a program put the repeated code in a function.

5.10 Advantages Of Using Functions

Four of the main advantages of using functions are;

i By hiding the complexity of a program its easier for a reader to follow the overall flow & logic of aprogram. This is even easier if the names of functions describe what they do.

ii Important changes can be made and tested in a method without worrying about effects on the rest ofthe code.

68

iii When subroutines are used programmers can easily divide the work by each working on implementing amethod. This division of labour increases the speed at which applications will be deployed.

iv Code blocks that are repeated can be put into a method which streamlines the code. This can also cutdown on the amount of typing.

69

Package Class Tree Deprecated Index Help

PREV CLASS NEXT CLASS FRAMES NO FRAMES All Classes

SUMMARY: NESTED | FIELD | CONSTR | METHOD DETAIL: FIELD | CONSTR | METHOD

Class BarCharter

java.lang.Object extended by BarCharter

public class BarCharterextends java.lang.Object

BarCharter.java displays a bar chart of the numbers in an integer array. The integers are displayed indescending order.

Field Summarystatic int ARRAY_SIZE

Constructor SummaryBarCharter()

Method Summarystatic int FindMax(int[] intArray, int pos)

FindMax the maximum value in an array.

static void main(java.lang.String[] args) BarCharter's main method fills the global int[] myArray with random numbers.

static void PrintStars(int value) PrintsStars displays stars on the screen that correspond to a value.

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Field Detail

ARRAY_SIZE

public static final int ARRAY_SIZE

See Also:Constant Field Values

BarCharter file:///home/griot/code/java/BarCharter/BarCharter...

01/20/2011 05:58 AM

70

Chapter 6

Objects And Classes

In the first chapter it was mentioned that an object is a description of some data and the ways pf manip-ulating the data. For example consider pen be a set of data points related to its weight, the colour of itsink, how much ink is left, the shape, and its owner. There are a certain number of operations that can bedone with the pen. Mainly writing, but a frustrated person can also throw it, a nice pen can be refilled, butno matter how hungry a person is they will never try and eat a pen. Neither can we drive one to the next town.

Even though there are certain actions associated with a pen there are many that are not. We can drive acar object and eat an object called oranges though. With our intuitive understanding of what an object iswe can now define a class as a description of a data type that includes the methods for manipulating thedata and accessing the data.

The relationship between a class and its objects is similar to a car’s engineering blueprints and the car. Theblueprints simply describe what the components are and how they work. With the blueprint we can buildmany instances of the car. Similarly once we have defined a class we can make instances (objects) of thatclass.

6.1 Components Of A Class

Let us examine how classes are defined in Java by writing one for a point in the Cartesian coordinatesystem. Everyone is familiar with the Cartesian system’s X and Y axis and how points are referenced bytheir coordinates in the two dimensions.

71

1 package src;

23 import java.awt .*;

4 import javax.swing.JPanel;

56 /**

7 * Point.java creates a point using doubles on the Cartesian coordinate

system.

8 *

9 * @param x the x coordinate.

10 * @param y the y coordinate.

11 * @param z the z coordinate

12 */

13 public class Point {

14 private double x;

15 private double y;

16 private double z;

1718 /**

19 * Point () creates a point at the origin , (0,0,0)

20 */

21 public Point() {

22 x = 0;

23 y = 0;

24 z = 0;

25 }

2627 /**

28 * Point creates a point at xcoord , ycoor , & zcoord ..

29 *

30 * @param xcoord the x coordinate.

31 * @param ycoord the y coordinate.

32 * @param zcoord the z coordinate.

33 */

34 public Point(double xcoord , double ycoord , double zcoord) {

35 x = xcoord;

36 y = ycoord;

37 z = zcoord;

38 }

3940 /**

72

41 * getsX returns the value of the x coordinate.

42 * @return x coordinate.

43 */

44 public double getX() {

45 return x;

46 }

4748 /**

49 * getsY returns the value of the y coordinate.

50 * @return y coordinate.

51 */

52 public double getY() {

53 return y;

54 }

5556 /**

57 * getsZ returns the value of the z coordinate.

58 * @return z coordinate.

59 */

60 public double getZ() {

61 return z;

62 }

6364 /**

65 * setsX assigns a value to x coordinate.

66 * @param number value to assign too x.

67 */

68 public void setX(double number) {

69 x = number;

70 }

7172 /**

73 * setsY assigns a value to y coordinate.

74 * @param number value to assign too y.

75 */

76 public void setY(double number) {

77 y = number;

78 }

7980 /**

81 * setsZ assigns a value to z coordinate.

73

82 * @param number value to assign too z.

83 */

84 public void setZ(double number) {

85 z = number;

86 }

8788 public boolean equals(Point p) {

89 boolean answer = false;

9091 if (this.getX() == p.getX())

92 if (this.getY() == p.getY())

93 answer = true;

9495 return answer;

96 }

9798 public double distance(Point p) {

99 double result = 0;

100101 result = Math.pow((this.getX() - p.getX()), 2) + Math.pow((this.

getY() - p.getY()), 2);

102 result = Math.sqrt(result);

103104 return result;

105 }

106107 /**

108 * toString converts Point object into a string.

109 *

110 * @return a string.

111 */

112 public String toString () {

113 return ("(" + this.getX() + ", " + this.getY() + ", " + this.getZ

() + ")");

114 }

115116 public void Draw() {

117 Panel pointPanel = new Panel ();

118119 }

120 }

74

Program 7.1: Point.java

There are four main differences between Point.java and the other programs we have seen so far. These thingsare;

i The use of the keyword private.

ii The use of constructors, Constructors are methods that have the same name as their class.

iii The absence of a main method.

iv The use of the keyword this to refer to a calling object.

So we see that the layout of a class can be broken down into

ClassName {instance variablesConstructorsaccesor methodsmututor methods}

6.1.1 Instance Variables

These are the data points in the class. Instance variables have a global scope. All instance variables shouldbe preceded by the modifier private, Private prevents any function or class outside the current one fromdirectly accessing the instance variables. Doing this helps abstract the details away from the user, which isa good programming practice. Java best practices are to have private instance methods and public methodsto access the data. You also here people refer to instance variables as fields.

6.1.2 Constructors

The constructor is used to build an instance of a class. You should always create at least a default constructorwhich initializes all the data in the object to their null values. Unlike primitives objects and other abstractdata types are not initialized. Constructors are frequently overloaded as was seen in Point

Chaining Constructors

since we can have more than one constructor best practices in OOP are to have all the constructors thattake less options be passed to the one that that takes all the fields as arguments when creating an object.

6.1.3 Methods

The methods provide the API (Application Programming Interface) to the class’ data fields, hence they arepublic. Generally all functions either access data or modify it.

75

Mutators

These change the value of data in some way, best practices call for mutators to have void as their returntype. Sometimes people call mutators setters.

Accessors

Retrieve the value stored in an instance variable and pass it to the entity that called it. Accessors must havea nonvoid return type. A synonym for accessor is getter.

Static Versus Nonstatic Methods

No doubt you noticed that Point does not have a main method This is because main is a static method.Static methods it can be used without having a class. Since static procedures can only access data in theirclass they are sometimes called class methods. Functions that are not preceded with the static are instancemethods since any chapter four had the keyword static. Lastly a class that has static functions cannotcreate instances of itself.

6.2 Creating An Object

To use our class we need make an object of the class’ type. This will be done in another class or programby using the new keyword as shown below.

ClassName variableName = new ClassName(possible args);

This is similar to the declaration of primitive types but we use the word new to let the Java interpreter knowthat we are going to create an object. New is always succeeded by a constructor invocation. UsesPoint.javashows us how the classes are used in Java.

1 package src;

23 public class UsesPoint {

45 /**

6 * Tests points for equality.

7 * @param a

8 * @param b

9 * @return a boolean , true if the points are equal. otherwise false.

10 */

11 public static boolean isEqual(Point a, Point b) {

12 boolean result = false;

1314 if (a.getX() == b.getX()) {

15 if (a.getY() == b.getY())

76

16 if(a.getZ() == b.getZ())

17 result = true;

18 }

19 return result;

20 }

2122 /**

23 * Prints a message about two points.

24 * @param a

25 * @param b

26 * @param aString

27 */

28 public static void printsTestResult(Point a, Point b, String aString)

{

29 System.out.println(a.toString () + " and " + b.toString () + aString

);

30 }

3132 public static void main(String [] args) {

33 Point pointOne = new Point(3, -2, 34);

34 Point pointTwo = new Point (12, 4.25, -6.382);

35 Point origin = new Point ();

3637 boolean test = false;

38 String resultString = " are not the same";

3940 test = isEqual(pointOne , pointTwo);

41 if (test == true)

42 resultString = " are the same";

4344 printsTestResult(pointOne , pointTwo , resultString);

45 System.out.println("current value of origin is " + origin.toString

());

4647 origin.setX (3);

48 origin.setY(-2);

49 origin.setZ (34);

50 System.out.printf("\norign has been set to %s\n", origin.toString

());

5152 if (isEqual(pointOne , origin) == true)

77

53 resultString = " are the same";

5455 printsTestResult(pointOne , origin , resultString);

56 }

57 }

Program 7.3: UsesPoint.java

6.3 Static versus Nonstatic Variables

Static methods cannot be used outside their class, on the other hand any variables that have the keywordstatic as a modifier can be used outside their class. However static variables are not duplicated. This impliesthat there is only ever instance of a static variable, on the other hand each instance of a class gets its owninstance variables. Since all objects have access to static variables they can change the value globally. Thisbehaviour can lead to applications behaving in an unpredictable manner. For this reason a great deal of careshould be taken when using static variables.

6.4 Pass By Value Versus Pass By Reference

As was mentioned earlier a program’s data and methods are stored in memory. Main memory is organizedin 2-4 byte blocks and each block has an address. There are two ways that programs get their data, theyeither;

i Pass the address of the data to each other (pass by reference).

ii Pass the value stored in the location that has the data’s address (pass by reference).

6.4.1 Pass By Value

With pass by value every invoker gets a copy of the data, which implies that all these copies are independentof each other. All primitive data types are pass by value in Java. In ScopeIllustrator.java and Area.java wesaw pass by value being used.

6.4.2 Pass By Reference

Since this style uses the variable’s address all the invokers can modify the data shared in the address.All objects use pass by reference. The reason why is that unlike primitives objects have both data andmethods, these can be located anywhere in main memory and they are can all be of differing sizes. So theonly way an object can keep track of all its data and functions is to refer to their addresses. To see theimplications of reference passing instead of value passing let us look at both ReferencePassingTest1.java andReferencePassingTest2.java.

78

1 package src;

23 public class ReferencePassingTest1 {

45 public static void main(String [] args) {

6 Point aPoint = new Point(5, 6, -4.5);

7 Point counterPoint = new Point(5, 6, -4.5);

89 if (aPoint == counterPoint)

10 System.out.println("They are both aPoint at " + aPoint.

toString ()

11 + ".");

12 else {

13 System.out.printf("The two points are %s &", aPoint.toString ()

);

14 System.out.printf(" %s. They are not the same.\n",

counterPoint.toString ());

15 }

16 }

17 }

Program 7.4: ReferencePassingTest1.java

1 package src;

23 public class ReferencePassingTest2 {

45 public static void main(String [] args) {

6 Point myPoint = new Point(2, 3, 0);

7 Point yourPoint = new Point(-3, 12.458 , 6);

89 yourPoint = myPoint;

1011 if (yourPoint == myPoint)

12 System.out.println("We share the same point at "

13 + myPoint.toString () + ".");

14 else

15 System.out.printf(

16 "Since your point is %s you do not get my point.",

17 yourPoint.toString ());

18 }

19

79

20 }

Program 7.5: ReferencePassingTest2.java

The output of running the two programs ins shown below.

$ java ReferencePassingTest1

The two points are (5.0, 6.0) & (5.0, 6.0).

$

$ java ReferencePassingTest2

We share the same point at (2.0, 3.0).

$

Even though point and counterPoint have the same values the equality test on line 7 failed because its testingto see if their addresses are the same. On the other hand yourPoint was assigned to the same address as my-Point so their equality test returned true. One implication of objectA = objectB

is that there is no native Java method for assigning only values from one object to another because the =

operator makes objects point to the same address. As a result of this its very common to implement a copymethod in classes so that objects can have pass by value functionality.

6.5 Anonymous Objects

In the following code fragment a point within a certain range is being generated and compared with theorigin of a signal. However the variable being passed to compareWithSignalOrigin does not have a name.This is an anonymous object. Anonymous objects are frequently used as temporary place holders.

for (int i = 0; i < 23; i++)

for (int j = 32; j < 500; j++)

compareWithSignalOrigin(new Point(( double i,), (double j))

);

In the next fragment we see the same result being achieved without an anonymous object.

for (int i = 0; i < 23; i++)

for (int j = 32; j < 500; j++) {

Point temp = new Point (( double i), (double j));

compareWithSignalOrigin(temp);

}

6.6 Packages & Classpath

Frequently we need to make a class available to other programs or projects. To do this we create a packageand import it. In other languages such as C, C# or Scheme packages are called libraries. To use our ownpackages we need to add our libraries to the classpath.

80

6.6.1 Classpath

The classpath is an environment variable that tells the Java interpreter where packages are located. Soin Windows if the packages are in Programs Files\Java\jdk-1.6.04\libraries then that path is thedefault value classpath. In Unix the classpath could be \usr\lib\jdk-1.6.04. So when we issue thecommand import java.util.*; we are saying that Java should incorporate the all classes that are storedin \usr\lib\java\jdk-1.6.04/lib/java/util.

Modifying The Classpath

To add our packages to the classpath we simply place a semicolon at the end of the classpath then putthe path to our packages there. So if in Windows the classpath currently includes these directories C\

Windows\Java\jdk-1.5.9.48\jre and D\Program Files\java1.6.0.4.22\lib\jre and we want to addour personal libraries in F\myjars we would modify the classpath variable so that it looks like this.

C\Windows\Java\jdki -1.5\ jre:D\Programs\java1604 .22\ lib\jre:F\myjars:

Now that you know how to modify the classpath I need to tell you that its a bad idea to change it fromits default. This is because it can cause dependencies in your programs. Its better to set your application’sclasspath at compile time. So the preferred method for setting classpath is,

javac -classpath package path ProgramName.java

6.6.2 Making Packages

If you look at the The package import syntax you can tell that the packageName is actually the name of asubdirectory that is under one of baseDirectory’s subDirectories.

import baseDirectory.subDirectory.packageName.ClassName;

Package names are related to the directory path where related classes are found. This is a big reasonwhy the import and package statements take a a hierarchical argument. When Java is looking for a pack-age it assumes that is one of the locations specified in CLASSPATH so the package name needs to startwith the directory immediately below a classpath entry. Other directories below the base are listed after that.

To illustrate this my classpath has an entry \home\banji\code\java where all my Java programs arewritten. Each project has a folder of its own and sub folders bin, where the classes are; and src where I keepmy source code. One of my projects deals with managing my music library and has the following directorystructure.

81

So if I want to the class GetPicture, which is under the downloader to be available to other classes Ihave to put the line, package music.artwork.downloader; in the beginning of GetPicture’s declaration.If getWallPapers.java needs to use GetPicture then getWallPapers will import it with the statement;import music.artwork.downloader.GetPicture;

Or if I want all the classes in the downloader directory I could type import music.artwork.downloader.*;.As you can see I did not have to include the base directory java in either statement since that is in my path.

6.6.3 Marking Classes As Packages

Once the class path has been set then; either by setting the environmental variable, or at compile time wemark the class as a package with the command,

package ClassName

At the top of Script.java you can see how Script has been marked as a package. Also take note that thepackage statement shows the path in reverse order.

1 package net.kumbi.file.systems;

23 public class Script {

4 private String aFile = null;

56 public Script () {

7 this.aFile = null;

8 }

910 public Script(String aFile) {

11 this.aFile = aFile;

12 }

1314 public boolean isScript(String extension) {

15 String [] shellExtensions = new String [] { "sh", "pl", "py", "tk",

"tcl" };

82

1617 for (int i = 0; i < shellExtensions.length; i++) {

18 if (extension.equals(shellExtensions[i])) {

19 return true;

20 }

21 }

22 return false;

23 }

2425 public String getaFile () {

26 return aFile;

27 }

2829 public void setaFile(String aFile) {

30 this.aFile = aFile;

31 }

32 }

Program 7.6: Script.java

ZR

83

84

Chapter 7

Arrays

An array is a collection of items that are all of the same type and are stored in contiguous memory locations.The items in an array are referenced by their index, the index shows the item’s position in the array. It isimportant to note that array sizes are immutable.

index 0 1 2 3 4 5’a’ ’b’ ’c’ ’d’ ’e’ ’f’

Table 7.1: charArray

The statement,

char[] charArray = {’a’, ’b’, ’c’, ’d’, ’e’, ’f’};

made the array seen above. If a researcher wanted to store the ages of three hundred survey participantswho live in Jimeta they could use an array for this. Another situation where an array might be used is forstoring the length of time that 23,000 Glo customers spent waiting for a clear.

7.1 Declaring Arrays

Arrays are created with a statement that corresponds to one of the three forms;

dataType [] variableName;

dataType [] variableName = new dataType[ARRAY SIZE];

dataType [] variableName = {value0, value2, . . . , valuen−1}

The size of an array cannot be changed, we reference items in the array by using their indices. The indices’range goes from 0 to N −1 where N is the size of the array. From looking at the array declarations it shouldbe obvious that main takes as its argument an array of strings. The third array declaration is rarely used

85

since its only feasible for a very small number of items.

Most of the time we need to know the array’s length and this is very easy to do with since the Array class’instance variable length is not marked as public, this is what should always be used to find an array’s size.To put an item into one of the array’s cells we use the command,

arrayName[index] = item;

. And if we need to get the value stored in a cell we do storageVariable = arrayName[index];

7.1.1 IndexOutBounds Error

One frequent cause of errors is due to people trying to read or write past the bounds of an array. To see howthis works if you look at the invocation of setInt its trying to put 5 in the 8th location instead of the 7th.

int intArray [] = new int [7];

intArray.setInt (7,5);

char[] searchTerm = new char [20];

for (int i = 0; i <= 20; i++)

searchTerm[i] = char.parseChar(args[i]);

In the for loop we are taking the string passed to main and put each string into an array of chars calledsearchTerm. But we will get an out of bounds error.

7.1.2 Char Versus String Arrays

We know that a String is a list of characters, however a char array is not the String object. Whenever wedeclare a char array there are no methods included with it since chars are a primitive data type. On theother hand Strings have methods included for handling the data.

String stringer = "Blondie was good , Fletcher was bad , & Hans was ugly."

;

char[] strung = stringer;

during the compilation Java will report that the types are incompatible.

7.2 Initializing arrays

I stated earlier that manually filing and array is impracticable and so we fill them with a loop. We have seenthis being done for BarCharter.java. But CreatesArray.java only focuses on the creation and initializationof anArry so it should be easier to follow whats going on.

86

1 public class CreatesArray {

2 public static final int ARRAY_SIZE = 10; // size of the array.

34 public static void main(String [] args) {

5 int index = 0;

6 float [] anArray = new float[ARRAY_SIZE ];

78 for (index = 0; index < ARRAY_SIZE; index ++) {

9 anArray[index] = (( float) index) - 3.0f/(( float) index);

10 System.out.println("anArray[" + index +"] = " + anArray[index

]);

11 }

12 }

13 }

Program 8.1: CreatesArray.java

Note that instead of using a value for array size I set that in a constant. By using a constant for array sizeI can change the size of my array by only a value in one place. Whereas if I had not used the constant Iwould have to make at least two changes to my code. When the program is compiled and run we get resultsseen below.

$ java CreatesArray

anArray [0] = -Infinity

anArray [1] = -2.0

anArray [2] = 0.5

anArray [3] = 2.0

anArray [4] = 3.25

anArray [5] = 4.4

anArray [6] = 5.5

anArray [7] = 6.571429

anArray [8] = 7.625

anArray [9] = 8.666667

$

One other thing to note from the output is that unlike languages such as C or Fortran which would give asegmentation fault when a division by zero takes place the Java interpreter evaluates the expression correctlyas −∞.

7.3 Array Operations

Some of the things that are frequently done with arrays;

i Compare arrays for equality.

87

ii Set arrays equal to each other,

iii Sorting the array’s items.

iv Get the smallest value.

v Get the largest value.

vi Find the frequency at which an item occurs.

vii Search for an item.

viii Join two arrays together.

ix Find out how many of the cells contain data.

With procedural languages like C programmers tended to roll their own functions and libraries that did allthese things. Fortunately since arrays are a type of object there are instance methods for handling thesenine, typical, array operations. Java’s array methods are in java.utils.Arrays. Though we should alwaysuse the Java standard libraries knowing how to do these nine operation can make you a more proficientdeveloper. In MyArray.java I have written a class definition that does operations 1 - 8. To do the lastoperation we would have to add two more variables to the class, one for keeping track of how many cells hadbeen used and the total number of cells.

1 package arraise;

23 public class MyArray {

4 private int[] array;

56 /**

7 * Default constructor

8 */

9 public MyArray () {

10 this.array = null;

11 }

1213 /**

14 * @param args an arbitrary number of ints. (

15 */

16 public MyArray(int ... args) {

17 this.array = args;

18 }

1920 /**

21 * @return the array

22 */

88

23 public int[] getArray () {

24 return array;

25 }

2627 /**

28 * @param array the array to set as reference

29 */

30 public void setArray(int[] array) {

31 this.array = array;

32 }

3334 /**

35 * Find largest value in array.

36 * @return max

37 */

38 public int max() {

39 int result = this.array [0];

4041 for (int i = 0; i < this.array.length; i++) {

42 int next = i + 1;

43 if ( result < this.array[next])

44 result = this.array[next];

45 }

4647 return result;

48 }

4950 /**

51 * Find smallest value in array.

52 * @return min

53 */

54 public int min() {

55 int result = this.array [0];

5657 for (int i = 0; i < this.array.length; i++)

58 if ( this.array[i] < this.array[i++])

59 result = this.array[i];

6061 return result;

62 }

63

89

64 /**

65 * Copies contents of array. If the array is the wrong size it will

adjust it.

66 * @param array.

67 */

68 public void copy(int[] array) {

69 int[] temp;

7071 if ( isLengthEqual(this.array , array) == false ) {

72 int newSize = getSizeDifference(this.array , array);

73 temp = resizeArray(this.array , newSize);

74 }

7576 for (int i = 0; i < array.length; i++)

77 temp[i] = array[i];

7879 this.array = temp;

80 }

8182 /**

83 * Checks if the arrays contain the same things in order and the same

size.

84 * @param array

85 * @return boolean

86 */

87 public boolean isEqual(int[] array) {

88 boolean result = false;

8990 if ( isLengthEqual(this.array , array) == false )

91 return result;

92 else {

93 for (int i = 0; i < array.length; i++) {

94 if ( this.array[i] != array[i] )

95 return result;

96 else

97 result = true;

98 }

99 }

100 return result;

101 }

102

90

103 /**

104 * Checks the frequency of x.

105 * @param x

106 * @return int

107 */

108 public int frequency(int x) {

109 int count = 0;

110111 for (int i = 0; i < this.array.length; i++)

112 if (this.array[i] == x)

113 count ++

114 ;

115 return count;

116 }

117 /**

118 * Adds subarray to a MyArray.

119 * @param subarray

120 * @return int array

121 */

122 public int[] add(int[] subArray) {

123 int[] newArray = resizeArray(this.array , subArray.length);

124125 for (int i = newArray.length; i < subArray.length; i++)

126 newArray[i] = subArray[i - newArray.length ];

127128 return newArray;

129 }

130131 /**

132 * Sorts in ascending order.

133 */

134 public void sort() {

135 int temp = 0;

136137 for (int i = 0; i < this.array.length; i++)

138 for (int j = 1; j < this.array.length; j++)

139 if (this.array[i] > this.array[j]) {

140 temp = this.array[i];

141 this.array[i] = this.array[j];

142 this.array[j] = temp;

143 }

91

144 }

145146 /**

147 * Gets value stored at position.

148 * @param position

149 * @return int

150 */

151 public int getValueAt(int position) {

152 return this.array[position ];

153 }

154155 /**

156 * Checks if x is in the array.

157 * @param x

158 * @return boolean

159 */

160 public boolean search(int x) {

161 boolean result = false;

162163 for (int i = 0; i < this.array.length; i++)

164 if ( this.array[i] == x ) {

165 result = true;

166 return result;

167 }

168169 return result;

170 }

171172 /**

173 * Tests if arrays are the same length

174 *@param x

175 *@param y

176 *@return boolean

177 */

178 private boolean isLengthEqual(int[] x, int[] y) {

179 boolean result = false;

180181 if (x.length == y.length)

182 result = true;

183184 return result;

92

185 }

186187 /**

188 * Finds difference between the lengths of arrays x and y.

189 * @param x

190 * @param y

191 * @return int

192 */

193 private int getSizeDifference(int[] x, int[] y) {

194 return ( x.length - y.length);

195 }

196197 /**

198 * Will either return a larger or smaller array depending on the value

of size.

199 * @param array

200 * @param size

201 * @return int array.

202 */

203 private int[] resizeArray(int[] array , int size) {

204 int newSize = array.length + size;

205 int[] newArray = new int[newSize ];

206207 return newArray;

208 }

209 }

Program 8.2: MyArray.java

7.3.1 Comparing Arrays For Equality

Since arrays are objects they use pass by reference. And like all objects comparing using the == operatorwill just test to see if their references are the same. To test arrays for equality we will first check if they areof the same size. And if they are then we need to make sure that they contain the same values in their cellsin the same order. That is why isEqual looks at the contents of a MyArray object.

7.3.2 Copying Objects

As was stated in the previous chapter the assignment operator only copies the references of objects so to geta separate copy of an object we need to copy the contents to a temporary object and then assign the addressof the temporary object to our target. It is essential that the primitive types be duplicated otherwise wewill simply have copied references.

93

7.3.3 Methods With Variable Arguments

The method, add(Object a, Object b) takes two objects and returns a third. However there are manytimes when we want to add more than an arbitrary number of items, so we want a function that does theequivalent of a1 + a2 + · · ·+ an. In Java this can be done by using the variable argument operator, . . . asseen in one of MyArray’s constructors. The syntax of varag has when they are declared is,

subRoutineName(dataType. . . variableName)

Whenever varargs are mixed with fixed args the vararg must be the subroutine’s last parameter otherwisethe interpreter will think that all the parameters are varargs furthermore, there can be only one vararg perfunction. max uses varargs to find the largest double in a series.

public double max(double ... args) {

double result = arg [0];

for (int i = 1; i < args.length; i ++)

if (arg[i] > result )

result = arg[i];

return result;

Builtin Array Methods

As was mentioned Java has a number of builtin functions that do all of the operations in MyArray, youshould use the Java standard libraries instead of rolling your own. Java’s array class is in java.util.Arrays.

7.4 Referencing Arrays

Since an array is a contiguous collection of memory addresses that all hold data of the same type we canrefer to an array by its first element’s address display.

String [] someStrings = new String[ARRAY_SIZE ];

System.out.println(strings);

So in the two preceding lines only the first string in someStrings will be displayed on the console.

7.5 Passing Arguments To Main

Most applications that we use rely on a number of smaller programs. All these programs tend to shareinformation with each other. So far we have used Scanner to pass input to a program which is not scalable.In reality programs get their input from the arguments passed to main. Doing this also makes our programsmuch easier to standardize by creating menus that we can easily port from one application to another. Foran example of this look at Trigger.java.

94

1 public class Trigger {

23 public static double SumOfSquares( double num1 , double num2) {

4 double result = Math.pow(num1 , 2) + Math.pow(num2 , 2);

56 return result;

7 }

89 public static void Display () {

10 System.out.print("\nTrigger.java displays trig ratios of a right")

;

11 System.out.println(" triangle. To use this program type:\n");

12 System.out.println("java Trigger <number1 > <number2 > <number3 >");

1314 System.out.println("\nYou can see these help messages on this

program");

15 System.out.println("by entering one of the three commands below.")

;

16 System.out.println("java Trigger -h");

17 System.out.println("java Trigger --help");

18 System.out.println("java Trigger\n");

1920 System.exit (13);

21 }

2223 public static double GetMax(double x, double y, double z) {

24 double maximum = 0;

2526 if (( x > y) & (x > z))

27 maximum = x;

2829 if (( y > x) & ( y > z))

30 maximum = y;

3132 if ((z > x) & (z > y))

33 maximum = z;

3435 return maximum;

36 }

3738 public static boolean PythagoreanCheck(double max , double a, double b)

95

{

39 boolean answer = false;

40 double result = SumOfSquares( a, b);

4142 if (Math.pow(max , 2) == result)

43 answer = true;

4445 return answer;

46 }

4748 public static double GetCosine(double adjacent , double hypotenuse) {

49 return (adjacent/hypotenuse);

50 }

5152 public static double GetSine(double opposite , double hypotenuse) {

53 return (opposite/hypotenuse);

54 }

5556 public static double GetTangent(double opposite , double adjacent) {

57 return (opposite/adjacent);

58 }

5960 public static double GetArcTangent(double tangent) {

61 return (Math.atan(tangent) * 180 / Math.PI);

62 }

6364 public static double GetGamma(double theta) {

65 return (180.0 - (90.0 + theta));

66 }

6768 public static void main(String [] args) {

69 double side1 = 0;

70 double side2 = 0;

71 double side3 = 0;

7273 double opposite = 0;

74 double adjacent = 0;

75 double hypotenuse = 0;

7677 double angleTheta = 0;

78 double angleGamma = 0;

96

79 double cosineOfTheta = 0;

80 double sineOfTheta = 0;

81 double tangentOfTheta = 0;

8283 boolean isRightTriangle = false;

8485 switch(args.length)

86 {

87 case 0:

88 Display ();

89 break;

9091 case 1:

92 if (args [0]. equals("-h") || args [0]. equals("--help"))

93 Display ();

94 else {

95 System.out.println("Invalid option");

96 System.exit (34);}

97 break;

9899 case 3:

100 try {

101 side1 = Double.parseDouble(args [0]);

102 side2 = Double.parseDouble(args [1]);

103 side3 = Double.parseDouble(args [2]);

104 } catch(NumberFormatException e) {

105 System.out.println("Argument was not a number.");

106 System.exit (7);

107 }

108 break;

109110 default:

111 System.out.println("Invalid number of arguments.");

112 System.exit (3);

113 break;

114 }

115116 if (side1 == 0 || side2 == 0 || side3 == 0){

117 System.out.println("One of the sides is zero.");

118 System.exit (4);

119 }

97

120121 if ( GetMax(side1 , side2 , side3) == side1) {

122 hypotenuse = side1;

123 opposite = side2;

124 adjacent = side3;

125 }

126127 else if ( GetMax(side1 , side2 , side3) == side2) {

128 hypotenuse = side2;

129 opposite = side1;

130 adjacent = side3;

131 }

132133 else {

134 hypotenuse = side3;

135 opposite = side1;

136 adjacent = side2;

137 }

138139 isRightTriangle = PythagoreanCheck(hypotenuse , opposite , adjacent)

;

140141 if ( isRightTriangle == true ) {

142 cosineOfTheta = GetCosine(adjacent , hypotenuse);

143 sineOfTheta = GetSine(opposite , hypotenuse);

144 tangentOfTheta = GetTangent(opposite , adjacent);

145146 angleTheta = GetArcTangent(tangentOfTheta);

147 angleGamma = GetGamma(angleTheta);

148 }

149150 else {

151 System.out.println("Not lengths of a right angled triangle.");

152 System.exit (9);

153 }

154155 System.out.printf("For the right angled triangle with sides of

length");

156 System.out.printf(" %.2f, %.2f, & %.2f", hypotenuse , opposite ,

adjacent);

157 System.out.printf("\n Sine (%.2f) = %.2f", angleTheta , sineOfTheta)

98

;

158 System.out.printf("\n Cosine (%.2f) = %.2f", angleTheta ,

cosineOfTheta);

159 System.out.printf("\n Tangent (%.2f) = %.2f", angleTheta ,

tangentOfTheta);

160161 System.out.printf("\nAnd the third angle is ");

162 System.out.printf("%.2f degrees .\n", angleGamma);

163 }

164 }

Program 8.3: Trigger.java

You can see that there is a help menu and the user simply passes the arguments on the command line asseen below.

$ java Trigger

Trigger.java displays trig ratios of a right triangle. To use this

program type:

java Trigger <number1 > <number2 > <number3 >

You can see these help messages on this program

by entering one of the three commands below.

java Trigger -h

java Trigger --help

java Trigger

saleh: bin $ java Trigger 5 6 7

Not lengths of a right angled triangle.

$

By using the command line I have made my Trigger.java more versatile since now it can be piped input fromanother program.

7.6 Enumerated Types

Sometimes we want to have lists of a type of item. For example look at the menu for Best Little JoloffHouse In Texas, Since there are six differing rice dishes at the restaurant customers are likely to say Giveme a 4.when they want gumbo. For situations like this one where a list of items is associated with numbers(enumerated) we can use the enum type, the syntax for an enum is,

enum identifier { ITEM1, ITEMT2, . . . , ITEMn}

99

Please note that all the items are in caps.

Table 7.2: Best Little Joloff Rice House In Texas Menu

Menu

1. Joloff Rice 6.50

2. Tuwo 8.50

3. Fried Rice 6.50

4. Rice With Pepper Sauce 5.50

5. Shrimp Gumbo 8.50

6. Curry 6.50

Therefore to create an enum for The Best Little Joloff Rice House In Texas, enum riceDishes JOLOFF,

TUWO, FRIED, PLAIN, GUMBO, CURRY;. If we had used enum in ConvertsNumberToMonth.java the codewould be simpler and cleaner.

1 public class NumberToMonth {

2 enum Month {JAN , FEB , MAR , APR , MAY , JUN , JUL , AUG , SEP , OCT , NOV , DEC};

34 public static void main(String [] args) {

5 Month aMonth = Month.MAR;

6 Month [] month = Month.values ();

7 int arg = 0;

89 try {

10 arg = Integer.parseInt(args [0]);

11 } catch(NumberFormatException e) {

12 System.out.println("Argument was not a number.");

13 System.exit (7);

14 }

15 if ( (arg > 12) | (arg < 1) ) {

16 System.out.printf("%d is out of range\n", arg);

17 System.exit (12);

18 } else

19 System.out.println("Month is " + month[arg] + ".\n");

2021 System.out.print(aMonth.toString () + " is the time for rabbits and

grass");

100

22 System.out.println(" cutters to go mad.");

23 }

24 }

Program 8.4: NumberToMonth.java

We can intuitively define enums as an array of constants, however this is more to help us understand whatthey are like. Enums are a type of object and their only similarity to constants, which are a type ofprimitive, is that we cannot change the values in an enum. Also like constants enums come right after theclass name’s declaration and are not part of any function body.

$ java NumberToMonth 5

Month is JUN.

MAR is the time for rabbits and grass cutters to go mad.

$

As can be seen from NumberToMonth.java’s output enum’s have a method called values which builds anarray from the enum list’s contents. Also ordinal tells us where an item is in enum. You can also see thatto assign a value to an instance of enum the syntax is,

EnumInstance variableName = EnumInstance.VALUE

7.7 Multidimensional Arrays

There are situations where we wan to use multidimensional arrays. For example we have a table of pH versusmolarity of a solution. The syntax to make a multidimensional array is,

dataType[][]. . . [] identifier = new dataType[][]. . . []

So for a 3x3 array of boolean where each array is a differing size, boolean[][][] boolArray = new boolean

[3][3][3];. For a two dimensional int array, int[][] intArray = new int[5][7];. It should be obviousthat we need nested for loops to access the individual cells. Imagine that we want to make a board for chessor draughts. then we start with building an 8x8 array, char board [][] = new char[8][8]; If we wantto see whats in B-5 . . . piece = board[1][4]. And to fill our board we put the 32 tokens in either the firstor last 16 slots depending on their colour.

public void setPieces(int startingRow) {

int column = 0;

int row = 0;

// Fill the bottom from the 6th row , avoids writing two separate nested

loops.

if (startingRow == 7)

101

row = 6;

for (row; row < board[( stratingRow + 1)][ column ]; row++ ) {

for (coulmn; column < board[row]. lengthlength; column ++)

board[row][ column] = player.selector(getPiece ());

}

}

You might have noticed that in a multidimensional array the individual array lengths are independent of eachother so we can have what are called ragged arrays. Ragged arrays can be useful for developers but greatcare must be taken in implementing them since dealing with variable rows and columns is more complicatedthan with fixed squaremultidimensional arrays.

zr

102

Chapter 8

Inheritance

Inheritance is the process by which a class is derived from a base class. When the derived class is made itinherits the parent’s instance variables and methods. For an example of inheritance take a look at Vector

which inherits methods and data from Point

1 package src;

23 import java.lang.Math;

45 public class Vector extends Point {

6 private Point coordinate;

78 public Vector () {

9 this (0.0, 0.0, 0.0);

10 }

1112 public Vector(double x, double y, double z) {

13 super(x, y, z);

14 }

1516 public Vector(Point p) {

17 coordinate = p;

18 }

1920 public void setCoordinate(Point p) {

21 coordinate = p;

22 }

2324 public Point getCoordinate () {

25 return coordinate;

103

26 }

2728 public Vector add(Vector a) {

29 Vector result = null;

30 double i = this.getX() + a.getX();

31 double j = this.getY() + a.getY();

32 double k = this.getZ() + a.getZ();

3334 result = new Vector(i, j, k);

35 return result;

36 }

3738 public double dotProduct(Vector a) {

39 double i = this.getX() * a.getX();

40 double j = this.getY() * a.getY();

41 double k = this.getZ() * a.getZ();

4243 return (i + j + k);

44 }

4546 public double magnitude () {

47 double sumOfSquares = Math.pow(this.getX(), 2) + Math.pow(this.

getY(), 2);

48 sumOfSquares += Math.pow(this.getZ(), 2);

49 double result = Math.sqrt(sumOfSquares);

5051 return result;

52 }

5354 public Vector crossProduct(Vector a) {

55 double i = (this.getY() * a.getZ()) - (this.getZ() * a.getY()) ;

56 double j = (this.getZ() * a.getX()) - (this.getX() * a.getZ());

57 double k = (this.getX() * a.getY()) - (this.getY() * a.getX());

5859 return (new Vector(i, j, k));

60 }

6162 public double sine() {

63 return (this.getY() / this.magnitude ());

64 }

65

104

66 public double cosine () {

67 return (this.getX() / this.magnitude ());

68 }

6970 public double tangent () {

71 return ( this.getX() / this.getY());

72 }

7374 public double arcTan(double tangent) {

75 return (Math.atan(tangent));

76 }

7778 public double arcSine(double sine) {

79 return (Math.asin(sine));

80 }

8182 public double arcCosine(double cosine) {

83 return (Math.acos(cosine));

84 }

8586 public boolean isParallel(Vector a) {

87 boolean answer = false;

8889 if ( this.dotProduct(a) == (this.magnitude () * a.magnitude ()))

90 answer = true;

9192 return answer;

93 }

9495 public boolean isPerpendicular(Vector a) {

96 boolean answer = false;

9798 if (this.dotProduct(a) == 0)

99 answer = true;

100 return answer;

101 }

102103 public boolean equals(Object anObject) {

104 boolean answer = false;

105106 if (getClass () != anObject.getClass ())

105

107 return answer;

108 else {

109 Vector a = (Vector)anObject;

110111 if (this.getX() == a.getX())

112 if (this.getY() == a.getY())

113 answer = true;

114 }

115 return answer;

116 }

117118 }

Program 9.1: Vector.java

You can see that Vector inherits data and methods from Point then it extends them. On the other handVectorCalc is an implementation of Vector that adds two vectors together.

1 package src;

2 import javax.swing.JOptionPane;

34 public class VectorCalc extends Vector {

56 public static void main(String [] args) {

7 Vector a = new Vector(6, -2, -1);

8 Vector b = new Vector(2, 5, 2);

910 Point p = new Point (4.34 , 6, 0.87);

11 Point p2 = new Point(3, 6, 7);

12 String pachydermia = "Some elephants are gray and wrinkly , others

were wooly and massive";

1314 Vector result = a.crossProduct(b);

1516 System.out.printf("Vector %s has magnitude of a: %.2f.\n", a.

toString (), a.magnitude ());

17 System.out.printf("Vector %s has magnitude of b: %.2f.\n", b.

toString (), b.magnitude ());

18 System.out.printf("Cross product of %s & %s is %s", a.toString (),

b.toString (), result.toString ());

1920 double scalar = b.dotProduct(a);

106

21 System.out.printf("Dot Product of %s and %s is %.3f.\n", a.

toString (), b.toString (), scalar);

2223 result = a.add(a);

24 System.out.println("sum of " + a.toString () + " & " + b.toString ()

+ " : " + result);

2526 if (a.equals(pachydermia) == false)

27 System.out.println(a.getClass () + " and " + pachydermia.

getClass () + " are not the same.");

28 else

29 System.out.println(a.toString () + " and " + pachydermia + "

are the same.");

3031 if (a.equals(p2) == false)

32 System.out.println(a.toString () + " and " + p2.toString () + "

are not the same");

33 else {

34 System.out.println(a.toString () + " and " + p2.toString () + "

are the same");

35 System.out.println(a.getClass () + " and " + p2.getClass () + "

were the classes compared.");

36 }

3738 if ( p instanceof Vector)

39 System.out.println("Points and vectors are the same class.");

40 else

41 System.out.println("Points and vectors are not the same class"

);

4243 if (a.isParallel(result) == true)

44 System.out.println(a.toString () + " & " + result.toString () +

" are parallel.");

45 else

46 System.out.println(a.toString () + " & " + result.toString () +

" are not parallel.");

4748 if (a.isPerpendicular(b) == true)

49 System.out.println(a.toString () + " & " + b.toString () + " are

perpendicular.");

50 else

107

51 System.out.println(a.toString () + " & " + b.toString () + " are

not perpendicular.");

52 JOptionPane.showMessageDialog(null , a.toString () + " & " + b.

toString () + " are not perpendicular.");

53 }

54 }

Program 9.2: VectorCalc.java

To mark a class as derived from another we need to put the following line at the beginning of the classdeclaration.

SubClass extends SuperClass { Subclass body }

The subclass has access to the same data types and methods that are in the parent so we do not need torecreate those. Because of this inheritance is one of the simplest ways to reuse code efficiently. In Figure 8.1it will be seen that the super class of atomic particles has a subclass of composite particles. Furthermore,even though Fermions can have only one super class as its parent it can have multiple subclasses (protonsand neutrons to name a few) as its children.

108

8.1 Properties Of Subclasses

Subclasses, which are also called child, or derived classes, have a number of properties that we will spendmost of this chapter discussing. The characteristics are;

i They can only have one parent. Unlike C++ where there is multiple inheritance Java derived classes canonly get their instance variables and methods from one super class.

ii A super class’ constructors cannot be inherited but they can be invoked from a subclass’ constructorwith the keyword super.

iii A derived class does not have to implement all the instance methods in the super class. We only needto create instance variables specific to the child class.

iv A child class can redefine the implementation of a super class’ instance methods, this is called overriding.

8.2 Invoking Super Class Constructors

We know that constructors initialize an object’s instance variables, so we can use the parent’s constructorto set the values of inherited variables. Whenever a subclass is created it either implicitly invokes the superconstructor as is seen in the Square’s default constructor. Or explicitly like what we see in the class’ secondconstructor.

public class Square extends Quadrilateral {

private double length;

public Square () {

length = 0;

}

public Square(double length) {

super (length , length , length , length);

}

In the second constructor the super class’ constructor is explicitly invoked and given the length of all thesides.

8.2.1 Reference Constructors

it might have been noticed that when we overload Constructors a great deal of the code is the same. Tocut down on typing duplicate code many developers pass one constructor’s argument’s to another. Whenthis is done the Constructor that all the others invoke is called a reference constructor. The overloadedconstructors call the reference one by using the this operator as seen in the code fragment for MyArray

public MyArray () {

this(null);

109

}

public MyArray(int[] a) {

this(a);

}

public MyArray(int ... a) {

size = a.length;

array = a;

}

When the number of options that can be used to create object is greater than three you should either us aParameter or Builder class. However those two methods of dealing with classes with multiple constructorarguments are beyond the scope of this chapter.

8.2.2 Protected Instance Variables

One of the reasons why we need to invoke the superclass constructor is that we have to instantiate variablesthat are marked private. Since they are marked private no object can directly access them. We know thatif the instance variables are marked public any object that uses the class can modify their properties, fur-thermore this can cause problems in learning what the variable’s state is.

However there are times when we want child objects to directly access their parent’s instance variables. Forsuch cases we use the protected modifier. Consider that for 8× 8 board games will have a declaration,

public class Board {

int dimension;

int [][] board;

Since under this class we have Chess, Checkers & other games if we have an instance of the Chess whichhas its own children, Rules, Pieces, etc, that all need to access the board we might find it easier to makethe array board protected. However using protected can make your program more complicated to debugsince the superclass’ instance variables can be modified by its children. Furthermore, if the parent class’variables are private then any changes that are made to the super class will not affect the children. Soanother problem associated with protected variables is more code reviews.

An alternative to marking variables as protected is to make them static. With static there is one instanceof the variable that is available to each object of the class.

8.3 Invoking A Superclass’ Methods

Consider an instance of the Proton class whose ancestor is CompositeParticles and its parent is Hadron.We use the following syntax to invoke a super class’ method.

110

super.methodName(arguments);

So if we want to invoke Hadron’s getFieldDirection method we would do the following;

Proton aProton = new Proton ();

aProton.fieldDirection = super.getFieldDirection ();

From this it can be seen that we can only directly invoke the parent’s methods and not its ancestor’s.Another example of using the parent’s method directly is seen in Force. Force directly invokes Vector’smethods of calculating its x & y components on its method totalForce

1 package src;

23 public class Force extends Vector {

4 private double mass;

5 private double radians;

6 private Vector friction;

7 private Vector acceleration;

89 public static final double GRAVITY = 9.8;

1011 public Force() {

12 this(0, 0, null , null);

13 }

1415 public Force(double mass , double radians , Vector friction , Vector

acceleration ) {

16 this.mass = mass;

17 this.radians = radians;

18 this.friction = friction;

19 this.acceleration = acceleration;

20 }

21 }

Program 9.3: Force.java

8.3.1 Overriding Methods

When a derived class changes the implementation of one of its parent’s methods that is called overriding.When we wrote our toString methods we were actually overriding toString that is in the Object class.An overriden method’s scope only exists int he child not the parent. And it must have the same functionprototype as its parent’s namesaked function. If you look at figure 7.2 you will see that all the subclassesposses methods with the same names.

111

Restrictions On Overriden Methods

There are two main restrictions that can be placed on overriden functions. The first deals with their returntype, the second concerns access permissions. Since derived classes are still instances of their base class wecan change the return type to a specific object than the parent. As for access permissions a derived class’methods can always be made less restrictive than its parents but never more restrictive.

Parent’s Access Modifier Child’s Access Modifierspublic public

protected public, protectedprivate private, protected, public

Table 8.1: Allowed Child Class Access Modifiers

So we can make make have the prototype public MyArray clone() or public Object clone(). But wecannot have private int hashCode().

112

If we do not place any access modifiers on an instance variable or method then Java gives it the defaultaccess permissions to package. When a method or indentifier has package access that means that allthe classes within its package can access it. So imagine that we have the two classes Bulletphysics andCalculateWindVelocty are both in the default Eclipse package src and we do not use any the accessmodifiers private, public, or protected on their methods or identifiers, then its possible for both classes tocall each others methods and access each others data directly. Its not a good idea to use the default accessmodifier.

Overriding Versus Overloading

Overloaded methods can have a differing number of parameters, order of parameters, and completely dif-fering return types. On the other hand overriden functions must have the same class of return type andparameters, as well as the same number of parameters.

From this you can tell that all of our implementations of toString have been overrides. Whereas wehave been using function prototypes of the form boolean equals(ObjectName, obj) in the Java APIequals is supposed to have the prototype boolean equals(Object obj).So you can seen that we havebeen overloading the equals subroutine.

Using GetClass Versus Instanceof For Comparisons

You might have noticed that Vector’s equals uses getClass from the Object class. This method willreturn true if the two classes are the same. Since children are instances of their parent class getClass willalways return true. In VectorCalc.java we not only use getClass indirectly via Vector’s equals methodbut also directly compare two objects using the instanceof keyword to compare a and p. You will noticethat when instanceof is used then the result is false.

Magnitude of a: 9.695359714832659

Magnitude of b: 5.830951894845301

Cross Product: (30.0 , 6.0, -18.0)

Dot Product: 44.0

sum of (3.0, 6.0, 7.0) & (3.0, 0.0, 5.0) : (6.0, 12.0, 14.0)

class src.Vector and class java.lang.String are not the same.

(3.0, 6.0, 7.0) and (3.0, 6.0, 7.0) are the same

class src.Vector and class src.Point were the classes compared.

Points and vectors are not the same class

(3.0, 6.0, 7.0) & (4.34, 6.0, 0.87) are not parallel.

(3.0, 6.0, 7.0) & (4.34, 6.0, 0.87) are not perpendicular.

If you use instanceof then it might break some things in the logic and tried the following it will not workcorrectly given that a Force object is also a Vector and Charge derived from Force. It would be betterfor us to typecast to make sure that children can use their parent’s methods and data without any problems.

Force torque = new Force(acceleration , mass);

Charge source = New Charge(current , time);

113

if (Charge instanceof Force)

source.super.equals(otherCharge);

There are good reasons to use instanceof but you need to exercise caution when using it.

8.4 The Final Modifier And Its Effects

Final prevents whatever its associated with from being modified. This means that radius in the followingstatement cannot have its value changed.

final double radius = 36.859;

Now that you have seen it you know why constants must always have final in their declaration, also usingstatic with an identifier assures that there will only be one instance of that variable to all of th objects.

8.4.1 Final Methods

If a subroutine is marked final in a class then none of the descendant classes can override the finalizedsubroutine. An example of a final method is in the code fragment below.

class Ballot {

. . . . .

final Candidate getVote(String office) {

return (getsCandidatePicked(selectContendersArray(office)));

}

. . . . .

As you probably guessed getVote cannot be overriden. Any of Ballot’s derived classes have to use getVote

as is. One important use of final subroutines is when constructors invoke subroutines all the functionsinvoked by the constructor should be marked final so that a child class does not accidentally change theimplementation of its parent’s constructor.

8.4.2 Final Classes

We can also mark a class as final. When we do this that means that the no other children can be madefrom it.

8.5 Effects of The Static Modifier

Now that we have examined the impact that static has on identifiers and functions in a class. Right now wewill look at what effect the keywods static and have on inheritance. We will also discuss importing staticmembers in your Java code.

114

8.5.1 Static Methods Cannot Be Inherited

As you know a function marked static cannot access data outside its class so whenever static is associatedwith a procedure the class that the procedure belongs to cannot be inherited. This is why we cannot createchild classes whenever our base class has a main method.

8.5.2 Static Imports

You have seen that whenever we need to use a print method or items in java.lang.Math.java we have to add thepackage to the identifier i.e. area = Math.pow(radius, 2)* Math.PI, or System.out.println(‘‘I’ve

been downcast so damn long that runtime errors are likely. I say I’ve been downcast for so

long that I need to be upcast the hierarchy tree.’’). The reason why we have to do is that theseclasses are static so when we use them we must state the full path to their methods, constants and variables.However this can sometimes create a lot of typing, to cut down on that we can explicitly import the packagewith a statement in the format

import static name.of.static.package;

So to statically import println I would have the import static java.lang.System.out; at the top of myprogram. You can see two examples of static imports being used in BadPractice.java

1 import static java.lang.Math .*;

2 import static java.lang.System.out;

34 public class BadExample {

56 public static void main(String [] args) {

7 double radius = 12;

8 double circumfrence = 0;

910 circumfrence = 2 * radius * PI;

1112 out.printf("The circumfrence of the circle with radius %.2f",

radius);

13 out.printf(" is %.2f.\n", circumfrence);

14 }

15 }

Program 9.3: BadExample.java

Use Static Imports Sparingly

I called the last program BadPractice because the Java documentation put out by Sun says that staticimports should be used sparingly. Liberal use of static imports is frowned upon because it can cause

115

problems with inheritance. Also its important for the JVM to know what classes the static data or methodcomes from so that any constraints on their behaviour or access can be followed properly. To find out moresee http://download.oracle.com/javase/1,5.0/docs/guide/language/static-import.html

8.6 Accessors That Return Objects

We have already seen that fields in an object are generally marked private and we get the value stored in afield with an accessor. Given that consider the following class.

1 public class SuperClass {

2 private

3 }

116

Chapter 9

Polymorphism

Consider the set of objects that make up the class of sea creatures. All the sea creatures do the followingthings.

Reproduce

Eat

Defend themselves

Excrete wastes

Communicate

Sense

Move

Grow

Repair themselves

Breathe

The only sea creature that do not move around are fixed plants like some of the kelp and seaweed. Althoughthey all can perform the tasks listed above the way each type of sea creature does its thing will be different.To defend itself a crab will hide in its shell, a jelly fish will use its stingers, Although tuna and blue whalesswim in schools to protect themselves the tuna scatter in different directions to confuse predators while bluewhales will form a defense cordon and try and drive the attacker away with headbutts. To move from pointA to B a crab crawls on the sea floor, whales and tuna swim, while a jellyfish will simply drift on the ocean’scurrents.

All this implies that if we were going to create a java simulation of all the sea creatures they would be in thesuperclass SeaCreature which would have the instance methods move, reproduce, defend, eat as wellsome others corresponding to the other tasks that were listed above. However the implementation of eachmethod will differ based on the type of SeaCreature, and some subclasses such as as RootedPlants willnot have any implementation of move. This property of each method’s implementation differing based onthe subclass is polymorphism.

There are a number of different ways that polymorphism is achieved in Java, one of the them overridinghas already been discussed in this chapter we shall look at three other ways of making a group of classespolymorphic. The three emthods we are going to discuss are:

117

• Upcasting/Downcasting

• Abstract Classes

• Interfaces

• Inner Classes

What we want to achieve with polymorphism is that whenever an object invokes a method its subclassesuse its implementation of the called method and not some other class’. To illustrate this if you could tell aperson,a dog, a komodo dragon, and cat all to speak they would all the animals would make differing sounds.With polymorphism we are trying to have the same effect.

9.1 Method Binding In Java

There are two times when the Java Virtual Machine can decide which implementation of move it shouldinvoke for a SeaCreature object. This can be done either at compile time or at runtime. Which evermethod it uses a specific method will be bound to an object. Now we shall discuss the two binding methods.

9.1.1 Early Binding

In early binding the class and the correct method for each class instance is determined at compile time.Generally when you use overloading or are using a compiled language early binding is done. Sometimes thisis called static binding. Java only uses early binding for methods that have been marked either static orfinal.

9.1.2 Late Binding

If an object’s immediate class and the version of the method that it calls is determined at runtime then latebinding is taking place. Most interpreted languages use late binding. A synonym for late binding is dynamicbinding. Though most Java developers will state that that JAva uses late binding to be exact what is goingon is something OOP researchers call type introspection.

IN Java dynamic binding is used for all nonstatci, nonfinal classes and methods. Since dynamic binding isused in Java let us consider what happens when PacificSwimmers.java is run.

1 package ocean;

23 public class PacificSwimmers {

45 public static void main(String [] args) {

6 double speed = 0.0;

7 double directionInDegrees = 0.0;

89 int numOfKrill = 200000;

1011 Whale mobyDick = new Whale("Moby -Dick");

12 Krill krillGruppe = new Krill("Krill Group", numOfKrill);

118

1314 speed = 10.0;

15 directionInDegrees = 90.0;

16 mobyDick.move(speed , directionInDegrees);

1718 speed = 0.3;

19 directionInDegrees = 270.0;

20 krillGruppe.move(speed , directionInDegrees);

2122 mobyDick.eat(krillGruppen);

2324 Person ahab = new Person("Captain Ahab");

25 ahab.move (1.0, 300);

26 System.out.print("Captain Ahab is " + ahab.getStatus ());

2728 Time attackTime = new Time (60);

2930 mobyDick.attack(ahab , attackTime);

31 ahab.defend(attackTime);

3233 if (ahab.getDamage () >= 0.5)

34 ahab.setStatus("dead");

3536 System.out.print("krill Group’s status is ");

37 System.out.println(krillGruppe.getStatus () + ".");

3839 System.out.print("Moby -Dick’s status is ");

40 System.out.println(mobyDick.getStatus () + ".");

4142 System.out.print("Captain Ahab’s status is ");

43 System.out.println(ahab.getStatus () + ".");

44 }

4546 }

Program 10.1: PacificSwimmers.java

Now at runtime the JVM knows that both mobyDick andkrillGruppe are SeaCreature objects, it finds thisinformation out at lines 9 & 10. However it does not decide which implementation of move is the right onefor mobyDick or krillGruppe until lines 16, 20, & 25. This mechanism of late binding of a function to a classby the JVM is the basis of polymorphism in Java.

Now that you understand what polymorphism is in Java we can spend the rest of the chapter looking firstly

119

at the effects that late binding have on the super and sub classes, this will be the main focus of the sectionscovering upcasting and downcasting. After that we shall look at how the four polymorphism techniques canbe used to improve software design.

9.2 Upcasting Versus Downcasting

Instance methods can be invoked either down the class hierarchy or up the class hierarchy. One invocationmethod is called upcasting while the other is downcasting. In both types of cast what is going on is that weare referencing an object’s address. Either the subclass is referencing a superclass’ instance or a superclassinstance is referencing a subclass’ object.

9.2.1 Upcasting

Here a superclass object is is assigned to a subclass’ instance, then it uses the subclass’ procedures. Sincederived classes are a subset of the base class they will have all the instance fields and functions of the baseclass and the upcasting can be done implicitly. The ways you can do an upcast are as follows;

BaseClass instanceOfBaseClass = instanceOfDerivedClass;

instanceOfBaseClass = instanceOfDerivedClass;

instanceOfBaseClass = (BaseClass) instanceOfDerivedClass;

We can see upcasting being done in Piecer.java piece

1 package game.piece;

23 public class Piecer {

45 public static void main(String [] args) {

6 CheckerPiece redChecker = new CheckerPiece ();

78 Piece aPiece;

9 aGamePiece = (Piece) redChecker;

1011 int column = 5;

12 int row = 3;

1314 aPiece.move(aPiece.getCurrentPosition (), aPiece.getNextPosition(

column , row));

15 }

120

16 }

Program 10.2: Piecer.java

redChecker is upcast to aPiece on line 9. and then on line 14 aPiece uses CheckerPiece’s instance methodsgetCurrentPosition, getNextPosition, & cnamemove instead of GamePiece’s instance methods. To geta better idea of upcasting’s impact we create a group of classes dealing with clothing sizes, GarmentSize,TrouserSize and ShowsUpCasting.

1 package clothing;

23 enum Gender {MALE , FEMALE , NEUTER}

45 public class GarmentSize {

6 private Gender aGender;

78 private String ageGroup;

9 private String size;

1011 private int age;

1213 public GarmentSize () {

14 this(null , null , null , 0);

15 }

1617 public GarmentSize(Gender aGender , String size , int age) {

18 this(aGender , null , size , age);

19 this.ageGroup = ageToAgeGroup(age);

20 }

2122 public GarmentSize(Gender aGender , String ageGroup , String size ) {

23 this(aGender , ageGroup , size , 0);

24 }

2526 public GarmentSize(Gender aGender , String ageGroup , String size , int

age) {

27 super ();

28 this.aGender = aGender;

29 this.ageGroup = ageGroup;

30 this.size = size;

31 this.age = age;

32 }

33

121

34 public Gender getaGender () {

35 return aGender;

36 }

3738 public void setaGender(Gender aGender) {

39 this.aGender = aGender;

40 }

4142 public String getAgeGroup () {

43 String answer = ageGroup;

4445 return answer;

46 }

4748 public String ageToAgeGroup(int age) {

49 if ((age >= 0) && (age <= 1))

50 ageGroup = "baby";

51 else if ((age >= 2) && (age <= 5))

52 ageGroup = "toddler";

53 else if ((age >=6) && (age <= 12 ))

54 ageGroup = "preteen";

55 else if ((age >= 13) && (age <= 19))

56 ageGroup = "teenager";

57 else if (age > 20 )

58 ageGroup = "adult";

59 else

60 ageGroup = "undetermined";

6162 return ageGroup;

63 }

6465 public void setAgeGroup(String ageGroup) {

66 if (! checkAgeGroup(ageGroup))

67 handlesIncorrectEntry("ageGroup");

68 else

69 this.ageGroup = ageGroup;

70 }

7172 public String getSize () {

73 String answer = size;

74 return answer;

122

75 }

7677 public void setSize(String size) {

78 if ((this instanceof GarmentSize) && (this.getClass ().getName ().

equals("clothing.GarmentSize"))) {

79 if (! checkSize(size))

80 handlesIncorrectEntry("size");

81 }

82 else

83 this.size = size;

84 }

8586 public int getAge () {

87 int answer = age;

88 return answer;

89 }

9091 public void setAge(int age) {

92 if ( age < 0)

93 handlesIncorrectEntry("age");

94 else

95 this.age = age;

96 }

9798 public String toString () {

99 return "[gender=" + aGender + ", age group=" + ageGroup + ", size=

" + size + "]";

100 }

101102 public boolean checkAgeGroup(String aString) {

103 String [] ageGroups = {"baby", "toddler", "preteen", "teenager", "

adult", "undetermined"};

104105 return checksForMatch(aString , ageGroups);

106 }

107108 public boolean checkSize(String aString) {

109 String [] sizes = {"XS", "S", "M", "L", "XL", "XXL"};

110111 return checksForMatch(aString , sizes);

112 }

123

113114 private boolean checksForMatch(String toMatch , String [] stringArray) {

115 for (int i = 0; i < stringArray.length; i++)

116 if (toMatch.equalsIgnoreCase(stringArray[i]))

117 return true;

118119 return false;

120 }

121122 protected void handlesIncorrectEntry(String fieldName) {

123 if (fieldName.equals("ageGroup")) {

124 System.out.print("Valid age groups are: baby , toddler , preteen

");

125 System.out.println(", teenage , adult , and undetermined.");

126 }

127128 if (fieldName.equals("size"))

129 System.out.print("Valid sizes are: XS , S, M, L, XL , and XXL");

130131 if (fieldName.equals("age"))

132 System.out.println("Valid ages are greater than or equal to

zero.");

133134 System.exit (57);

135 }

136137 }

Program 10.3: GarmentSize.java

Below you can see TrouserSize which is derived from GarmentSize.

1 package clothing;

23 public class TrouserSize extends GarmentSize {

4 private int waist;

5 private int inSeam;

67 public TrouserSize () {

8 this(null , null , 0, 0);

9 }

1011 public TrouserSize(Gender aGender , String ageGroup , int waist , int

124

inSeam) {

12 super(aGender , ageGroup , null , 0);

13 this.waist = waist;

14 this.inSeam = inSeam;

15 this.setSize(intsToSizeString ());

16 }

1718 public TrouserSize(Gender aGender , String ageGroup , String size) {

19 super(aGender , ageGroup , null , 0);

20 this.setSize(size);

21 this.waist = getWaistFromSize(size);

22 this.inSeam = getInSeamFromSize(size);

23 }

2425 public int getWaist () {

26 return waist;

27 }

2829 public void setWaist(int waist) {

30 this.waist = waist;

31 }

3233 public int getInSeam () {

34 return inSeam;

35 }

3637 public void setInSeam(int inSeam) {

38 this.inSeam = inSeam;

39 }

4041 public void setSize(String size) {

42 if ( (this instanceof TrouserSize) && ( checkSize(size) == false))

43 super.setSize("Unk");

4445 else if ( (this instanceof TrouserSize) && ( checkSize(size) ==

true))

46 super.setSize(size);

4748 else {

49 System.out.println(this.getClass ().getName () + "is not a pair

of trousers.");

125

50 System.exit (25);

51 }

52 }

5354 public String toString () {

55 return "[waist=" + waist + ", inseam=" + inSeam + ", gender=" +

getaGender () + ",, age group=" + getAgeGroup () + "]";

56 }

5758 @Override

59 public boolean checkSize(String aString) {

60 String middleLetter = "x";

6162 return (middleLetter.regionMatches (0, aString , 2, 1));

63 }

6465 private int getWaistFromSize(String size) {

66 int waist = 0;

6768 if (checkSize(size))

69 waist = Integer.parseInt(size.substring (0, 1));

7071 return waist;

72 }

7374 private int getInSeamFromSize(String size) {

75 int inSeam = 0;

7677 if (checkSize(size))

78 inSeam = Integer.parseInt(size.substring(3, 4));

7980 return inSeam;

81 }

8283 private String intsToSizeString () {

84 String size = waist + "x" + inSeam;

85 return size;

86 }

8788 }

Program 10.4: TrouserSize.java

126

After creating those two classes we use ShowsUpcasting to look at what happens when an instance ofTrouserSize is upcast to a GarmentSize object.

1 package clothing;

23 import java.awt.GridLayout;

45 import javax.swing.JPanel;

6 import javax.swing.JFrame;

7 import javax.swing.JLabel;

8 import javax.swing.JTextField;

910 public class ShowsUpcasting {

1112 public static void main(String [] args) {

13 JFrame framer = new JFrame("Garment Size Informer");

14 framer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

15 framer.setLayout(new GridLayout (1, 3));

16 framer.setSize (600, 600);

17 framer.setVisible(true);

1819 JPanel leftPanel = new JPanel(new GridLayout (4, 1));

20 framer.add(leftPanel);

2122 JPanel centerPanel = new JPanel(new GridLayout (4, 1));

23 framer.add(centerPanel);

2425 JPanel rightPanel = new JPanel(new GridLayout (4, 1));

26 framer.add(rightPanel);

2728 TrouserSize plaidPants = new TrouserSize(Gender.MALE , "adult", 34,

30);

29 TrouserSize myDockers = new TrouserSize(Gender.FEMALE , "preteen",

"12x10");

3031 GarmentSize clothing = new GarmentSize(Gender.FEMALE , "teen", "m")

;

32 GarmentSize moreClothing = plaidPants;

3334 addsPanelItems(leftPanel , clothing);

35 addsPanelItems(rightPanel , moreClothing);

36 addsPanelItems(centerPanel , myDockers);

127

37 }

3839 public static String getLabelTitle(GarmentSize clothing) {

40 String title = null;

4142 String prefix = "clothing.";

43 String suffix = "Size";

4445 String objectName = clothing.getClass ().getName ();

4647 title = objectName.substring (( prefix.length () - 1), (objectName.

length () - suffix.length ()));

48 return title;

49 }

5051 public static void addsPanelItems(JPanel panel , GarmentSize garment) {

52 JLabel clothingType = new JLabel("Garment Type");

53 JLabel size = new JLabel("Size");

54 JLabel gender = new JLabel("Gender");

55 JLabel ageGroup = new JLabel("Age Group");

5657 JTextField showClothingType = new JTextField (20);

58 showClothingType.setText(getLabelTitle(garment));

5960 JTextField showSize = new JTextField (10);

61 showSize.setText(garment.getSize ());

6263 JTextField showGender = new JTextField (10);

64 showGender.setText(garment.getaGender ().name());

6566 JTextField showAgeGroup = new JTextField (10);

67 showAgeGroup.setText(garment.getAgeGroup ());

6869 JPanel row1 = new JPanel(new GridLayout (1,2));

70 row1.add(clothingType);

71 row1.add(showClothingType);

7273 JPanel row2 = new JPanel(new GridLayout (1,2));

74 row2.add(gender);

75 row2.add(showGender);

76

128

77 JPanel row3 = new JPanel(new GridLayout (1,2));

78 row3.add(ageGroup);

79 row3.add(showAgeGroup);

8081 JPanel row4 = new JPanel(new GridLayout (1,2));

82 row4.add(size);

83 row4.add(showSize);

8485 panel.add(row1);

86 panel.add(row2);

87 panel.add(row3);

88 panel.add(row4);

89 }

9091 }

Program 10.5: ShowsUpcasting.java

You will see that plaidPants is being upcast into moreClothing on line 32 of ShowsUpcasting.java. And thenwhen we run the program we see what’s been stored in each object’s fields.

129

From this we can see that moreClothing uses TrouserSize’s methods instead of GArmentSize’s methods.Lastly remember that objects are pass by reference so upcasting is just having a superclass identifier pointto a subclass object instead.

9.2.2 Downcasting

Here a base class is being assigned to a derived one. Downcasting statements can be in one of two forms,

DerivedClass instanceOfDerivedClass = (DerivedClass) instanceOfBaseClass

instanceOfDerivedClass = (DerivedClass) instanceOfBaseClass

130

Downcasting must always be done explicitly, not including the cast before assigning the base class’ addresswill generate a ClassCastException.

Since a child will have extra more fields and methods than its parent downcasting can be problematic. Itsvery easy to get either compile or runtime errors when we use downcasting. Frequently subtle logic errorscome up when downcasting is used. When downcasting use instanceof and getClass to verify that thesuper and sub classes are of the same type.

The Java Virtual Machine’s interpreter checks types at runtime via a process called Run Time Type Iden-tification (RTTI) Despite its problems we will generally see downcasts being tied to upcasts because whenwe assign a child’s class to a parent’s object it is quite likely that we will need to use the child’s morespecific fields and procedures, hence upcasts and downcasts are tied together frequently. To illustrate down-casting we introduce two new programs, BaseBatlCapSie.java and ShowsDowncast.java. First we look atBaseBallCapSize.

12 package clothing;

34 /**

5 * BaseballCapSize has information & methods for fitted baseball caps.

6 * @param team is the name of the team that licensed the cap.

7 */

8 public class BaseBallCapSize extends GarmentSize {

9 private String team;

1011 public BaseBallCapSize () {

12 this(null , null , null , null);

13 }

1415 public BaseBallCapSize(String size , String team) {

16 this(null , null , size , team);

17 }

1819202122 /**

23 * @param aGender

24 * @param ageGroup

25 * @param size

26 */

27 public BaseBallCapSize(Gender aGender , String ageGroup , String size ,

131

String aTeam) {

28 super(Gender.NEUTER , null , null);

29 team = aTeam;

30 setSize(size);

31 }

3233 public void setSize(String size) {

34 if (size.equalsIgnoreCase("s"))

35 super.setSize("small");

3637 if (size.equalsIgnoreCase("m"))

38 super.setSize("medium");

3940 if (size.equalsIgnoreCase("l"))

41 super.setSize("large");

4243 if (size.equalsIgnoreCase("xl"))

44 super.setSize("extra large");

4546 else

47 super.setSize("Unk");

48 }

4950 /**

51 * @return the team

52 */

53 public String getTeam () {

54 String answer = team;

55 return answer;

56 }

5758 /**

59 * @param team the team to set

60 */

61 public void setTeam(String aTeam) {

62 team = aTeam;

63 }

6465 /* (non -Javadoc)

66 * @see java.lang.Object#toString ()

67 */

132

68 @Override

69 public String toString () {

70 return "BaseBallCapSize [team=" + team + ", toString ()="

71 + super.toString () + "]";

72 }

7374 }

Program 10.6: BaseBallCapSize.java

Then the actual downcasting is done in ShowsDowncasting.

1 package clothing;

23 import java.awt.GridLayout;

45 import javax.swing.JPanel;

6 import javax.swing.JFrame;

7 import javax.swing.JLabel;

8 import javax.swing.JTextField;

910 public class ShowsDowncasting {

1112 public static void main(String [] args) {

13 JFrame framer = new JFrame("Downcaster Exampler");

14 framer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

15 framer.setLayout(new GridLayout (1, 3));

16 framer.setSize (600, 600);

17 framer.setVisible(true);

1819 JPanel leftPanel = new JPanel(new GridLayout (5, 1));

20 framer.add(leftPanel);

2122 JPanel centerPanel = new JPanel(new GridLayout (5, 1));

23 framer.add(centerPanel);

2425 JPanel rightPanel = new JPanel(new GridLayout (5, 1));

26 framer.add(rightPanel);

2728 BaseBallCapSize yourCap = new BaseBallCapSize("xl", "Black Sox");

29 BaseBallCapSize myCap = new BaseBallCapSize("m", "Chicago Cubs");

3031 GarmentSize clothing = new GarmentSize(Gender.FEMALE , "baby", "m")

133

;

3233 addsPanelItems(leftPanel , clothing);

34 addsPanelItems(rightPanel , yourCap);

35 addsPanelItems(centerPanel , myCap);

3637 // clothing = yourCap;

38 // yourCap = (BaseBallCapSize) clothing;

3940 addsPanelItems(leftPanel , clothing);

41 addsPanelItems(rightPanel , yourCap);

42 addsPanelItems(centerPanel , myCap);

43 }

4445 public static String getLabelTitle(GarmentSize clothing) {

46 String title = null;

4748 String prefix = "clothing ..";

49 String suffix = "Size";

5051 String objectName = clothing.getClass ().getName ();

5253 title = objectName.substring (( prefix.length () - 1), (objectName.

length () - suffix.length ()));

54 return title;

55 }

5657 public static void addsPanelItems(JPanel panel , GarmentSize cap) {

58 JLabel clothingType = new JLabel("Garment Type");

59 JLabel size = new JLabel("Size");

60 JLabel gender = new JLabel("Gender");

61 JLabel ageGroup = new JLabel("Age Group");

62 JLabel team = new JLabel("Team");

6364 JTextField showClothingType = new JTextField (20);

65 showClothingType.setText(getLabelTitle(cap));

6667 JTextField showSize = new JTextField (10);

68 showSize.setText(cap.getSize ());

6970 JTextField showGender = new JTextField (10);

134

71 showGender.setText(cap.getaGender ().name());

7273 JTextField showAgeGroup = new JTextField (10);

74 showAgeGroup.setText(cap.getAgeGroup ());

7576 JTextField showTeam = new JTextField (10);

77 if (cap instanceof BaseBallCapSize)

78 showTeam.setText(BaseBallCapSize.getTeam ());

7980 JPanel row1 = new JPanel(new GridLayout (1,2));

81 row1.add(clothingType);

82 row1.add(showClothingType);

8384 JPanel row2 = new JPanel(new GridLayout (1,2));

85 row2.add(gender);

86 row2.add(showGender);

8788 JPanel row3 = new JPanel(new GridLayout (1,2));

89 row3.add(ageGroup);

90 row3.add(showAgeGroup);

9192 JPanel row4 = new JPanel(new GridLayout (1,2));

93 row4.add(size);

94 row4.add(showSize);

9596 JPanel row5 = new JPanel(new GridLayout (1,2));

97 row5.add(team);

98 row5.add(showTeam);

99100 panel.add(row1);

101 panel.add(row2);

102 panel.add(row3);

103 panel.add(row4);

104 panel.add(row5);

105 }

106107 }

Program 10.7: ShowsDowncasting.java

You will see that for us to downcast first we had to do an upcast. The following picture shows us whathappens during the two sets of calls to addsPanelItems. Lastly notice that team is static as well

135

136

137

9.2.3 Upcasting/Downcasting Guidelines

This is one of the easiest ways to implement polymorphism in your Java applications. However if you arenot careful it will introduce subtle errors and can cause major problems for both the developer and user. Touse upcasts and downcasts effectively keep the following considerations in mind.

1. Create an object of the base class.

2. For each instance of the base class we need a derived class to do an upcast.

3. Upcasts lead to references to the derived class’ unique fields being lost.

4. When we need to deal with something in that only the derived class can do we will need to do adowncast from the more general class to the specific one.

5. Downcasts should only be done for classes that correspond to the child. To make sure that the classyou are trying to cast was originally the same as the child use the instanceof operator.

6. When doing a downcast make sure that any unique fields and methods are still handled correctly.

9.3 Abstract Classes

The second way of achieving polymorphism is by using abstract classes For a class to be abstract at leastone of its methods will not have a body. The syntax of an abstract class declaration is

accessModifier absract ClassName {

. . . access-modifier return-type methodName(parameters);

. . . }

You will notice that both the method and the class must have the keyword abstract in their headers. Alsothe method header is followed by a semicolon.

9.3.1 Guidelines For Making A Method Abstract

We do not need to make all the functions in a class abstract, we only need to create an abstract functionwhen

• All the subclasses need to have the functionality that the abstract function is supposed to provide.

• Each subclass’ implementation of the abstract method will unique.

138

9.3.2 Properties Of Abstract Methods

Whenever an abstract function is created it must be implemented in a descendant class. Since abstractfunctions cannot be defined in the base class but they have to be overridden in the children they cannot bemarked as private. We can use protected, package, or public.

9.3.3 Properties Of Abstract Classes

A class with no abstract methods is called a concrete class. If an abstract class is marked private thennone of its concrete children will be able to redefine their implementations of its abstract functions. Anotherproperty of abstract classes is that they cannot be used to create other classes. However an abstract class.concrete descendants can instantiate objects. Though we cannot have instances of an abstract class we candeclare it as a variable which the concrete class will be plugged into. Our first example of an abstract classis DrawShape, then we shall try implementing GarmentSize using abstraction.

12 package clothes.sizes;

3 /**

4 * GarmentSize is an abstract class used set and display information about

garments.

5 * Its concrete subclasses must have concrete implementations of setSize ()

.

6 * @param Gender is an enum whose values are MALE , FEMALE , NEUTER.

7 * @param AgeGroup an enum whose values are BABY , TODDLER , PRETEEN , TEEN ,

8 * ADULT , & NONE

9 */

10 // Decided to use an enum for the age groups since they are fixed.

11 enum Gender {MALE , FEMALE , NEUTER };

12 enum AgeGroup {BABY , TODDLER , PRETEEN , TEEN , ADULT , NONE}

1314 public abstract class GarmentSize {

15 private Gender aGender;

16 private AgeGroup anAgeGroup;

1718 // Had to make size protected so that the concrete classes could set

its value.

19 protected String size;

20 private String clothingType;

2122 private int age; //This is only used to find the age group.

2324 /**

25 * Default constructor which creates a null GarmentSize object.

139

26 */

27 public GarmentSize () {

28 this(null , null , null , 0);

29 }

3031 /**

32 * Creates a GarmentSize object and sets the value of AgeGroup based

value of age

33 * parameter.

34 * @param aGender - An enum which represents gender.

35 * @param age - This is only ever used to find the correct age group.

36 * @param size - A String

37 */

38 public GarmentSize(Gender aGender , int age , String size) {

39 this(aGender , null , size , age);

40 setAgeGroup(age);

41 }

4243 /**

44 * Creates a GarmentSize object , with parameters below.

45 * @param aGender

46 * @param anAgeGroup

47 * @param size

48 */

49 public GarmentSize(Gender aGender , AgeGroup anAgeGroup , String size)

{

50 this(aGender , anAgeGroup , size , 0);

51 }

5253 /**

54 * @param aGender

55 * @param size

56 * @param AgeGroup

57 * @param clothingType

58 */

59 public GarmentSize(Gender aGender , AgeGroup anAgeGroup , String size ,

int age) {

60 this.aGender = aGender;

61 this.anAgeGroup = anAgeGroup;

62 this.age = age;

63 this.size = size;

140

6465 // Need to set the clothingType once the object is created.

66 setClothingType ();

67 }

6869 /**

70 * @return the aGender

71 */

72 public Gender getGender () {

73 Gender answer = this.aGender;

74 return answer;

75 }

7677 /**

78 * @param aGender the aGender to set

79 */

80 public void setaGender(Gender aGender) {

81 this.aGender = aGender;

82 }

8384 /**

85 * @return the AgeGroup

86 */

87 public AgeGroup getAgeGroup () {

88 AgeGroup answer = this.anAgeGroup;

89 return answer;

90 }

9192 /** Sets value of enum AgeGroup.

93 * @param AgeGroup to set possible values to.

94 */

95 public void setAgeGroup(AgeGroup anAgeGroup) {

96 this.anAgeGroup = anAgeGroup;

97 }

9899 /**

100 * Sets the age group based on the age range that age falls under.

101 * @param nonnegative int representing the age.

102 */

103 public void setAgeGroup(int age) {

104 if (age < 0 )

141

105 this.anAgeGroup = AgeGroup.NONE;

106 else if ((age >= 0) && (age <= 1))

107 this.anAgeGroup = AgeGroup.BABY;

108 else if ((age >= 2) && (age <= 5))

109 this.anAgeGroup = AgeGroup.TODDLER;

110 else if ((age >=6) && (age <= 12 ))

111 this.anAgeGroup = AgeGroup.PRETEEN;

112 else if ((age >= 13) && (age <= 19))

113 this.anAgeGroup = AgeGroup.TEEN;

114 else

115 this.anAgeGroup = AgeGroup.ADULT;

116 }

117118 /** Returns the string which corresponds to the type of garment.

119 * @return the clothingType

120 */

121 public String getClothingType () {

122 String answer = this.clothingType;

123 return answer;

124 }

125126 /**

127 * Sets the clothingTypeField by calling a private method.

128 */

129 public void setClothingType () {

130 this.clothingType = extractsType ();

131 }

132133 /**

134 * Abstract method that to set size of different types of clothes.

135 * @param size of the garment.

136 */

137 public abstract void setSize(String size);

138139 public String getSize () {

140 String answer = this.size;

141 return answer;

142 }

143144 /**

145 * You should not really need to call this since garments are

142

categorized by age

146 * groups. Its only here for possible error checking.

147 * @return the age

148 */

149 public int getAge () {

150 int answer = age;

151 return answer;

152 }

153154 /**

155 * If the age group was set previously and age is outside of the age

group range

156 * set the age to the age group ’s midpoint. Otherwise sets to age to

parameter.

157 * @param age a nonnegative int.

158 */

159 public void setAge(int age) {

160 this.age = age;

161 }

162163 /**

164 * Parses the string returned by getclass () & getname () fields to get

the class name.

165 * Strips the package information & suffix "Size" from the class name.

166 * @return

167 */

168 private String extractsType () {

169 String type = null;

170 String suffix = "Size";

171 String prefix = "clothes.sizes.";

172173 String object = this.getClass ().getName ();

174175 int startOfTypeString = prefix.length ();

176 int endOfTypeString = object.length () - suffix.length ();

177178 type = object.substring(startOfTypeString , endOfTypeString);

179 return type;

180 }

181182 /**

143

183 * Overrides

184 */

185 public String toString () {

186 String aString = clothingType + ": size = " + size + ", gender = "

+ aGender;

187 aString += " , age group = " + anAgeGroup;

188189 return aString;

190 }

191192 }

Program 10.8: GarmentSize.java

One of the things that you will notice is that even though the previous program is named GarmentSize itsin package clothes.sizes unlike our first encounter with GarmentSize which was in package clothing. Youprobably noticed that I also redefined ageGroup to be an enum since. Lastly, the only function that reallyneeds to be different for the various types of clothes we might need to get size information for is their sizes.So only setSize is abstract. Furthermore, I rewrotethe toString method to make it more general. Now thatthe major changes in GarmentSize have been examined we can look at how TrouserSize is reimplementedto make use of abstractions.

1 package clothes.sizes;

23 /**

4 * Gets and displays information about trouser sizes. Subclass of

GarmentSize.

5 * @param waist tailor ’s waist in inches , an int.

6 * @param inSeam tailor ’s inseam in inches , an int.

7 */

8 public class TrouserSize extends GarmentSize {

9 private int waist;

10 private int inSeam;

1112 /**

13 * Creates an empty trouser object.

14 */

15 public TrouserSize () {

16 this(null , null , null , 0, 0);

17 }

1819 /**

144

20 * Creates TrouserSize object from the following fields. The size of

the trousers

21 * are set by this constructor. We chain this to another constructor.

22 * @param aGender field inherited from super class ..

23 * @param anAgeGroup field inherited from super class.

24 * @param waist

25 * @param inSeam

26 */

27 public TrouserSize(Gender aGender , AgeGroup anAgeGroup , int waist , int

inSeam) {

28 this(aGender , anAgeGroup , null , waist , inSeam);

29 this.setSize(intsToSizeString ());

30 }

3132 /**

33 * Creates a TrouserSize object and uses the size argument to set the

values of

34 * waist & inSeam. Again this is chained to another constructor ..

35 * @param aGender field inherited from superclass

36 * @param anAgeGroup field inherited from superclass

37 * @param size should be of the form "waistxinseam ". as in 32x30

otherwise.

38 */

39 public TrouserSize(Gender aGender , AgeGroup anAgeGroup , String size) {

40 this(aGender , anAgeGroup , size , 0, 0);

41 this.waist = getWaistFromSize(size);

42 this.inSeam = getInSeamFromSize(size);

43 }

4445 /**All other constructors in TrouserSize are chained to this. The

only call to the

46 * the superclass constructor happens here.

47 */

48 public TrouserSize(Gender aGender , AgeGroup anAgeGroup , String size ,

int waist , int inSeam) {

49 super(aGender , anAgeGroup , size );

50 this.waist = waist;

51 this.inSeam = inSeam;

52 this.size = size;

53 }

54

145

55 /**

56 * Used to get the waist.

57 * @return waist.

58 */

59 public int getWaist () {

60 return waist;

61 }

6263 /**

64 * Set the waist.

65 * @param waist

66 */

67 public void setWaist(int waist) {

68 this.waist = waist;

69 }

7071 /**

72 * @return inSeam

73 */

74 public int getInSeam () {

75 return inSeam;

76 }

7778 /**

79 * Sets the in seam.

80 * @param inSeam

81 */

82 public void setInSeam(int inSeam) {

83 this.inSeam = inSeam;

84 }

8586 /**

87 * Implementation of abstract method setSize. If this method is

invoked by a

88 * non TrouserSize object then it displays a message and exits.

89 * @param size a string in the form "aaxbb" where aa are the waist and

bb are

90 * the inseam. If size is in the wrong format the its set to "Unknown

".

91 */

92 public void setSize(String size) {

146

93 if ( (this instanceof TrouserSize) && ( checkSize(size) == false))

94 this.size = "Unknown";

9596 else if ( (this instanceof TrouserSize) && ( checkSize(size) ==

true))

97 this.size = size;

9899 else {

100 System.out.println(this.getClass ().getName () + "is not a pair

of trousers.");

101 System.exit (25);

102 }

103 }

104105 /**

106 * We only enclose the string describing a TrouserSize object between

square

107 * braces

108 */

109 public String toString () {

110 return "[ " + super.toString () + " ]";

111 }

112113 /**

114 * If the string is not in the correct form to be the size of a pair

of pants returns

115 * @param aString hopefully of the form aaxbb where aa - waist , bb -

inseam.

116 * @return true if aString is in the format of a aaxbb where aa and bb

are digits

117 * separated by an x. Otherwise returns false.

118 */

119 private boolean checkSize(String aString) {

120 String middleLetter = "x";

121122 return (middleLetter.regionMatches (0, aString , 2, 1));

123 }

124125 /** After it verifies that the string is in the correct format for a

trouser sizes

126 * will strip the waist measurement from the string.

147

127 * @param size

128 * @return waist

129 */

130 public int getWaistFromSize(String size) {

131 int waist = 0;

132133 if (checkSize(size))

134 waist = Integer.parseInt(size.substring (0, 1));

135136 return waist;

137 }

138139 /** After it verifies that the string is in the correct format for a

trouser sizes

140 * will strip the in seam measurement from the string.

141 * @param size

142 * @return inSeam

143 */

144 public int getInSeamFromSize(String size) {

145 int inSeam = 0;

146147 if (checkSize(size))

148 inSeam = Integer.parseInt(size.substring(3, 4));

149150 return inSeam;

151 }

152153 /**

154 * Converts the measurements for waist and inseam into a string

representing the

155 * size.

156 * @return size

157 */

158 public String intsToSizeString () {

159 String size = this.getWaist () + "x" + this.getInSeam ();

160 return size;

161 }

162163 }

Program 10.9: TrouserSize.java

148

You might have noticed that the we implemented the abstract method setSize. On the other hand withour new implementation of BaseBallCapSize we see that the code is much simpler. However there are noreally big changes in either subclass’ implementation of their functionality.

1 package clothes.sizes;

2 /**

3 * BaseballCapSize has information & methods for fitted baseball caps.

4 * @param team is the name of the team that licensed the cap.

5 */

6 public class BaseBallCapSize extends GarmentSize {

7 private String team;

89 public BaseBallCapSize () {

10 this(null , null , null);

11 }

1213 /**

14 * Create a BaseBallCapSize object

15 * @param size the size of the baseball cap. An enum

16 * @param team the name of the team.

17 */

18 public BaseBallCapSize(String size , String team) {

19 this(null , size , team);

20 }

2122 /**

23 * All the other constructors in this class are chained to this one.

24 */

25 public BaseBallCapSize(AgeGroup anAgeGroup , String size , String aTeam)

{

26 super(Gender.NEUTER , anAgeGroup , size);

27 team = aTeam;

28 }

2930 /**

31 * Sets the size of baseball caps.

32 * @param size of cap. Possible sizes are "s" for small , "m" for

33 * medium , "l" for large , "xl" for extra large , & "Unk" for unknown

sizes. A value of

34 * "Unk" for baseball cap size indicates there might be an error.

35 */

36 public void setSize(String size) {

149

37 if (size.equalsIgnoreCase("s"))

38 this.size = "small";

3940 if (size.equalsIgnoreCase("m"))

41 this.size = "medium";

4243 if (size.equalsIgnoreCase("l"))

44 this.size = "large";

4546 if (size.equalsIgnoreCase("xl"))

47 this.size = "extra large";

4849 else

50 this.size = "Unknown";

51 }

525354 public String getSize () {

55 return this.size;

56 }

5758 /**

59 * @return the team

60 */

61 public String getTeam () {

62 return this.team;

63 }

6465 /**

66 * @param team the team to set

67 */

68 public void setTeam(String aTeam) {

69 this.team = aTeam;

70 }

7172 /* (non -Javadoc)

73 * @see java.lang.Object#toString ()

74 */

75 @Override

76 public String toString () {

150

77 String aString = "[ " + super.toString () + ", team = " + getTeam ()

+ " ]";

7879 return aString;

80 }

8182 }

Program 10.11: BaseBallCapSize.java

But when we look at UsingAbstractClass we see that when we want to use the superclass methods andits much cleaner and simpler. Since there is no upcasting or downcasting we do not have to check if themethod being invoked is the correct one for the object.

1 package clothes.sizes;

23 public class UsingAbstractClass {

45 public static void main(String [] args) {

6 TrouserSize leatherPants = new TrouserSize(Gender.FEMALE , AgeGroup

.TODDLER , "32x30");

7 System.out.println(leatherPants.toString ());

89 // Testing iif TrouserSize ’s instance methods are working

correctly.

10 TrouserSize denimPants = new TrouserSize ();

11 denimPants.setAgeGroup(AgeGroup.TEEN);

12 denimPants.setaGender(Gender.NEUTER);

13 denimPants.setInSeam (29);

14 denimPants.setWaist (34);

1516 // If inSeam & waist are set outside a constructor we need to

invoke setSize ()..

17 denimPants.setSize(denimPants.intsToSizeString ());

18 System.out.println(denimPants.toString ());

1920 // Create two baseball caps and print their information.

21 BaseBallCapSize aCap = new BaseBallCapSize("m", "Black Sox");

22 aCap.setAgeGroup(AgeGroup.PRETEEN);

23 BaseBallCapSize cricketCap = new BaseBallCapSize(AgeGroup.ADULT , "

L", "Chcago Cubs");

2425 System.out.println("\n" + aCap.toString ());

151

26 System.out.print(cricketCap.toString ());

27 }

2829 }

Program 10.12: UsingAbstractClass.java

9.4 Interfaces

An interface is a type thathas all its methods marked as abstract. The syntax for creating an interface is;

public interface InterfaceName { public returnType methodName1(. . . ) public returnType methodName2(. . . ) }

You will notice that the methods do not need the keyword abstract in their headers.

Interface Names

The will should all end with the suffix “able”.

9.5 Inner Classes

See chapters 8 and 13 of Absolute Java

152

Chapter 10

Exceptions

In software development one of the biggest worries is dealing with boundary conditions and cases where thealgorithms and data are not meant to handle. In the early days systems would simply fail, this behaviourwas usually undesirable since

i We need information about why the failure occurred.

ii Applications that simply stop working at a critical time can cause a major catastrophe.

To deal with exceptions and failures gracefully developers do a number of things. Many of these featuresthat we will discuss here are in other languages. With exception handling an application is more reliable, itwill fail gracefully and will alert users and developers about possible errors.

10.1 Generalized Exception Handling Mechanism

Generally to handle exceptions in a manageable way we break down the flow of of execution as follows;

• One portion of the code deals with produce the exception.

• A different portion of the code handles the exception.

10.1.1 Termination Versus Resumption Models Of Exception Handling

Some languages will return the flow of execution to point just after the exception was generated, they only dothis wen the problem is dealt with in the error handling block though. Such languages follow a resumptionmodel since the flow of control returns to the next statement after the error is handled.

On the other hand other languages will have the flow of execution start after the error handling block.Since the old flow of control that would have existed before the error is terminated such languages follow antermination model. In Java flow of execution never goes back to the point before the exception happened soJava follows a termination model of exception handling.

153

10.2 Handling Exceptions With If-Else

So far we have used if-else constructs to deal with boundary conditions and errors. The problem with thisstyle is that there is no standard way of documenting how the errors are reported, detected and handled.So each coder will do exception handling in their own idiosyncratic way. For an example of the complexitythat can be involved with using if-else for handling exceptions look at AssuresEntryIsDouble1.java.

1 import java.text.NumberFormat;

2 import java.text.ParsePosition;

34 import javax.swing.JOptionPane;

5678 /**

9 * Displays a number entered into a dialog window as double in a message

window.

10 * All the boundary conditions are handled with if-else.

11 */

12 public class AssuresEntryIsDouble1 {

1314 /**

15 * Converts a double to a Double object and displays it in a message

window.

16 * @param number a double.

17 */

18 public static void displayOutput(double number) {

19 Double temp = new Double(number);

20 String message = "You entered " + temp.toString () + ".";

21 JOptionPane.showMessageDialog(null , message);

22 } // end displayOutput

2324 /**

25 * If nonnumeric input was given displays an error message and makes

the

26 * program exit.

27 */

28 public static void handlesNonNumericEntry () {

29 String message = "Nonnumeric entry passed to displayInputDialog.";

30 message += " Exiting with status 44";

3132 JOptionPane.showMessageDialog(null , message);

154

33 System.exit (44);

34 } //end handlesNonNumericEntry

3536 /**

37 * Displays pane asking for a number. For nonnumeric entries invokes

38 * handlesNonNumericEntry.

39 *

40 * @return a Double object.

41 */

42 public static Double displayInputDialog () {

43 Double aDoubleObj = null;

44 String entry = JOptionPane.showInputDialog("Enter a number.");

4546 // If the entry is not a number then call handlesNonNumericEntry.

47 // Otherwise return the entry as Double.

48 if ( false == isNumber(entry))

49 handlesNonNumericEntry ();

5051 aDoubleObj = Double.parseDouble(entry);

52 return aDoubleObj;

53 } //end displayInputDialog

5455 /**

56 * Converts a Double object to a double primitive.

57 * @return a double.

58 */

59 public static double convertsFromDoubleObj () {

60 double value = displayInputDialog ().doubleValue ();

6162 return value;

63 } //end convertsFromDouble

6465 /**

66 * Tests if a string is numeric.

67 * @return a boolean.

68 */

69 public static boolean isNumber(String aString) {

70 // We use the NumberFormat object since it works for decimals as

well as

71 // integers.

72 NumberFormat formatter = NumberFormat.getInstance ();

155

7374 // Set the position we will start to the parse aString from.

75 ParsePosition position = new ParsePosition (0);

7677 //Here we actually parse aString. If any of the entries do not

correspond

78 // to a number then position.getIndex () will be different from

aString ’s

79 // length.

80 formatter.parse(aString , position);

81 return aString.length () == position.getIndex ();

82 } //end isNumber

8384 /**

85 * Calls other functions.

86 */

87 public static void main(String [] args) {

88 double value = 0;

8990 value = convertsFromDoubleObj ();

91 displayOutput(value);

92 } //end main

9394 } // end AssuresEntryIsDouble1

Program 11.1: AssuresEntryIsDouble1.java

10.3 Handling Exceptions With Try-Catch

Though what we did works its fairly cumbersome fortunately we can use Java’s try-catch blocks to do thesame thing much more simply and with less code.

10.3.1 Try Block

In the try block we place the instructions that we hope will run without generating an error or failure dueto boundary conditions. From looking at our exception handling mechanism we see that the try block iswhere the code that generates the exception is placed. The syntax of a try block is;

try { statements to execute that might generate an error; }

156

10.3.2 Catch Block

If the code in the try block generated an error or boundary condition then the error is thrown to the catchblock by the Java interpreter to be handled. Catch blocks implement the second part of the exceptionhandling mechanism. The syntax of a catch block is shown below.

catch (ExceptionClass parameterName) { Statements to handle instance of ExceptionClass }

You will notice that catch takes an object of type Exception as its parameter. To see all the types ofExceptions that are standard in Java consult the APIs. Since there are many possible exceptions that canbe generated by a try block we will have a catch block for each one. Some exceptions are more specificthan others being that some are children of more generic exceptions.

The most specific catches should be placed first because the interpreter will pick the first catch block itfinds. So if the first conditions are too broad then the more specific ones will always be skipped. Assure-

sentryIsDouble1’s functionality is implemented in AssuresEntryIsDouble2.java with try & catch blocks.AssuresEntryIsDouble2’s code could have been made even simpler by getting rid of convertsFromDou-

bleObj but that would obscure the effect of exception handling with try and catch blocks.

1 import javax.swing.JOptionPane;

23 /**

4 * Displays a number entered into a dialog window as double in a message

window.

5 * We use try -catch blocks for dealing with the boundary conditions.

6 */

7 public class AssuresEntryIsDouble2 {

89 /**

10 * Converts a double to a Double object and displays it in a message

window.

11 * @param number a double.

12 */

13 public static void displayOutput(double number) {

14 Double temp = new Double(number);

15 String message = "You entered " + temp.toString () + ".";

16 JOptionPane.showMessageDialog(null , message);

17 } // end displayOutput

1819 /**

20 * Displays pane asking for a number. For nonnumeric entries invokes

21 * @return a Double object.

22 */

157

23 public static Double displayInputDialog () {

24 Double aDoubleObj = null;

25 String entry = JOptionPane.showInputDialog("Enter a number.");

2627 // Here we try to convert entry from a string to a double Object.

28 try {

29 aDoubleObj = Double.parseDouble(entry);

30 }

3132 // Replaced handlesNonNumericEntry with this catch block.

33 catch (NumberFormatException e) {

34 String message = "Nonnumeric entry passed to

displayInputDialog.";

35 message += " Exiting status = 44.";

36 JOptionPane.showMessageDialog(null , message);

37 System.exit (44);

38 } //end displayInputDialog

3940 // If the try is successful then the flow of execution drops to

the

41 // return statement.

42 return aDoubleObj;

43 }

4445 /**

46 * Converts a Double object to a double primitive.

47 * @return a double.

48 */

49 public static double convertsFromDoubleObj () {

50 double value = displayInputDialog ().doubleValue ();

5152 return value;

53 } //end convertsFromDouble

5455 /**

56 * Calls other functions.

57 */

58 public static void main(String [] args) {

59 double value = 0;

6061 value = convertsFromDoubleObj ();

158

62 displayOutput(value);

63 } //end main

6465 } // end AssuresEntryIsDouble2

Program 11.2: AssuresEntryIsDouble2.java

10.4 Handling Exceptions With Try-Catch-Finally

We have already seen how try-catch blocks can be used to handle exceptions and we noticed the improvementsit made to our code. Now we see how the finally operator can assist us with exception handling.

10.4.1 Finally Block

A finally block is executed weather an exception is thrown or not. The finally block is a good place torelease resources that were used or called in the try block. The finally blocks’s syntax is;

finally { statements to execute outside the try-catch blocks }

It is essential that no exceptions are thrown in the finally block. AssuresEntryIsDouble3 implementsthe same functionality as the previous two programs but is much shorter and easier to follow.

1 import javax.swing.JOptionPane;

23 /**

4 * Displays a number entered into a dialog window as double in a message

window.

5 * We use try -catch -finally blocks for dealing with the boundary

conditions.

6 */

7 public class AssuresEntryIsDouble3 {

89 /**

10 * Displays a message in the panel depending on if there is an error

or if the

11 * entry can be converted to a double.

12 */

13 public static void entryProcessor () {

14 int exitValue = 0;

15 Double aDoubleObj = null;

1617 String message = null;

18 String entry = JOptionPane.showInputDialog("Enter a number.");

159

1920 // Here we try to convert entry from a string to a double Object.

21 try {

22 aDoubleObj = Double.parseDouble(entry);

23 message = "You entered " + aDoubleObj.toString () + ".";

24 message += " Exiting with status 0.";

25 }

2627 // NumberFormatException is a child of Exception so it goes first.

28 catch (NumberFormatException e) {

29 message = "Nonnumeric entry passed to displayInputDialog.";

30 message += " Exiting status = 44.";

31 exitValue = 44;

32 }

3334 // The super class Exception is handled after the subclass.

35 catch(Exception e) {

36 message = "General input error in displayInputDialog.";

37 message += " Exiting with status 12";

38 exitValue = 12;

39 }

4041 // The statements that will always be executed go here.

42 finally {

43 JOptionPane.showMessageDialog(null , message);

44 System.exit(exitValue);

45 }

46 } // End entryProcessor

4748 /**

49 * Invokes entryProcessor.

50 */

51 public static void main(String [] args) {

52 entryProcessor ();

53 } //end main

54 } // end AssuresEntryIsDouble3

Program 11.3: AssuresEntryIsDouble3.java

You will notice that the output dialog is not displayed until the finally block is reached. Also using finally

allows us to keep the program running and exit in a much more clean and general fashion than in either ofthe two previous programs.

160

10.4.2 The Difference Between A Try Block & A Try Statement

You will sometimes read or hear people referring to a try statement instead of a try block. A try statementincludes not only the try block but any catch blocks associated with the try block as well as its possiblefinally block. The difference between a try block and statement is shown in the Venn diagram.

10.5 Overview Of The Throwable Class

Errors in a program can be classified as either synchronous or asynchronous. Asynchronous errors are dueto things that are outside the program’s direct control. Asynchronous errors are due to other programs,network problems or resources such as discs, files, memory that are not directly under the control of theprogram that uses them.

Synchronous errors on the other hand occur when a fault occurs with resources, memory, files, functions thatare under the direct control of the application that experiences the failure. You could say that synchronouserrors are caused by things directly under the program’s control. Since all errors are caused by boundaryconditions of some sort we can consider all errors as things that throw an error condition. With this be-haviour in common both synchronous and asynchronous errors are handled by the Throwable class.

Throwable exists under java.lang.Object package so we see that its parent class is Object. The syn-chronous and asynchronous errors have the following subclasses under Throwable

• Error → deals with asynchronous errors.

161

• Exception → deals with synchronous errors.i

The next figure shows the hierarchy of these four classes.

Everything other than the Exception class in the above hierarchy is outside the scope of this chapter.

10.6 The Exception Class

Exception has a lot of subclasses, one its most important subclasses is RuntimeException which we shalldiscuss in a bit more detail later. One way that all exceptions in Java are categorized is based on how theinterpreter deals with them. Exceptions are either checked or unchecked.

• Checked Exceptions → If these are not handled by a try statement the program will not compile.All exceptions outside of RuntimeException fall under this category.

• Unchecked Exceptions → Since the complier does not check to see if they are handled a programcan compile without handling this class of exceptions.

10.6.1 Exception’s Constructors

Exception has four constructors. The default takes no arguments, One takes string as its parameter,a second an object of type Throwable, and the last one takes both a string and a Throwable as itsarguments. All of Exception’s constructors will be used in the future examples.

10.6.2 Exception’s Mutators

Most of Exception’s setters that we are interested in are inherited from Throwable. The setters aresetStacktrace, initStackTrace, & initCause. The first two setters deal with configuring the values ofthe stack while the last is used to initialize the a Throwable to some value. Again we shall see these usedin future examples.

162

10.6.3 Exception’s Accessors

The getters return either the stack or a message describing the exception. However, unlike getMessage,getLocalizedMessage, getStackTrace, & printStackTrace getCause will return the Throwable thatcaused the exception to occur.

10.6.4 Exception’s Commonly Used Subclasses

It was mentioned before that Exception’s subclasses are either checked or unchecked. In this section we aresimply presenting the most commonly used subclasses in each category. For more details on their propetiesconsult the Java APIs.

ArithmeticException ArrayStoreExceptionNegativeArraySizeException IllegalArgumentExceptionIllegalStateException IllegalPathStateExceptionClassCastException EnumConstantNotPresentExceptionEmptyStackException IndexOutOfBoundsExceptionUnknownTypeException UnknownElementExceptionNullPointerException NoSuchElementExceptionBufferOverflowException SystemExceptionUnsupportedOperationException SecurityException

Table 10.1: Unchecked Exceptions Found in RuntimeException

ClassNotFoundCloneNotSupportedException

IllegalAccessExceptionInstantiationExceptionInterruptedExceptionNoSuchFieldException

NoSuchMethodException

Table 10.2: Checked Exceptions

10.7 throw

So far we have seen cases where the interpreter throws an exception without any intervention from thedeveloper. Such exception throwing is implicit. However there are times when we want to explicitly throwan exception, and for that we use the throw operator. The syntax for throw is. . .

throw ExcepectionClassConstructor()

163

By using throw we can toss exceptions anywhere in our code and we can also have a try block toss multipleexceptions to differing catch blocks explicitly. In AssignSoccerPlayer you can see throw being used twice.Lastly if the condition that causes throw statement to be exceuted then the program’s flow of executionpasses to the catch invoked by the throw statement.

12 public class AssignSoccerPlayer {

34 public static void main(String [] args) {

5 TeamPlayer aPlayer = new TeamPlayer ();

6 try {

7 PlayerSetter aSetter = new PlayerSetter(aPlayer);

8 currentInjuries = aPlayer.getNumOfInjuries ();

910 if (currentInjuries >= 5 )

11 throw new ExcessiveInjuryException ();

1213 if (aPlayer.getJerseyNumber () <= 0 )

14 throw new InvalidJerseyNumberException("improper number");

1516 else

17 a.Player.assignToField ();

18 }

1920 catch (ExcessiveInjuryException e) {

21 aPlayer.handlesExcessiveInjuryException ();

22 }

2324 catch (InvalidJerseyNumberException e) {

25 aPlayer.handlesInvalidJerseyNumberException ();

26 }

27 }

2829 }

Program 11.4: AssignSoccerPlayer.java

10.7.1 Scope Of Thrown Exceptions

Whenever an exception is thrown there is a hierarchy of places where it can be handled.

i The first catch block associated with the try block handles the thrown exception.

164

ii If the first catch block does not handle the class of exception thrown then its passed to the next catch

in the try statement.

iii If none of the try statement’s blocks can catch the exception then its passed on to any nested try

statements.

iv If there are no nested catch block that can handle the exception then its passed to any catch blocks inother try statements.

v In the event that no try statements are associated with the exception then the Java interpreter will dealwith the exception.

A throw operator is used to exit a try block immediately and pass the flow of execution to a catch block.Consider the case where you need to

sorts out how to deal with the exception. The two ways of dealing with exceptions are either to use try

blocks or assertions.

10.8 Using Throws In Methods

To make error handling in functions easier we can use the throws keyword. Its syntax is. . .

methodModifers returnType methodName( parameters) throws ExceptionClass {

methodBody; }

By using throws in our methods we are able to cut down on writing error handling code yet still get usefulinformation about possible causes or errors. Whenever a function throws an exception the thrown exceptionmust be handled by the invoker.

10.9 Exception Output

Frequently users for not need to see error messages. Also error messages should not interrupt the flow ofoutput. Generally we want to know the what exception was thrown, what files and other resources theapplication was using when the error was thrown along with what was in the stack. You can see that theprogrammer might want to get a lot of information. Since the information required to discover why anexception was thrown can be quite large this is frequently written to a log file. If we used System.out

everything will be written or directed to standard output, which is the console. On the other hand usingSystem.err will send all error messages to standard error where it really should be directed to.

Instead of using println or printf from System.out we will use System.err We can put all of our code ina try block so that it throws an exception to the interpreter i.e.

165

1 public class UsingExceptions {

23 public static void throwsException () throws ArithmeticException {

4 try {

5 int x = 5/0;

6 } catch (SecurityException e) {

7 e.printStackTrace ();

8 } finally {

9 System.err.println("Leaving throwsException:");

10 }

11 }

12 public static void main(String [] args) {

13 try {

14 throwsException ();

15 } catch (ArithmeticException e) {

16 System.err.println(e + " caught in main.");

17 }

1819 }

2021 }

Program 11.3: UsingExceptions.java

10.9.1 Excepetion’s Message Utilities

The most commonly used functions for displaying or getting error messages in Java are shown below. Thoughthere are a great deal more than the four shown here these are the most commonly used ones. All of themexcept for System.err.println are methods in Throwable. Being that Throwable is a child of Object

its in Java.lang so we do not use use an import statement to use the last three functions.

System.err.println

Displays a string in standard error.

printStackTrace

Displays the stack trace and the exception that was thrown. printStackTrace nicely formats the output.

getStackTrace

Returns an array that contains the stack elements. We can use this to send the stack to some other locationother than standard error, a log file perhaps.

166

getMessage

Returns a string associated with the exception’s message.

To see what other methods are in available in Throwable for showing and getting exceptions and errorslook at either http://download.oracle.com/javase/7/docs/api/ or your local Java’s documentation.

10.10 Rethrowing Errors

Sometimes a method might not know how to handle an exception. For example look at the makeFile below.

1 public void makeFile(String path , String fileName) {

2 try {

3 } catch (NoWritePermission e) {

4 System.err.println(‘‘Method makeFile cannot handle ’’ + e + ‘‘

exception.’’);

5 throw e;

6 }

7 }

Since makeFile does not know what to do it throws the exception back to its invoker for it to be handled.Exceptions are rethrown if;

• The method cannot process the exception.

• The function can only partially process the exception.

An exception must be thrown before the finally block.

10.11 Stack Unwinding

If an uncaught exception is thrown by a function then all of the function;s data and instructions are removedfrom the stack and then the exception is passed to the invoker. If the invoker also refuses to handle toexception then its also removed from the stack. If this cycle continues to the main method the applicationwill exit with an error number.

10.12 Chained Exceptions

You saw earlier that some methods can throw an exception to their inovker and have the caller handle it.This can cause problems if the invovker does it own exception handling in a try block. If the invoker doesnot report that some other method throws an exception this can make it hard to debug so Java uses chainedexceptions. To chain the exception we simply put a throw statement in the invokers catch block as shownin the Chainer.java.

167

1 public class Chainer {

23 public static void main(String [] args) {

4 try {

5 thrower ();

6 } catch (UnsupportedOperationException e) {

7 e.printStackTrace ();

8 }

910 }

1112 public static void thrower () throws UnsupportedOperationException {

13 try {

14 madMethod ();

15 } catch (NegativeArraySizeException e) {

16 System.out.println("Original cause: " + e.getCause ());

17 }

18 }

1920 public static void madMethod () {

21 UnsupportedOperationException e = new

UnsupportedOperationException("not allowed");

2223 e.initCause(new NegativeArraySizeException("size is -13"));

24 throw e;

2526 }

2728 }

Program 11.4: Chainer.java

So with the throw in thrower we will be able to get the reason why madMethod threw an exception.

10.13 Rolling Your Own Exceptions

If your classes do specific thingd its a good idea to make exceptions for them. If you decide to roll your ownexceptions you can only have two constructors in the class.

• The default no-argument constructor will pass default messages to the super constructor.

• The second constructor takes a message as its argument, and this message is passed to the superconstructor.

168

10.14 Assertions

When a function is executed there might be things about its stack that should be true. If the its state isnot what we expect then this is an indication of possible errors. This fact is used in debugging programs byusing the assert keyword. The syntax i which we use assert is. . .

{ method-body assert(condition that should evaluate to true) }

To enable assertions at the command line do java -ea ProgramName

Once debugging is done assertions should be disabled.

169

170

Chapter 11

Debugging

Generally the first time we run a program it will generate some logic errors that the programmer must fix. Iwould say debugging is different from testing because generally different people run the tests. Also debuggingis done by the program’s designer while testing is handled by a different team. Hopefully by the time youare done with this chapter you will be aware of good strategies for detecting logic errors in your code.

11.1 The Debugging Process

Generally when debugging we are trying to find the source of an error and this can be quite time consuminghowever if its done in a structured process we can detect and remove bugs much more easily.

11.2 Doing Code Walk Throughs

11.3 Using Print To Debug

11.3.1 Advantages Of Print Statement Debugging

11.3.2 Disadvantages Of Print Statement Debugging

11.4 Using Assert To Debug

11.5 Debuggers

A debugger is very useful since we are able to view the running program’s state in memory. They can makedebugging very easy. Though some of the popular debuggers are gdb, jdb, Visual Studio Debugger. Theyall have some things in common.

171

11.5.1 Stack Tracer

11.5.2 Breakpoints

Watch Points

Class Breakpoints

Exception Breakpoints

Method Breakpoints

11.5.3 Profilers

11.5.4 Code Analysis Engine

11.6 Using The Eclipse Debugger

11.6.1 Setting Breakpoints

11.6.2 Running The Debugger

11.6.3 Viewing The Stack

11.6.4 Watching Values Of Variables

172

Chapter 12

Unit Testing

173

174

Chapter 13

Files

In Java files are seen as a stream of bytes. The end of a file is shown either by an end of file marker or by abyte count that shows where the file ends.

175

176

Chapter 14

I/O Streams

177

178

Chapter 15

Generics

You have seen that in many of our classes we do all kinds of checks and use exceptions to make sure that itwill work with the correct data types and class. A classic example of this is in sorting algorithms. With ourcurrent knowledge even for arrays we would have to create a different sort of method for ints, floats, doubles,chars, and Strings. Doing this is very tedious, and since the same implementation has to be written for eachdata type its easy to introduce inconsistencies and errors into each sort implementation.

One solution to the problem is to have one general class that takes as its input any nonprimitive type as itsargument. Because of this generics are also called parameterized types.

Advantages Of Using Generics

The advantages of using generic classes are as follows;

i We can use methods on various data types without having to do so much type checking and casting.

ii Cutting down on type checks and casts will decrease the amount of errors due to type mismatches.

iii More errors are caught at compile time versus execution time when parameterized types are used.

iv Generics make code reuse much easier.

v Generics make our code type safe since we cut down on type casts and type checks.

vi More bugs are found at compile time instead of run time when we use generics.

The syntax needed to define a parameterized type in Java is;

179

access modifier class GenericName < Parameters > {

Parameters

Constructors

functions

} (15.1)

To see get a better idea of what the layout of a generic class is look at

1 public class Data <T> {

2 private T a;

34 public Data(T a) {

5 this.a = a;

6 }

78 public void setA(T a) {

9 this.a = a;

10 }

1112 public T getA() {

13 T answer = this.a;

14 return answer;

15 }

1617 }

Program 15.1: Data.java

180

Chapter 16

Collectors & Iterators

181

182

Chapter 17

Threads

183

184

Chapter 18

Basic GUI Input/Output

185

186

Chapter 19

UML Basics

187