1.3 Translating using both a Compiler and Interpreter

Download Report

Transcript 1.3 Translating using both a Compiler and Interpreter

Object-based Programming
• Intuitive explanation
• Using objects to read input
• Creating objects
• Style rules
Program Components ~ Physical Objects
Natural Objects
Manufactured Objects
~ Program
Objects
Program Objects ~ Manufactured Objects
operations
manufactured by
perform
accelerate
brake
Class
instance of
add
Program
Object
Program
Object
subtract
execute
invoke
call
methods
Classification through Factories
manufactured by
manufactured by
Classification through Classes
instance of
BufferReader
BufferReader
BufferReader
Instance
Instance
ABMISpreadsheet
instance of
ABMISpreadsheet
ABMISpreadsheet
Instance
Instance
Using vs. Creating Objects
• Driving a car
– Using BufferReader for input
• Building a factory
– Creating ABMISpreadsheet
String Input
String Input
package main;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class AnInputPrinter {
public static void main (String[] args) {
System.out.println("Please enter the line to be printed");Classifying/
System.out.println ("The input was: " + readString());
typing
}
instances
static BufferedReader inputStream =
new BufferedReader(new InputStreamReader(System.in));
public static String readString() {
constructing
try {
return inputStream.readLine();
new instance
}
catch (Exception e) {
Invoking
System.out.println(e);
operation
return "";
}
}
}
Reading a String
• Wait for the user to enter a string on the next line.
• In case the user terminates input before entring a string, return “” and print an
error message.
Objects constructed to allow reading of strings from System.in
static BufferedReader inputStream =
new BufferedReader(new InputStreamReader(System.in));
public static String readString() {
try {
return inputStream.readLine();
} catch (Exception e) {
System.out.println(e);
return "";
}
}
}
Chained construction
static BufferedReader inputStream =
new BufferedReader(new InputStreamReader(System.in));
Line tokens
•
•
•
•
Char tokens
Byte input stream
Order light fixtures
Pass them to builder
Construct InputStreamReader instance
Pass it as a parameter to instance of
BufferedReader
• Understand better when we implement our
own class
Try-Catch Block
Program fragment that can
cause exception
try {
return inputStream.readLine();
}
catch (Exception e) {
System.out.println(e);
return 0;
}
Exception
Handler
Exception
Object
Import Declaration
Importing a Package
import java.io.BufferedReader;
short name
public class AnInputPrinter {
….
new BufferedReader(…)
package java.io;
public class BufferedReader {
….
…...
}
}
public class AnInputPrinter {
...
new java.io.BufferedReader(...)
…
}
full name
Package declaration makes
full class name long
Import declaration allows
use of short name
Import all vs. selective import
import java.io.BufferedStream;
import java.io.*;
import java.io.InputStreamReader;
import java.util.*;
import java.util.Vector;
• import all classes in
• requires more typing, specially
java.io
when a large number of classes
• convenient
are imported (e.g. toolkit)
• can accidentally import
and use undesired classes • accident importation not possible
• must look at entire code • class header documents imports
• know package of imported class
to determine what is
imported
• do not know package of
imported class
Always do selective imports
Integer Input
Integer Input
package main;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class AnInputSquarer {
public static void main (String[] args) {
System.out.println("Please enter the integer to be squared:");
int num = readInt();
System.out.println ("The square is: " + num*num);
}
static BufferedReader inputStream =
new BufferedReader(new InputStreamReader(System.in));
public static int readInt() {
try {
return Integer.parseInt(inputStream.readLine());
} catch (Exception e) {
System.out.println(e);
return 0;
}
}
}
readInt()
• Wait for the user to enter a string (of digits) on the next line.
• Return the int represented by the string.
• In case user terminates input before entring anything or enters a non integer
return 0 and print an error message.
public static int readInt() {
try {
return Integer.parseInt(inputStream.readLine());
} catch (Exception e) {
System.out.println(e);
return 0;
}
}
Alternative readInt()
• Wait for the user to enter a string (of digits) on the next line.
• Return the int represented by the string.
• In case user terminates input before entring anything or enters a non integer
return 0 and print an error message.
public static int readInt() {
try {
return new Integer (inputStream.readLine()).intValue());
} catch (Exception e) {
System.out.println(e);
return 0;
}
}
Less efficient and not clear that parsing occurs
Reading other primitive values
new Double (inputStream.readLine()).doubleValue());
new Boolean (inputStream.readLine()).doubleValue());
new T (inputStream.readLine()).tValue());
General pattern for reading primitive value of type t
Using vs. Creating Objects
• Driving a car
– Using BufferReader for input
• Building a factory
– Creating ABMISpreadsheet
ABMISpreadsheet
package bmi;
public class ABMISpreadsheet {
double height;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
No static
height = newHeight;
}
double weight;
Must be put in file
public double getWeight() {
ABMISpreadsheet.java,
return weight;
in folder bmi
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
}
Declaring Instance Variables
Missing
Code
public class ABMISpreadsheet {
Instance
double height;
Variables
...
double weight;
...
public void setWeight(double newWeight) {
weight = newWeight;
}
…
}
Parameter
instance methods
Instance Variables
ABMISpreadsheet Instance
setWeight
Body
getBMI
accesses
accesses
Body
accesses
Parameters
Instance
Variables
Belong to a single
method
Belong to all methods of
an instance
local variable
global variable
Outside Access to a Class
public class ABMISpreadsheet {
double height;
...
double weight;
...
public double getBMI() {
return weight/(height*height);
}
…
}
outside access
Main or other class
Variables should not be
public
But other classes need
their values
Accessing Instance Variables Via
Public Methods
ABMISpreadsheet Instance
weight
reads
writes
getWeight()
setWeight()
weight
calls
calls
height
reads
reads
writes
getHeight() setHeight() getBMI()
new
Weight
height
calls
Other class
calls
new
Height
Coding the Methods
ABMISpreadsheet Instance
weight
reads
writes
getWeight()
setWeight()
weight
calls
calls
height
reads
writes
getHeight() setHeight()
new
Weight
height
calls
Other class
calls
new
Height
Coding the Methods
ABMISpreadsheet Instance
weight
reads
writes
getWeight()
setWeight()
weight
calls
calls
new
Weight
Other class
Coding Getter and Setter Methods
ABMISpreadsheet Instance
public double getWeight() {
return weight;
}
weight
reads
writes
getWeight()
public void setWeight(double newWeight) {
weight = newWeight;
}
setWeight()
function
weight
calls
calls
new
Weight
other class
procedure
returns nothing
Functions vs. Procedures
package bmi;
public class ABMISpreadsheet {
double height;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
double weight;
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
}
functions
procedures
return nothing
Function vs. Procedure
Function
Procedure
Function vs. Procedure
Function
Procedure
Assignment Statement
public void setHeight(double newHeight) {
height = newHeight;
}
setHeight(1.77)
<variable>
=
<expression>
code that yields a value
variables memory
LHS
RHS
weight
1.75*weight
newHeight 1.77
0
height
1.77
0
weight
0.0
Properties
public class ABMISpreadsheet {
double height;
public double getHeight() {
return height;
Height
}
public void setHeight(double newHeight) {
height = newHeight;
}
double weight;
public double getWeight() {
return weight;
Weight
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
BMI
return weight/(height*height);
}
}
Read-Only and Editable Properties
Typed, Named Unit of Exported Object State
public class C {
Bean
Name: P
Type: T
public T getP() {
...
}
Readonly
Editable
public void setP(T newValue) {
...
}
}
Violates Bean
Conventions
Getter method
Setter method
Conventions for
newP
obtainP
•humans
•tools
Properties Classification
public class ABMISpreadsheet {
double height;
public double getHeight() {
return height;
Height
}
public void setHeight(double newHeight) {
height = newHeight;
}
double weight;
public double getWeight() {
return weight;
Weight
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
BMI
return weight/(height*height);
}
}
Read-Only
Editable
Independent
Editable
Independent
Read-only
Dependent
Using ABMISpreadsheet
ABMIDriver
package main;
import bmi.ABMISpreadsheet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ABMIDriver {
static BufferedReader dataIn = new BufferedReader(new
InputStreamReader(System.in));;
public static void main (String args[]) {
ABMISpreadsheet bmiSpreadsheet = new ABMISpreadsheet();
bmiSpreadsheet.setWeight(readWeight());
bmiSpreadsheet.setHeight(readHeight());
print (bmiSpreadsheet);
}
ABMIDriver
public static double readWeight() {
System.out.println("Please enter weight in Kgs:");
return readDouble();
}
public static double readHeight() {
System.out.println("Please enter height in Metres:");
return readDouble();
}
public static double readDouble() {
try {
return (new Double(dataIn.readLine())).doubleValue();
} catch (Exception e) {
System.out.println(e);
return 0;
}
}
ABMIDriver
public static void print (ABMISpreadsheet bmiSpreadsheet) {
System.out.println("****Weight*****");
System.out.println(bmiSpreadsheet.getWeight());
System.out.println("****Height****");
System.out.println(bmiSpreadsheet.getHeight());
System.out.println("****Body Mass Index****");
System.out.println (bmiSpreadsheet.getBMI());
}
}
ABMIEditor
package main;
import bmi.ABMISpreadsheet;
import bus.uigen.ObjectEditor
import java.io.InputStreamReader;
public class ABMIEditor {
ObjectEditor.edit(new ABMISpreadsheet());
}
ObjectEditor.edit()
public class ABMISpreadsheet {
Height double height, weight;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
Weight }
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
BMI }
public double getBMI() {
return weight/(height*height);
}
}
Properties Classification
public class ABMISpreadsheet {
double height;
public double getHeight() {
return height;
Height
}
public void setHeight(double newHeight) {
height = newHeight;
}
double weight;
public double getWeight() {
return weight;
Weight
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
BMI
return weight/(height*height);
}
…
Read-Only
Editable
Independent
Editable
Independent
Read-only
Dependent
Calling Getter and Setter Methods
• When ObjectEditor window is created
•Getter method of each property called to display initial
value of property
• When property is changed to a new value
•Setter method of property is called with new value as
actual parameter
•Getter method of each property is called to refresh display
Calling Getter and Setter Methods
public class ABMISpreadsheet {
double height = 1.77;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
double weight = 77;
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
}
Tracing Method Calls
public class ABMISpreadsheet {
double height = 1.77;
public double getHeight() {
System.out.println (“getHeight Called”);
return height;
}
public void setHeight(double newHeight) {
System.out.println (“setWeight Called”);
height = newHeight;
}
double weight = 77;
public double getWeight() {
System.out.println (“getWeight Called”);
return weight;
}
public void setWeight(double newWeight) {
System.out.println (“setWeight Called”);
weight = newWeight;
}
public double getBMI() {
System.out.println (“getBMI Called”);
return weight/(height*height);
Actual Trace
Modified ABMISpreadsheet
public class ABMISpreadsheet {
double height, weight;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
How will above
public double getBMI() {
return calculateBMI(weight, height);
UI change?
}
public double calculateBMI(double weight, double height) {
return weight / (height*height);
|
}
Properties + Class Menu
Editing in slow motion : Initial
value
Editing in slow motion: text
string edited
Editing in slow motion: return
triggers setter and getter calls
Renaming getter method
public class ABMISpreadsheet {
double height, weight;
public double height() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return calculateBMI(weight, height);
}
public double calculateBMI(double weight, double height) {
return weight / (height*height);
|
}
ObjectEditor does not know it is
getter
Reducing Access
public class ABMISpreadsheet {
double height, weight;
double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return calculateBMI(weight, height);
}
public double calculateBMI(double weight, double height) {
return weight / (height*height);
|
}
Height is not a readable property
Changing setter
public class ABMISpreadsheet {
double height, weight;
public double getHeight() {
return height;
}
public int setHeight(double newHeight) {
height = newHeight;
return height;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return calculateBMI(weight, height);
}
public double calculateBMI(double weight, double height) {
return weight / (height*height);
Height is not a writeable property
ABMISpreadsheet
ABMISpreadsheet Instance
weight
reads
writes
getWeight()
setWeight()
weight
calls
calls
height
reads
reads
writes
getHeight() setHeight() getBMI()
new
Weight
height
calls
Other class
calls
new
Height
AnotherBMISpreadsheet
ABMISpreadsheet Instance
weight
reads
writes
getWeight()
setWeight()
weight
calls
calls
height
reads
bmi
writes
reads
getHeight() setHeight() getBMI()
new
Weight
height
calls
Other class
calls
new
Height
AnotherBMISpreadsheet
ABMISpreadsheet Instance
weight
reads
writes
getWeight()
setWeight()
weight
calls
calls
height
reads
bmi
writes
reads
getHeight() setHeight() getBMI()
new
Weight
height
calls
Other class
calls
new
Height
Methods that Changes
AnotherBMISpreadsheet Instance
weight
height
writes
writes
setWeight()
calls
bmi
reads
setHeight() getBMI()
new
Weight
Other class
calls
new
Height
setWeight()
AnotherBMISpreadsheet Instance
weight
bmi
writes
setWeight()
public void setWeight(double newWeight) {
weight = newWeight;
bmi = weight / (height*height);
new }
calls
Weight
Other class
setHeight()
AnotherBMISpreadsheet Instance
height
bmi
writes
setHeight()
public void setHeight(double newHeight) {
height = newHeight;
bmi = weight / (height*height);
}
calls
Other class
new
Height
getBMI()
AnotherBMISpreadsheet Instance
bmi
reads
getBMI()
public double getBMI() {
return bmi;
}
Other class
Complete Code
package bmi;
public class AnotherBMISpreadsheet {
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = weight/(height*height);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = weight/(height*height);
}
public double getBMI() {
return bmi;
}
}
Similarities in the two Classes
package bmi;
public class ABMISpreadsheet {
double height;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
double weight;
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
}
Similarities in the two Classes
package bmi;
public class AnotherBMISpreadsheet {
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = weight/(height*height);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = weight/(height*height);
}
public double getBMI() {
return bmi;
}
}
Similarities in the two Classes
Interface
package bmi;
public interface BMISpreadsheet {
public double getHeight();
public void setHeight (double newVal);
public double getWeight() ;
public void setWeight(double newWeight) ;
public double getBMI();
}
Must be put in file
BMISpreadsheet.java in folder
bmi
Implementing an Interface
contract
package bmi
public class AnotherBMISpreadsheet implements BMISpreadhsheet {
parameter
double height, weight, bmi;
public double getHeight() {
names never
return height;
matter to Java
}
public void setHeight (double newHeight) {
height = newHeight;
bmi = calculateBMI();
}
public double getWeight() {
package bmi;
return weight;{
public interface BMISpreadsheet
}
public
double getHeight();
newWeight)
public void
voidsetWeight(double
setHeight (double
newVal);{
weight
= newWeight;
public double
getWeight()
;
bmi
= calculateBMI();
public void
setWeight(double
newWeight) ;
}
public
double getBMI();
public double getBMI() {
}
return bmi;
}
Real-World Analogy
implements
Accord
Specification
manufactures
Interface
implements
ABMISpreadsheet
instance of
ABMISpreadsheet
BMISpreadsheet
Instance
Instance
AnotherBMISpreadsheet
ABMISpreadsheet
instance of
AnotherBMISpreadsheet
AnotherBMISpreadsheet
Instance
Instance
Using Car Specification to Classify
implements
Accord
Specification
manufactures
Accord
Accord
Accord
Accord
Using Interface to Classify
implements
ABMISpreadsheet
instance of
BMISpreadsheet
BMISpreadsheet
BMISpreadsheet
Instance
Instance
AnotherBMISpreadsheet
instance of
BMISpreadsheet
BMISpreadsheet
Instance
Instance
Class-based typing
package main;
import bmi.ABMISpreadsheet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ABMIDriver {
static BufferedReader dataIn = new BufferedReader(new
InputStreamReader(System.in));;
public static void main (String args[]) {
ABMISpreadsheet bmiSpreadsheet = new ABMISpreadsheet();
bmiSpreadsheet.setWeight(readWeight());
bmiSpreadsheet.setHeight(readHeight());
print (bmiSpreadsheet);
}
Class-based Typing
public static void print (ABMISpreadsheet bmiSpreadsheet) {
System.out.println("****Weight*****");
System.out.println(bmiSpreadsheet.getWeight());
System.out.println("****Height****");
System.out.println(bmiSpreadsheet.getHeight());
System.out.println("****Body Mass Index****");
System.out.println (bmiSpreadsheet.getBMI());
}
}
Should print be in ABMISpreadsheet?
Interface-based typing
package main;
import bmi.ABMISpreadsheet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ABMIDriver {
static BufferedReader dataIn = new BufferedReader(new
InputStreamReader(System.in));;
public static void main (String args[]) {
BMISpreadsheet bmiSpreadsheet = new ABMISpreadsheet();
bmiSpreadsheet.setWeight(readWeight());
bmiSpreadsheet.setHeight(readHeight());
print (bmiSpreadsheet);
}
Interface-based Typing
public static void print (BMISpreadsheet bmiSpreadsheet) {
System.out.println("****Weight*****");
System.out.println(bmiSpreadsheet.getWeight());
System.out.println("****Height****");
System.out.println(bmiSpreadsheet.getHeight());
System.out.println("****Body Mass Index****");
System.out.println (bmiSpreadsheet.getBMI());
}
}
Changing the class
package main;
import bmi.ABMISpreadsheet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ABMIDriver {
static BufferedReader dataIn = new BufferedReader(new
InputStreamReader(System.in));;
public static void main (String args[]) {
BMISpreadsheet bmiSpreadsheet = new
AnotherBMISpreadsheet();
bmiSpreadsheet.setWeight(readWeight());
bmiSpreadsheet.setHeight(readHeight());
print (bmiSpreadsheet);
}
1 (vs. 3) changes!
Cannot Instantiate Specification
Cannot order car from a specification
•Must order from factory.
•A car defined by Accord specification ordered from
factory implementing the specification.
Cannot instantiate interface
•Must instantiate class.
•new BMISpreadsheet() - illegal
•BMISpreadsheet instance created by instantiating class
implementing interface.
Interface as Syntactic Specification
package bmi;
public class ABMISpreadsheet implements BMISpreadsheet{
double height, weight;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return height/(weight*weight);
}
}
Interface as Syntactic Specification
package bmi;
public class ABMISpreadsheet implements BMISpreadsheet{
double height, weight;
public double getHeight() {
return height;
Syntactic
}
public void setHeight(double newHeight) {
Contract
height = newHeight;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
Bombay
return 3245.4
Market
}
Index?
}
Interface Required
Define interface for:
– All classes (that are instantiated.)
– Some are not.
• main class
– Include all public instance methods
– when interface not given a priori, define it after
class implemented
• bottom up programming
Pros and cons of two alternatives
public class ABMISpreadsheet implements BMISpreadsheet {
double height;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
double weight;
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
}
Pros and cons of two alternatives
public class AnotherBMISpreadsheet implements BMISpreadsheet {
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = weight/(height*height);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = weight/(height*height);
}
public double getBMI() {
return bmi;
}
}
ABMISpreadsheet vs.
AnotherBMISpreadSheet
• AnotherBMISpreadsheet less likely to be correct
•Have to remember to set all dependents
• ABMISpreadsheet uses less space (variables)
• Getter methods of AnotherBMISpreadhseet are faster.
• Setter methods of ABMISpreadsheet are faster.
• Usually getter methods are called more often that setter
methods - e.g when a graphical user interface is refreshed
•Typically AnotherBMISpreadsheet will be faster, overall.
Time-Space Tradeoff
Time
Space
Space Miser
Time Miser
Time-Space Tradeoff
Space
Time
Space Miser
Time Miser
Relating Interface and Class
Names
Class Name:
•<Qualifier><Interface> (ABMISpreadsheet,
ASpaceEfficientBMISpreadsheet, SpaceEfficientBMISpreadsheet)
•<Interface><Qualifier>Impl (BMISpreadsheetImpl,
BMISpreadsheetSpaceEfficientImpl)
Interface Name:
•<ClassName>Interface (ABMISpreadsheetInterface,
IABMISpreadsheet)
Overloading
Look at the airplane fly.
Two different
words with
same name
The fly is bothering me.
Operation
Definitions
Context of
Actual
Parameters
String
double
Two different
operations with
same name
public void println (String val) {…} System.out.println(“****Weight****”);
public void println (double val) {…} System.out.println(bmiSpreadsheet.getWeight());
Overloaded Operators
5+6
6.0 + 5.0
“6” + “5”
“6” + 5
Java: Cannot define programmer defined overloaded operators
Can define overloaded methods
Ambiguous Context
Time flies like an arrow.
Fruit flies like an orange.
Operation
Definitions
public void myPrint (String val) {…}
public void myPrint (String val) {…}
myPrint(“setWeight called”);
Ambiguous Context
String s =read() + read() + read()
String s =reads () +ss reads () + ss reads ()
String s = reads () +sd readd() +ss reads ()
String s =reads () +ss reads () + sd reads ()
String s =reads () +sd readd() +sd readd ()
Return type not part of disambiguating context
Operation
Definitions
public double read () {…}
public String read () {…}
double i = read();
String s = read();
ABMIDriver
public static void print (ABMISpreadsheet bmiSpreadsheet) {
System.out.println("****Weight*****");
System.out.println(bmiSpreadsheet.getWeight());
System.out.println("****Height****");
System.out.println(bmiSpreadsheet.getHeight());
System.out.println("****Body Mass Index****");
System.out.println (bmiSpreadsheet.getBMI());
}
}
Should print be in ABMISpreadsheet?
Modified ABMISpreadsheet
public void print () {
System.out.println("****Weight*****");
System.out.println(getWeight());
System.out.println("****Height****");
System.out.println(getHeight());
System.out.println("****Body Mass Index****");
System.out.println (getBMI());
}
}
Different method invocation syntax
Method Invocation Syntax
System.out.println(bmiSpreadsheet.getBMI())
Target
Object
External Call
Method
Name
getBMI()
Internal Call
Modified ABMISpreadsheet
public void print () {
System.out.println("****Weight*****");
System.out.println(getWeight());
System.out.println("****Height****");
System.out.println(getHeight());
System.out.println("****Body Mass Index****");
System.out.println (getBMI());
}
Object name implicit
Modified ABMISpreadsheet
public void print () {
System.out.println("****Weight*****");
System.out.println(this.getWeight());
System.out.println("****Height****");
System.out.println(this.getHeight());
System.out.println("****Body Mass Index****");
System.out.println (this.getBMI());
}
The object on which the method (print) is being invoked
Original ABMIDriver
package main;
import bmi.ABMISpreadsheet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ABMIDriver {
static BufferedReader dataIn = new BufferedReader(new
InputStreamReader(System.in));;
public static void main (String args[]) {
ABMISpreadsheet bmiSpreadsheet = new ABMISpreadsheet();
bmiSpreadsheet.setWeight(readWeight());
bmiSpreadsheet.setHeight(readHeight());
print (bmiSpreadsheet);
}
Modified ABMIDriver
package main;
import bmi.ABMISpreadsheet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ABMIDriver {
static BufferedReader dataIn = new BufferedReader(new
InputStreamReader(System.in));;
public static void main (String args[]) {
ABMISpreadsheet bmiSpreadsheet = new ABMISpreadsheet();
bmiSpreadsheet.setWeight(readWeight());
bmiSpreadsheet.setHeight(readHeight());
bmiSpreadsheet.print ();
}
Object-based vs. conventional
programming
• Program element is
autonomous, active.
Its users simply ask it
to do things.
• It is the target of
method call
– bmiSpreadsheet.getBM
I();
– bmiSpreadsheet.print()
• Users share code
• Program element is
passive. Users write
code to manipulate it.
• It is parameter to
method call:
– getBMI(bmiSpreadshe
et)
– print (bmiSpreadsheet)
• Users write their own
code
UI Code and Objects
• Original approach was better
– though less “O-O”
– lots of text books prefer the modified approach
• Object can have multiple user interfaces
– UI code should not be tied to object code
– hard to change independently
• User-interface code should be in main (or other
classes)
• Only object invocation, instantiation (for now), user
interface code (for now), connection (for now) in
main
– no arithmetic, scanning, ...
ABMIDriver
package main;
import bmi.ABMISpreadsheet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ABMIDriver {
static BufferedReader dataIn = new BufferedReader(new
InputStreamReader(System.in));;
public static void main (String args[]) {
ABMISpreadsheet bmiSpreadsheet = new ABMISpreadsheet();
bmiSpreadsheet.setWeight(readWeight());
bmiSpreadsheet.setHeight(readHeight());
print (bmiSpreadsheet);
}
Object instantiation and invocation
ABMIDriver
public static double readWeight() {
System.out.println("Please enter weight in Kgs:");
return readDouble();
}
public static double readHeight() {
System.out.println("Please enter height in Metres:");
return readDouble();
}
public static double readDouble() {
try {
return (new Double(dataIn.readLine())).doubleValue();
} catch (Exception e) {
System.out.println(e);
return 0;
}
Input code
}
ABMIDriver
public static void print (ABMISpreadsheet bmiSpreadsheet) {
System.out.println("****Weight*****");
System.out.println(bmiSpreadsheet.getWeight());
System.out.println("****Height****");
System.out.println(bmiSpreadsheet.getHeight());
System.out.println("****Body Mass Index****");
System.out.println (bmiSpreadsheet.getBMI());
}
}
Output code and object invocation
UI vs. Debugging Code
public void setWeight(double newWeight) {
System.out.println(“Weight: “ + weight);
weight = newWeight;
}
UI vs. Debugging Code
public void getBMI() {
System.out.println(“BMI returned: “ + getBMI());
weight/(height*height);
}
Infinite recursion!
Comments
Single-line comment
double bmi; //computed by setWeight and setHeight
Arbitrary comment
/* This version recalculates the bmi
when weight or height change, not when
getBMI is called
*/
public class AnotherBMISpreadsheet {…}
/* recompute dependent properties */
bmi = weight / (height*height);
Removing Debugging Code
/*
System.out.println(newHeight); /*debugging statement */
*/
/*
System.out.println(newHeight); // debugging statement
*/
Javadoc Conventions
/* This version recalculates the bmi
when weight or height change, not when
getBMI is called
*/
public class AnotherBMISpreadsheet {…}
/* This version recalculates the bmi
* when weight or height change, not when
* getBMI is called
*/
public class AnotherBMISpreadsheet {…}
What to Comment?
Any code fragment needing explanation:
•class
•top-level algorithm, author, date modified
•variable declaration
•purpose, where used
•method declaration
•params, return value, algorithm, author, date modified
•statement sequence
•explanation
•Debugging code
What to Comment?
double w; // weight
Bad Variable Name
double weight; // weight
Redundant
double weight;
Self Commenting
double bmi; // computed by setWeight() and setHeight()
Useful Comment
Javadoc Tags
Javadoc
tags
/*
* @author Prasun Dewan
* @param newWeight the new value of the property, weight.
* sets new values of the variables, weight and bmi
*/
public void setWeight (double newWeight) {
…
}
/*
* @author Prasun Dewan
* @return the value of the variable, weight
*/
public double getWeight () {
…
}
Improving the Style
public class AnotherBMISpreadsheet implements BMISpreadsheet {
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = weight/(height*height);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = weight/(height*height);
}
public double getBMI() {
return bmi;
}
}
Code
Repetition
Why Avoid Code Duplication?
• Less Typing
• Changes (Inches, LB)
•can forget change all repetitions
Example Changes: LB, Inches
public class AnotherBMISpreadsheet implements BMISpreadsheet {
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
weight/(height*height);
bmi = (weight/2.2)/(height
* 2.54/100*height*2.54/100);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
weight/(height*height);
bmi = (weight/2.2)/(height
* 2.54/100*height*2.54/100);
}
...
How to avoid code duplication?
public class AnotherBMISpreadsheet implements BMISpreadsheet {
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = calculateBMI(weight, height);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = calculateBMI(weight, height);
}
double calculateBMI(double weight, double height) {
return (weight/2.2)/(height * 2.54/100*height*2.54/100);
}
Not public
Principle of Least Privilege
• Do not give a user of some code more rights than it needs.
•Code is easier to change.
•Need to learn less to use code.
•Less likelihood of accidental or malicious damage to program.
• Like hiding engine details from car driver.
ABMISpreadsheeet
Other class
getWeight()
setWeight()
getHeight()
setHeight()
getBMI()
computeBMI()
calculateBMI()
Only Public Methods in Interface
package bmi;
public class AnotherBMISpreadsheet implements BMISpreadhsheet {
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight (double newHeight) {
height = newHeight;
bmi = calculateBMI(weight, height);
}
public double getWeight() {
package bmi;
return weight;{
public interface BMISpreadsheet
}public double getHeight();
public
newWeight)
public void
voidsetWeight(double
setHeight (double
newVal);{
weight
= newWeight;
public double
getWeight()
;
bmi
= calculateBMI(weight,
height);
public void
setWeight(double
newWeight)
;
}public double getBMI();
public double getBMI() {
}
return bmi;
}
double calculateBMI(double weight, double height) {
return weight/ (height*height);
not in
}
interface
Pure vs. Impure Functions
ABMISpreadsheet Instance
ABMISpreadsheet Instance
calculateBMI
getWeight
Body
accesses
Body
accesses
weight
weight
calculateBMI(77,1.77)
height
24.57
77
setWeight(71)
...
...
calculateBMI(77,1.77)
setWeight(77)
getWeight()
24.57
getWeight()
71
Impure Functions
public double calculateBMI(double weight, double height) {
System.out.println(“height: “ + height + “weight: “ +
weight)
return weight/(height*height);
}
Printing is side effect
Side Effect
• Printing
• Reading input
• Changing global
variable
• Benign
• Done all the time
– readLine()
• Very dangerous
– only if implementing
input
Improving the Style
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = calculateBMI(weight, height);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
Magic
bmi = calculateBMI();
numbers?
}
public double getBMI() {
return bmi;
}
double calculateBMI(double weight, double height) {
return (weight/2.2)/(height * 2.54/100*height*2.54/100);
}
}
Improving
the
Style
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = calculateBMI(weight, height);
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = calculateBMI(weight, height); Named
}
public double getBMI() {
return bmi;
}
double calculateBMI() {
return (weight/LBS_IN_KG) /
(height*CMS_IN_INCH/100*height*CMS_IN_INCH/100);
}
Constants
Declaring Named Constants
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
return (weight/LBS_IN_KG) /
(height*CMS_IN_INCH/100*height*CMS_IN_INCH/100);
}
}
Un-initializing
Declaration
Initializing
Declaration
All Caps by
Conventions
Cannot
Change
Initial Value
Variables vs. Named Constants
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
double lbsInKg = 2.2;
double cmsInInch = 2.54;
double calculateBMI(double weight, double height) {
return (weight/lbsInKg) / (height*cmsInInch/100*height*cmsInInch/100);
}
}
Accidental or Malicious
Modification
Violating Least
Privilege
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
double lbsInKg = 2.2;
double cmsInInch = 2.54;
double calculateBMI() {
lbsInKg = 22;
return (weight/lbsInKg) / (height*cmsInInch/100*height*cmsInInch/100);
}
}
Literals, Named Constants,
Constants, Variables
Literal
Constant
Named
Constant
return (weight/2.2) / (height*2.54/100*height*2.54/100);
return (weight/LBS_IN_KG) / (height*CMS_IN_INCH/100*height*CMS_IN_INCH/100)
return (weight/lbsInKg) / (height*cmsInInch/100*height*cmsInInch/100);
Variable
Literals vs. Named Constants vs.
Variables
Use constants for program values that do not
change.
– Use named constants for magic numbers
What is a Magic Number?
Natural Constants
return (weight/2.2) / (height*2.54/100*height*2.54/100);
return (weight/LBS_IN_KG) / (height*CMS_IN_INCH/100*height*CMS_IN_INCH/100)
Human-Created Constant
return hoursWorked*hourlyWage + 50;
return hoursWorked*hourlyWage + BONUS;
System.out.println (“Bonus: “ + 50);
What is a magic number?
• Human-created constant is a magic number.
• Natural constant may be a magic number to some.
More Code Repetition
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
return (weight/LBS_IN_KG) /
(height*CMS_IN_INCH/100*height*CMS_IN_INCH/100) ;
}
}
Within Same Method
and Has Same Value
Removing Code Repetition
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
double heightInMetres = height*CMS_IN_INCH/100;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Independent Code = Method
Separate Method for:
• any independent piece of code.
• even if it is not duplicated.
• specially if it is more than one line.
public void setWeight(double newWeight) {
System.out.println(“Weight: “ + weight);
weight = newWeight;
}
public void setWeight(double newWeight) {
printWeight();
weight = newWeight;
}
Local vs. Global Variable
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
double heightInMetres = height*CMS_IN_INCH/100;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Local vs. Global Variable
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
double heightInMetres = height*CMS_IN_INCH/100;
public void setHeight(double newHeight) {
height = heightInMetres;
bmi = calculateBMI();
}
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Violating least privilege
Identifier Scope
• Region of code where the identifier is visible.
• Arbitrary scopes not possible
Scope
public class AnotherBMISpreadsheet implements BMISpreadsheet{
height Scope
double height, weight, bmi;
public double getHeight() {
Not a Scope
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = calculateBMI();
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = calculateBMI();
heightInMetres
}
public double getBMI() {
Scope
return bmi;
}
double calculateBMI(double weight, double height) {
double heightInMetres = height*CMS_IN_INCH/100;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres);
}
Multiple
definitions
public class AnotherBMISpreadsheet implements BMISpreadsheet{
height Scope
double height, weight, bmi;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
bmi = calculateBMI();
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
bmi = calculateBMI();
height Scope
}
public double getBMI() {
return bmi;
}
double calculateBMI(double weight, double height) {
double heightInMetres = height*CMS_IN_INCH/100;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres);
}
Overriding Scopes
• Narrower scope overrides definitions in
more general scope
Scope of Public Items
getHeight()
Scope
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
public double getHeight() {
return height;
}
...
}
ABMISpreadsheetDriver
ABMISpreadsheet
Non Public Instance Variables
public class ABMISpreadsheet implements BMISpreadsheet
{
public double height, weight, bmi;
...
}
Making Instance Variables Public
public class ABMISpreadsheetWithPublicVariables {
public double height, weight, bmi;
...
}
Other Classes
Hard to Change Representation
public class ABMISpreadsheetWithPublicVariables {
public double height, weight;
...
}
Other Classes
Internal constraints violated
public class ABMISpreadsheetWithPublicVariables {
public double height, weight, bmi;
...
}
Other Classes
bmiSpreadsheet.height = 5.0;
System.out.println (bmiSpreadsheet.bmi);
Encapsulation Principle
Do not make instance variables public
– Expose them through public methods
Variable Scope
• Least privilege =>
– Keep scope of variable as small as possible
• no public variables
• as few global variables as possible
Named-Constant Scope
• Least privilege does not apply since named
constants cannot be modified.
• Make scope of named constants as large as
possible to prevent duplication.
Named constant scope
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
public final double LBS_IN_KG = 2.2;
public final double CMS_IN_INCH = 2.54;
double calculateBMI() {
double heightInMetres = height*CMS_IN_INCH/100;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Public Constants
public interface BMISpreadsheet {
Inconsistent value
cannot be stored
public final double CMS_IN_INCH = 2.54;
}
Implementation
Independent
ABMISpreadsheet
AnotherBMISpreadsheet
Principle
Declare implementation-independent named
constants in interfaces
– implementing classes can access them.
Initializing Declaration
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
double heightInMetres = height*CMS_IN_INCH/100;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Un-initializing Declaration
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
double heightInMetres;
heightInMetres = height*CMS_IN_INCH/100;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Un-initialized Variable
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
double heightInMetres;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Initializing all Variables
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height, weight, bmi;
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
double heightInMetres = height*CMS_IN_INCH/100;;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Initializing all Variables
public class AnotherBMISpreadsheet implements BMISpreadsheet{
double height = 70, weight = 160, bmi = calculateBMI();
...
final double LBS_IN_KG = 2.2;
final double CMS_IN_INCH = 2.54;
double calculateBMI() {
double heightInMetres = height*CMS_IN_INCH/100;;
return (weight/LBS_IN_KG) / (heightInMetres*heightInMetres) ;
}
}
Instance-independent Instantiation
package bmi;
public class ABMISpreadsheet {
double height = 1.77;
double weight = 70;
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
Instance-dependent Initialization
• May want instance variables to be initialized
to different values in different instances (my
and your instance of ABMISpreadsheet)
• Can be done by adding special method called
constructor to class.
Instance-dependent
Instantiation
package bmi;
public class ABMISpreadsheet {
Combined type and
double height, weight ;
method name
public ABMISpreadsheet (double initHeight, double initWeight) {
height = initHeight;
weight = initWeight;
}
public double getHeight() {
return height;
}
public void setHeight(double newHeight) {
height = newHeight;
}
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
Constructor
Special method in a class:
• name of method same as class name
• no return type name in header
• called immediately after an instance is created (after
instance variables are allocated in memory and before
they can be accessed)
• used to initialize instance variables based on its
parameters
• prefix new precedes call to it
– new ABMISpreadsheet (77, 1.77)
• Cannot be declared in interface
• Can have multiple parameters
– usually one per instance variable
How Java processes a constructor call
new C (a1, a2, …)
• Creates an instance of C (allocates memory for
its instance variables)
• Calls the constructor
– actual parameters a1, a2, … must match the formal
parameters (as in all methods)
• new ABMISpreadsheet(77, 1.77) legal
• new ABMISpreadsheet() illegal
• Returns the instance (of type C)
Default Constructor
• Every class must have a constructor
• Java automatically creates one if we do not
Default Constructor
package bmi;
public class ABMISpreadsheet {
public ABMISpreadsheet() {
}
double height;
public double getHeight() {
return height;
}
Default public void setHeight(double newHeight) {
height = newHeight;
}
double weight;
public double getWeight() {
return weight;
}
public void setWeight(double newWeight) {
weight = newWeight;
}
public double getBMI() {
return weight/(height*height);
}
Inserted in Object Code
not in Source Code
new ABMISpreadsheet()
Case Conventions
• Start variable name with lowercase letter (weight).
•Start class name with uppercase letter (ABMICalculator)
•Start each new word with upper case letter (ASquareCalculator)
Errors
class ABMISpreadsheet {
double height, weight;
static double getBMI() {
return (height*heigh)/weight
}
Syntax
Error
Semantics
Error
Logic
Error
Access
Error
Static vs. non static
• In main class
– Make all methods and variables static
– Main class not instantiated
• Instantiated class
– Only instance methods and variables
– At least for now
Another Object-based Problem
Another Example: Point
X
.
R
Y
q
.
Solution
public class ARocketTracker {
public static void main (String args[]) {
System.out.println("Please Enter Cartesian Coordinates of Highest Point");
double highestX = readDouble();
double highestY = readDouble();
double highestRadius = Math.sqrt(highestX*highestX + highestY*highestY);
double highestAngle = Math.sqrt (Math.atan(highestY/highestX));
print (highestX, highestY, highestRadius, highestAngle);
}
public static void print(double x, double y, double radius, double angle) {
System.out.println ("Highest Horizontal Distance " + x);
System.out.println ("Highest Vertical Distance
" + y);
System.out.println ("Highest Total Distance
" + radius);
System.out.println ("Highest Angle
" + angle);
}
public staticdouble readDouble() { … };
…
}
}
Related Problem
Related Solution
public class ARocketTracker {
public static void main (String args[]) {
System.out.println("Please Enter Polar Coordinates of Highest Point");
double highestRadius = readDouble();
double highestAngle = readDouble();
double highestX = highestRadius*Math.cos(highestAngle);
double highestY = highestRadius*Math.sin(highestAngle);
print (highestX, highestY, highestRadius, highestAngle);
}
public static void print(double x, double y, double radius, double angle) {
System.out.println ("Highest Horizontal Distance " + x);
System.out.println ("Highest Vertical Distance
" + y);
System.out.println ("Highest Total Distance
" + radius);
System.out.println ("Highest Angle
" + angle);
}
public staticdouble readDouble() { … };
…
}
}
Drawbacks of monolithic solutions
• Read code in main method
– cannot return two values from a method
• Calculation code not reusable
Point Interface
public interface Point {
public int getX();
public int getY();
public double getAngle();
public double getRadius();
}
Point Representations
•
•
•
•
•
X, Y (Cartesian Representation)
Radius, Angle (Polar Representation)
X, Radius
X, Y, Radius, Angle
….
Algorithms
Cartesian Representation
R = sqrt (X2 * Y2)
X
q = arctan (Y/X)
.
R
Y
q
.
Polar Representation
X = R*cos(q)
Y = R*sin(q)
Class: ACartesianPoint
public class ACartesianPoint implements Point {
int x, y;
public ACartesianPoint(int initX, int initY) {
x = initX;
y = initY;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public double getAngle() {
return Math.atan((double) y/x);
}
public double getRadius() {
return Math.sqrt(x*x + y*y);
}
}
Class: APolarPoint
public class APolarPoint implements Point {
double radius, angle;
public APolarPoint(int initRadius, int initAngle) {
radius = initRadius;
angle = initAngle;
}
public int getX() {
return (int) (radius*Math.cos(angle));
}
public int getY() {
return (int) (radius*Math.sin(angle));
}
public double getAngle() {
return angle;
}
public double getRadius() {
return radius;
}
}
Using the Interface and its
Implementations
Point point1 = new ACartesianPoint (50, 50);
Point point2 = new APolarPoint (70.5, Math.pi()/4);
point1 = point2;
Constructor chooses implementation
Cannot be in interface.
Shared main method
public static void main (String args[]) {
Point highest = getPoint();
print (highest);
}
Shared print method
public static void print (Point p) {
System.out.println ("Higest Horizontal Distance
p.getX());
System.out.println ("Highest Vertical Distance " +
p.getY());
System.out.println ("Highest Total Distance
"+
p.getRadius());
System.out.println ("Highest Angle
"+
p.getAngle());
}
"+
Get method Cartesian
public static Point getPoint () {
System.out.println("Please Enter Cartesian Coordinates of Highest Point");
return new ACartesianPoint (readDouble(),readDouble());
}
Get method Polar
public static Point getPoint () {
System.out.println("Please Enter Polar Coordinates of Highest Point");
return new APolarPoint (readDouble(), readDouble());
}
Bottom-up Programming with
Coarse-grained steps
Interface
Class
Used in
ABMISpreadsheet
example
Top-Down with Finer Steps
Interface
Representation
Algorithm
Class
Used in Point
example
Real life
• Define initial interface
• Modify it incrementally as you change