Object-based Programming Intuitive explanation Using objects to read input Creating objects Style...

Preview:

Citation preview

Object-based Programming

• Intuitive explanation

• Using objects to read input

• Creating objects

• Style rules

Manufactured Objects

Natural Objects

Program Components ~ Physical Objects

~ Program

Objects

Program Objects ~ Manufactured Objects

Program

Object

add

subtract

methodsexecuteinvokecall

manufactured byaccelerate

brake

operations

perform

Classinstance of

Program

Object

Classification through Factories

manufactured by

manufactured by

Classification through Classes

BufferReader

Instance

BufferReader instance of

BufferReader

Instance

ABMISpreadsheet

Instance

ABMISpreadsheet instance of

ABMISpreadsheet

Instance

Using vs. Creating Objects

• Driving a car– Using BufferReader for input

• Building a factory– Creating ABMISpreadsheet

String Input

String Inputpackage 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"); System.out.println ("The input was: " + readString()); } 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 "";

} }}

Classifying/ typing

instances

Invoking operation

constructing new instance

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 "";

} }}

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

Chained construction

• 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

static BufferedReader inputStream = new BufferedReader(new InputStreamReader(System.in));

Byte input streamChar tokensLine tokens

try {return inputStream.readLine();

} catch (Exception e) {

System.out.println(e);return 0;

}

Try-Catch Block

Exception Object

Program fragment that can cause exception

Exception Handler

public class AnInputPrinter {

...

}

import java.io.BufferedReader;

public class AnInputPrinter {

….

…...

}

Importing a Package

new BufferedReader(…)

new java.io.BufferedReader(...)

package java.io;

public class BufferedReader {

….

}

short name

full name

Import Declaration

Package declaration makes full class name long

Import declaration allows use of short name

Import all vs. selective import

import java.io.*;

import java.util.*;

• import all classes in java.io

• convenient

• can accidentally import and use undesired classes

• must look at entire code to determine what is imported

• do not know package of imported class

import java.io.BufferedStream;

import java.io.InputStreamReader;

import java.util.Vector;

• requires more typing, specially when a large number of classes are imported (e.g. toolkit)

• accident importation not possible

• class header documents imports

• know package of imported class

Always do selective imports

Integer Input

Integer Inputpackage 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;

}}

}

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 new Integer (inputStream.readLine()).intValue());} 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.

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

ABMISpreadsheetpackage 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);}

}

No static

Declaring Instance Variables

public class ABMISpreadsheet {double height;...double weight; ...public void setWeight(double newWeight) {

weight = newWeight;}

…}

Instance Variables

Missing Code

instance methods Parameter

Instance VariablesABMISpreadsheet Instance

getBMI

InstanceVariables

Body accesses

Belong to all methods of an instance

local variable global variable

setWeight

Parameters

Body

accesses

Belong to a single method

accesses

Outside Access to a Class

public class ABMISpreadsheet {double height;...double weight; ...public double getBMI() {

return weight/(height*height);}

…}

Main or other class

Variables should not be publicBut other classes need their values

outside access

Accessing Instance Variables Via Public Methods

Other class

ABMISpreadsheet Instance

weight height

getBMI()

reads

setWeight()

new Weight

calls

writes

setHeight()

new Height

calls

writes

height

getHeight()

calls

reads

getWeight()

reads

weight calls

Coding the Methods

Other class

ABMISpreadsheet Instance

weight height

setWeight()

new Weight

calls

writes

setHeight()

new Height

calls

writes

height

getHeight()

calls

reads

getWeight()

reads

weight calls

Coding the Methods

Other class

ABMISpreadsheet Instance

weight

setWeight()

new Weight

calls

writes

getWeight()

reads

weight calls

Coding Getter and Setter Methods

other class

ABMISpreadsheet Instance

weight

setWeight()

new Weight

calls

writes

getWeight()

reads

weight calls

public double getWeight() {return weight;

}

public void setWeight(double newWeight) {weight = newWeight;

}

procedure function

returns nothing

Functions vs. Procedurespackage 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 Statementpublic void setHeight(double newHeight) {

height = newHeight;}

newHeight 0

height 0

variables memory

setHeight(1.77)

1.77

1.77

<expression>

LHS RHS

<variable> = code that yields a value

weight

1.75*weight 0.0weight

Propertiespublic 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);}

}

Height

Weight

BMI

public class C {

}

Read-Only and Editable Properties

public T getP() { ...}

Typed, Named Unit of Exported Object State

Name: P

Type: T

Readonlypublic void setP(T newValue) { ...}

Editable

newP

obtainPViolates Bean Conventions

Bean

Conventions for

•humans

•tools

Getter methodSetter method

Properties Classificationpublic 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);}

}

Height

Weight

BMI

Editable

Editable

Read-only

Independent

Independent

Dependent

Read-Only

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);

}

ABMIDriverpublic 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());

}}

Look at the airplane fly.

The fly is bothering me.

Overloading

System.out.println(“****Weight****”);

System.out.println(bmiSpreadsheet.getWeight());

Context of Actual Parameters

Two different words with same name

Two different operations with same name

String

double

public void println (String val) {…}

public void println (double val) {…}

Operation Definitions

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

myPrint(“setWeight called”);

Time flies like an arrow.

public void myPrint (String val) {…}

public void myPrint (String val) {…}

Operation Definitions

Fruit flies like an orange.

Ambiguous Context

double i = read();public double read () {…}

public String read () {…}

Operation Definitions

Return type not part of disambiguating context

String s = read();

String s =read() + read() + read()

String s =reads () +ss reads () + ss reads ()

String s = reads () +sd readd() +ss reads ()

String s =reads () +sd readd() +sd readd ()

String s =reads () +ss reads () + sd reads ()

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 ABMISpreadsheetpackage 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);}

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

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.getBMI(

);

– bmiSpreadsheet.print()

• Users share code

• Program element is passive. Users write code to manipulate it.

• It is parameter to method call:– getBMI(bmiSpreadsheet)

– 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

ABMIDriverpublic 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!

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())

Method Name

Target Object

getBMI()Internal Call

External 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

ABMISpreadsheet

Other class

ABMISpreadsheet Instance

weight height

setWeight()

new Weight

calls

writes

setHeight()

new Height

calls

writes

height

getHeight()

calls

reads

getWeight()

reads

weight calls

reads

getBMI()

AnotherBMISpreadsheet

Other class

ABMISpreadsheet Instance

weight height

setWeight()

new Weight

calls

writes

setHeight()

new Height

calls

writes

height

getHeight()

calls

reads

getWeight()

reads

weight calls

getBMI()

bmi

reads

AnotherBMISpreadsheet

Other class

ABMISpreadsheet Instance

weight height

setWeight()

new Weight

calls

writes

setHeight()

new Height

calls

writes

height

getHeight()

calls

reads

getWeight()

reads

weight calls

getBMI()

bmi

reads

Methods that Changes

Other class

AnotherBMISpreadsheet Instance

weight height

setWeight()

new Weight

calls

writes

setHeight()

new Height

calls

writes

getBMI()

bmi

reads

setWeight()

Other class

AnotherBMISpreadsheet Instance

weight

setWeight()

new Weight

calls

writes

bmi

public void setWeight(double newWeight) {weight = newWeight;bmi = weight / (height*height);

}

setHeight()

Other class

AnotherBMISpreadsheet Instance

height

setHeight()

new Height

calls

writes

bmi

public void setHeight(double newHeight) {height = newHeight;bmi = weight / (height*height);

}

getBMI()

Other class

AnotherBMISpreadsheet Instance

getBMI()

bmi

reads

public double getBMI() {return bmi;

}

Complete Codepackage 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 Classespackage 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 Classespackage 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;}

}

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();

}

package bmipublic class AnotherBMISpreadsheet implements BMISpreadhsheet {

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();

}public double getBMI() {

return bmi;}

}

Implementing an Interface contract

package bmi;public interface BMISpreadsheet {

public double getHeight(); public void setHeight (double newVal); public double getWeight() ;public void setWeight(double newWeight) ;public double getBMI();

}

parameter names never matter to Java

manufactures

Real-World Analogy

AccordSpecification

implements

Interface

AnotherBMISpreadsheet

Instance

AnotherBMISpreadsheet instance of

AnotherBMISpreadsheet

Instance

ABMISpreadsheet instance of

ABMISpreadsheet

Instance

ABMISpreadsheet

InstanceBMISpreadsheet

implements

Using Interface to Classify

BMISpreadsheet

Instance

AnotherBMISpreadsheet instance of

BMISpreadsheet

Instance

ABMISpreadsheet instance of

BMISpreadsheet

Instance

BMISpreadsheet

InstanceBMISpreadsheet

implements

Using Car Specification to Classify

manufactures

AccordSpecification

implements

AccordAccord

AccordAccord

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 classpackage 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.

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;}public void setHeight(double newHeight) {

height = newHeight; }public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight; }public double getBMI() {

return 3245.4}

}

Interface as Syntactic Specification

Syntactic Contract

Bombay Market Index?

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

Interface Required

Pros and cons of two alternativespublic 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 alternativespublic 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 MiserSpace Miser

Space

Time

Space

Time

Time MiserSpace Miser

Time-Space Tradeoff

Relating Interface and Class Names

Class Name:•<Qualifier><Interface> (ABMISpreadsheet, ASpaceEfficientBMISpreadsheet, SpaceEfficientBMISpreadsheet)•<Interface><Qualifier>Impl (BMISpreadsheetImpl, BMISpreadsheetSpaceEfficientImpl)

Interface Name:•<ClassName>Interface (ABMISpreadsheetInterface)

Comments

double bmi; //computed by setWeight and setHeight

Single-line comment

/* recompute dependent properties */bmi = weight / (height*height);

Arbitrary comment

/* This version recalculates the bmi when weight or height change, not when getBMI is called*/public class AnotherBMISpreadsheet {…}

Removing Debugging Code

/*System.out.println(newHeight); // debugging

statement*/

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

double weight; // weight

double bmi; // computed by setWeight() and setHeight()

double weight; Self Commenting

Redundant

Bad Variable Name

Useful Comment

/* * @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 () {

…}

Javadoc TagsJavadoc tags

Improving the Stylepublic 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;bmi = weight/(height*height);

}public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;bmi = weight/(height*height);

}...

bmi = (weight/2.2)/(height * 2.54/100*height*2.54/100);

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 = (weight/2.2)/(height * 2.54/100*height*2.54/100);

}public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;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); }

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

setWeight()

setHeight()getHeight()

getWeight()

getBMI() calculateBMI()computeBMI()

Only Public Methods in Interfacepackage 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() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;bmi = calculateBMI(weight, height);

}public double getBMI() {

return bmi;}double calculateBMI(double weight, double height) {

return weight/ (height*height);}

}

not in 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();

}

Pure Vs Impure FunctionsABMISpreadsheet Instance

getWeight

weight

Body accesses

calculateBMI(77,1.77)

calculateBMI(77,1.77) 24.57

24.57 getWeight()

getWeight()

setWeight(77)

77

71

......setWeight(71)

ABMISpreadsheet Instance

calculateBMI

weight

Body

accesses

height

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

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();

}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

Magic numbers?

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);

}public double getBMI() {

return bmi;}double calculateBMI() {

return (weight/LBS_IN_KG) / (height*CMS_IN_INCH/100*height*CMS_IN_INCH/100);

}}

Improving the Style

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);

}

}

Declaring Named Constants

Initializing Declaration

Un-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);}

}

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);}

}

Accidental or Malicious Modification

Violating Least Privilege

Constant

return (weight/lbsInKg) / (height*cmsInInch/100*height*cmsInInch/100);

return (weight/2.2) / (height*2.54/100*height*2.54/100);

Literals, Named Constants, Constants, Variables

Variable

Literal

return (weight/LBS_IN_KG) / (height*CMS_IN_INCH/100*height*CMS_IN_INCH/100)

Named Constant

Literals Vs Named Constants Vs Variables

Use constants for program values that do not change.– Use named constants for magic numbers

return (weight/2.2) / (height*2.54/100*height*2.54/100);

What is a Magic Number?

return (weight/LBS_IN_KG) / (height*CMS_IN_INCH/100*height*CMS_IN_INCH/100)

Natural Constants

return hoursWorked*hourlyWage + 50;

return hoursWorked*hourlyWage + BONUS;

Human-Created Constant

System.out.println (“Bonus: “ + 50);

• Human-created constant is a magic number.

• Natural constant may be a magic number to some.

What is a magic number?

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) ;}

}

More Code Repetition

Within Same Method and Has Same Value

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) ;}

}

Removing Code Repetition

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;

}

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) ;}

}

Local Vs Global Variable

Violating least privilege

Identifier Scope

• Region of code where the identifier is visible.

• Arbitrary scopes not possible

public class AnotherBMISpreadsheet implements BMISpreadsheet{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();

}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);

}}

Scope

heightInMetres Scope

height Scope

Not a Scope

public class AnotherBMISpreadsheet implements BMISpreadsheet{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();

}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);

}}

Multiple definitions

height Scope

height Scope

Overriding Scopes

• Narrower scope overrides definitions in more general scope

public class AnotherBMISpreadsheet implements BMISpreadsheet{double height, weight, bmi;public double getHeight() {

return height;}...

}

Scope of Public Items getHeight() Scope

ABMISpreadsheetDriver

ABMISpreadsheet

public class ABMISpreadsheet implements BMISpreadsheet {

public double height, weight, bmi;...

}

Non Public Instance Variables

public class ABMISpreadsheetWithPublicVariables {

public double height, weight, bmi;

...

}

Making Instance Variables Public

Other Classes

public class ABMISpreadsheetWithPublicVariables {

public double height, weight;

...

}

Hard to Change Representation

Other Classes

public class ABMISpreadsheetWithPublicVariables {

public double height, weight, bmi;

...

}

Internal constraints violated

Other Classes

bmiSpreadsheet.height = 5.0;

System.out.println (bmiSpreadsheet.bmi);

Do not make instance variables public– Expose them through public methods

Encapsulation Principle

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.

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) ;}

}

Named constant scope

public final double CMS_IN_INCH = 2.54;

Public ConstantsInconsistent value cannot be stored

Implementation Independent

public interface BMISpreadsheet {

}

ABMISpreadsheet AnotherBMISpreadsheet

Declare implementation-independent named constants in interfaces– implementing classes can access them.

Principle

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 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-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; 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 = 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) ;}

}

Initializing all Variables

Instance-independent Instantiationpackage 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 Instantiationpackage bmi;public class ABMISpreadsheet {

double height, weight ;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);}

Combined type and method name

ConstructorSpecial 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 Constructorpackage 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);}

public ABMISpreadsheet() {

}

Inserted In Object Code not in Source Code

Default

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)

class ABMISpreadsheet {double height, weight;static double getBMI() {

return (height*heigh)/weight}

Errors

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.

Y R

.

Solutionpublic 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 Solutionpublic 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

X.

Y R

.

R = sqrt (X2 * Y2)

= arctan (Y/X)

Cartesian Representation

Polar Representation

X = R*cos()

Y = R*sin()

Class: ACartesianPointpublic 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: APolarPointpublic 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 methodpublic 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

Recommended