class variables & methods more on dependencies representation and representation errors...

84
Class Variables & Methods • More on dependencies • Representation and representation errors • Primitive vs. Object Properties • Class Variables/Methods • Primitive vs. Object Types • Simple vs. Structured Types

Post on 20-Dec-2015

227 views

Category:

Documents


0 download

TRANSCRIPT

Class Variables & Methods

• More on dependencies

• Representation and representation errors

• Primitive vs. Object Properties

• Class Variables/Methods

• Primitive vs. Object Types

• Simple vs. Structured Types

Loan Object

Loan vs. BMI

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

Read-Only vs. Editable, Dependent vs. Independent

Editable

Dependent

1-Way vs. 2-Way Dependencies

BMI

Height

Weight

Principle

Monthly Interest

Yearly Interest

Loan Object

Loan Interface

public interface Loan {public int getPrincipal(); public void setPrincipal(int newValue);public int getYearlyInterest(); public void setYearlyInterest(int newVal); public int getMonthlyInterest(); public void setMonthlyInterest(int newVal);

}

A Loan Representation

setYearlyInterest()

setMonthlyInterest()

getYearlyinterest()

setPrincipal() getPrincipal()

getMonthlyInterest()

write read

double principal

Stored vs. Computed

Editable

Dependent

Stored

Computed

Loan Algorithm

setYearlyInterest()

setMonthlyInterest()

getYearlyinterest()

setPrincipal() getPrincipal()

getMonthlyInterest()

write read

F1-1

F2-1

F1

F2

int principal

Setting and Getting Stored Property

setPrincipal() getPrincipal()

public void setPrincipal(int newVal) {principal = newVal;

}

public int getPrincipal(){ return principal;

}

int principal

Getting and Setting Computed Property

setYearlyInterest()

getYearlyinterest()write read

F1-1

F1

public int getYearlyInterest() {

return principal* INTEREST_RATE/100;

}

public void setYearlyInterest(int newVal) {

principal = newVal*100/INTEREST_RATE;

}

int principal

Getting and Setting Computed Property

setMonthlyInterest()

getMonthlyInterest()

F2-1

F2

public int getMonthlyInterest() {

return getYearlyInterest()/12;

}

public void setMonthlyInterest(int newVal) {

principal = setYearlyInterest(newVal*12);

}

int principal

Modified Loan Interface

public interface Loan {public final int INTEREST_RATE = 6;public int getPrincipal(); public void setPrincipal(int newValue);public int getYearlyInterest(); public void setYearlyInterest(int newVal); public int getMonthlyInterest(); public void setMonthlyInterest(int newVal);

}

Middle-Out Programming

Interface

Representation

Algorithm

Class

Another Loan Representation

int yearlyInterest

setYearlyInterest()

setMonthlyInterest()

getYearlyinterest()

setPrincipal() getPrincipal()

getMonthlyInterest()

write read

Conversion Errors with Principal Repn.

No Conversion Errors with YearlyInterest Repn.

Car Loan

House Loan

Total Loan

Principal

Yearly Interest

Monthly Interest

Loan Pair

Car Loan Yearly Interest

Car Loan Monthly Interest

House Loan Principal

Car Loan Principal

...

Primitive vs. Object Properties

Loan Pair

Car Loan Principal

Car Loan Yearly Interest

Car Loan Monthly Interest

House Loan Principal

...

Loan Pair

Car Loan

House Loan

Total Loan

Primitive Properties

Object Properties

Reusing Loan!

Object Types

Primitive types

Primitive vs. Object Types

Types

Classes

ABMISpreadsheet

AnotherBMISpreadsheet

Interfaces

BMISpreadsheet Loan

Stringdouble int

Type = Set of operations

ALoan AnotherLoan

Loan Pair Interface

public interface LoanPair { public Loan getCarLoan(); public void setCarLoan(Loan newValue); public Loan getHouseLoan(); public void setHouseLoan(Loan newValue); public Loan getTotalLoan(); }

Space Efficient Representation

Dependent

Stored

Computed

Car Loan

House Loan

Total Loan

Principal

Yearly Interest

Monthly Interest

Dependent

Independent

Space Efficient Representation

Loan carLoan

setHouseLoan() getHouseLoan()

setCarLoan() getCarLoan()

write read

Loan houseLoan

getTotalLoan()

Getter Method

Loan carLoan

getCarLoan()

public Loan getCarLoan(){ return carLoan;

}

Accessing Uninitialized Object Variable !!

variables memory

Object Variables

Primitive Variables

Default Values for Variables

height 0.0

0.0weight

null

null

carLoan

houseLoanLoan carLoan

Loan houseLoan

double height

double weight

Legal double Values

Illegal Loan values

Invoking methods on null

carLoan.getPrincipal()

• null pointer exception.

• unchecked exception

ObjectEditor Display of Null

Initialization of Object Variables

Loan carLoan = new ALoan()

Loan houseLoan = new AnotherLoan()

ALoanPair

Loan carLoan = new ALoan()

setCarLoan() getCarLoan()

write read

Loan houseLoan = new AnotherLoan()

getTotalLoan()

setHouseLoan() getHouseLoan()

getTotalLoan()

Loan carLoan = new ALoan()

Loan houseLoan = new AnotherLoan()

getTotalLoan()

public Loan getTotalLoan(){ houseLoan + carLoan;

}

Programmer-Defined Add Algorithmpublic Loan add(Loan loan1, Loan loan2) {• // create Loan instance• // set one of its properties to sum of corresponding properties of loan 1 and loan2 • // other properties are dependent and will be set automatically • // return Loan instance}

Programmer-Defined Addpublic Loan add(Loan loan1, Loan loan2) { Loan retVal = new ALoan(); retVal.setPrincipal(loan1.getPrincipal() + loan2.getPrincipal()); return retVal;}

public Loan add(Loan loan1, Loan loan2) { Loan retVal = new ALoan(); retVal.setYearlyInterest(loan1.getYearlyInterest() + loan2.getYearlyInterest()); return retVal;}

public Loan add(Loan loan1, Loan loan2) { Loan retVal = new ALoan(); retVal.setMonthlyInterest(loan1.getMonthlyInterest() + loan2.getMonthlyInterest()); return retVal;}

public Loan add(Loan loan1, Loan loan2) { Loan retVal = new AnotherLoan(); retVal.setPrincipal(loan1.getPrincipal() + loan2.getPrincipal()); return retVal;}

Returning AnotherLoan()

public Loan add(Loan loan1, Loan loan2) { Loan retVal = new AnotherLoan(); retVal.setYearlyInterest(loan1.getYearlyInterest() + loan2.getYearlyInterest()); return retVal;}

public Loan add(Loan loan1, Loan loan2) { Loan retVal = new AnotherLoan(); retVal.setMonthlyInterest(loan1.getMonthlyInterest() + loan2.getMonthlyInterest()); return retVal;}

Other alternativespublic Loan add(Loan loan1, Loan loan2) { Loan retVal = new ALoan(); retVal.setPrincipal(loan1.getPrincipal() + loan2.getPrincipal()); return retVal;}

public Loan add(Loan loan1, Loan loan2) { return new ALoan(loan1.getPrincipal() + loan2.getPrincipal()));}

Instance vs. Class operation

public Loan add(Loan loan1, Loan loan2) { return new ALoan(loan1.getPrincipal() + loan2.getPrincipal()));}

Operation on an instance?

Should be class operation

Real-World Analogy

new AnAccord(beige)

new AnAccord(grey)

getMileage()

64000blend(beigeCar, greyCar)

numCarsProduced()101234

O-O Word

new ALoan(10000)

new ALoan(100000)

getPrincipal()

100000

ALoancarLoan

houseLoan

add(carLoan, totalLoan)

totalLoan

numInstances()

3

Class Methods

• Methods can be invoked on class itself.

• Called class or static methods

• Declared in class on which they are invoked.

• Keyword static in header.

• Accesses no instance variable.

• Header cannot appear in interface.

Programmer-Defined Add

public static Loan add(Loan loan1, Loan loan2) { return new ALoan(loan1.getPrincipal() + loan2.getPrincipal()));}

public Loan getTotalLoan(){

return ALoan.add (houseLoan, carLoan);

}

Accesses instance variables

Instance Method

Class Method

Accesses no instance variable

External Call of Class Method

ALoan.add(carLoan, houseLoan)

Class as target

Math.round(5.7)

numInstances() Algorithm

Declare variable, numInstances initialized to zero

Increment numInstances each time a new instance is created

getNumLoans() returns numInstances

returning numLoans

getNumLoans() returns numInstances

public static int getNumLoans() {

return numInstances;

}

Incrementing getNumLoans (edit)

Increment numInstances each time a new instance is created

???

Incrementing getNumLoans (edited)

Increment numInstances each time a new instance is created

Public Aloan() {

numInstances++

}

Incrementing getNumLoans (soln)

Increment numInstances each time a new instance is created

public ALoan(int initPrincipal) { setPrincipal(initPrincipal); numInstances = numInstances + 1;}

Declaring numInstances

Declare variable, numInstances initialized to zero

int numInstances = 0; // instance variable

1

memory

Loan Object

int numInstances = 0;

public ALoan(int initPrincipal) { setPrincipal(initPrincipal); numInstances = numInstances + 1;}

0principal

0numInstances

0principal

0numInstances 1

10000

15000

1

memory

Loan Object

static int numInstances = 0;

public ALoan(int initPrincipal) { setPrincipal(initPrincipal); numInstances = numInstances + 1;}

0numInstances

0principal 10000

1

0principal 5000

2

Instance Vs Class Members

• Class Members– Class methods

– Class variables

• Instance Members– Instance methods

– Instance variables

Scope of Class and Instance Members

• Class Members– visible to other class

members

– visible to all instance members

• class & instance methods can access class variables

• class and instance methods can call class methods

• Instance Members– visible to other

instance members

– not visible to class members

• which of (zero to many) copies of an instance variable should a class member refer to?

public static int getNumLoans() {

System.out.println(principal);

return numInstances;

}

Legal & Illegal Accesses

static int numInstances = 0;

public ALoan(int initPrincipal) { setPrincipal(initPrincipal); numInstances = numInstances + 1; System.out.println(getNumLoans());}

int principal;

public setPrincipal(int newPrincipal) { principal = newPrincipal; }

Class vs. Instance Constant

• Should be class constant– guaranteed to have one copy– easy to refer (require no instance creation)– Class methods can refer to it.

• Unless some good reason for hiding named constants from class methods

Class vs. Instance Methods

public static Loan add(Loan loan1, Loan loan2) { return new ALoan(loan1.getPrincipal() + loan2.getPrincipal()));}

Class Method

Accesses no instance variable

public Loan add(Loan loan1, Loan loan2) { return new ALoan(loan1.getPrincipal() + loan2.getPrincipal()));}

Instance Method

ALoan.add(carLoan, houseLoan)

Math.round(5.7)

(new ALoan).add(carLoan, houseLoan)

(new Math).round(5.7)

Class vs. Instance Method• Instance method has all the privileges of a class

method.• Any class method can be made an instance method.• Should not have instance method that does not

access any instance variable.– They belong to the class.

– Violate least privilege principle.

– Require needless instantiation.

• But instance method can be put in interfaces• Tradeoff!

ACourseFactory

package factories;import courseTree.RegularCourse;import courseTree.FreshmanSeminar;import courseTree.ARegularCourse;import courseTree.AFreshmanSeminar;public class ACourseFactory implements CourseFactory {

public RegularCourse getRegularCourse() {return new ARegularCourse();

}public FreshmanSeminar getFreshmanSeminar() {

return new AFreshmanSeminar();}

}

No instance variables accessed.

ACourseFactory with class methods

package factories;import courseTree.RegularCourse;import courseTree.FreshmanSeminar;import courseTree.ARegularCourse;import courseTree.AFreshmanSeminar;public class ACourseFactory {

public static RegularCourse getRegularCourse() {return new ARegularCourse();

}public static FreshmanSeminar getFreshmanSeminar()

{return new AFreshmanSeminar();

}}

ACourseFactory.getRegularCourse(); (new ACourseFactory).getRegularCourse();

No interface

ALoggedCourseFactory with class methods

package factories;import courseTree.RegularCourse;import courseTree.FreshmanSeminar;import courseTree.ALoggedRegularCourse;import courseTree.ALoggedFreshmanSeminar;public class ALoggedCourseFactory {

public static RegularCourse getRegularCourse() {return new ALoggedRegularCourse();

}public static FreshmanSeminar getFreshmanSeminar() {

return new ALoggedFreshmanSeminar();}

}

Cannot substitute factories

void fillCourses() { CourseFactory courseFactory = (new ACourseFactorySelector()).getCourseFactory(); CourseList prog = new ACourseList(); RegularCourse introProg = courseFactory.getRegularCourse (); introProg.init("Intro. Prog.", "COMP", 14); …}

Resolving tradeoff

• Create instance methods when substitution expected.

• Hard to dream of situation when not.– Factory selector class?

Factory Selector Class

package factories;public class ACourseFactorySelector implements CourseFactorySelector {

public static CourseFactory getCourseFactory() {return new ALoggedCourseFactory();

}}

Class with only static methods?

• Math.– round(), power(),

• Console– Converts various

input strings to primitive types.

readInt()

readDouble()

readBoolean()

readChar()

Console

readString()

Separate Class for Inputimport java.io.BufferedReader;import java.io.InputStreamReader;public class Console { 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 String readString() {

try {return inputStream.readLine();

} catch (Exception e) {System.out.println(e);return "";

} } ... //other methods}

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

} }}

Using Console

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: " + Console.readString()); }}

Object Types

Primitive types

Primitive vs. Object Types

Types

Classes

ABMISpreadsheet

AnotherBMISpreadsheet

Interfaces

BMISpreadsheet Loan

Stringdouble int

Type = Set of operations

ALoan AnotherLoan

Primitive vs. Object Types

• Object types– Classes– Interfaces– Names start with upper case letter

• Primitive types– int, double, float, boolean, …– Names start with lower case letter

• Other ways to classify types?

Programmer-defined

Predefined

Predefined vs. Programmer-defined Types

Types

Classes

ABMISpreadsheet

AnotherBMISpreadsheet

Interfaces

BMISpreadsheet Loan

String

double int

ALoan AnotherLoan

Programmer-defined vs. Predefined Types

• Programmer-defined interface/class (Loan/ALoan) is programmer-defined type.

• Programmer-defined types in Java must be object types

• Some object types are predefined (String)

• All primitive types are predefined.

Structure Types

Atomic types

Structure vs. Atomic Types

Types

Classes

ABMISpreadsheet

AnotherBMISpreadsheet

Interfaces

BMISpreadsheet Loan

Stringdouble int

ALoan AnotherLoan

Instances of structure type decomposed into one or more smaller values

AnExpressionStartAnExpressionEnd

Structure vs. Atomic Types

• Atomic type cannot be decomposed.

• Structure types have one or more “components”.

Loan Interface

public interface Loan {public int getPrincipal(); public void setPrincipal(int newValue);public int getYearlyInterest(); public void setYearlyInterest(int newVal); public int getMonthlyInterest(); public void setMonthlyInterest(int newVal);

}

A Loan Representation

setYearlyInterest()

setMonthlyInterest()

getYearlyinterest()

setPrincipal() getPrincipal()

getMonthlyInterest()

write read

double principal

Another Loan Representation

int yearlyInterest

setYearlyInterest()

setMonthlyInterest()

getYearlyinterest()

setPrincipal() getPrincipal()

getMonthlyInterest()

write read

Physical vs. Logical Structure

ALoan instance

doubleprincipal

ALoan instance

doublePrincipal

Yearly Interest

Monthly Interest

double

double

Physical

Logical

Loan Pair Interface

public interface LoanPair { public Loan getCarLoan(); public void setCarLoan(Loan newValue); public Loan getHouseLoan(); public void setHouseLoan(Loan newValue); public Loan getTotalLoan(); }

ALoanPair

Loan carLoan = new ALoan()

setCarLoan() getCarLoan()

write read

Loan houseLoan = new AnotherLoan()

getTotalLoan()

setHouseLoan() getHouseLoan()

Physical vs. Logical Structure

ALoan doubleprincipal

Loan

doublePrincipal

Yearly Interest

Monthly Interest

double

double

Physical

Logical

ALoanPair Instance

carLoan

houseLoanyearlyInterest

AnotherLoan double

ALoanPair Instance

CarLoan

Loan

HouseLoan

TotalLoan

Loan

Variable Name

Class/primitive type of value stored in Variable

Property Name

Property Type

Physical vs. Logical

• Physical describes internal (in-memory) state of object.

• Logical describes external (exported) state of object.

Loan Pair Variation

public interface LoanPair { public int getCarLoanMonthlyInterest(); public void setCarLoanMonthlyInterest(int newValue); public int getHouseLoanMonthlyInterest(); public void setHouseLoanMonthlyInterest(int newValue); public Loan getTotalLoan (); }

ALoanPair Variation

Loan carLoan = new ALoan()

setCarLoanMonthlyInterest() getCarLoanMonthlyInterest()

write read

Loan houseLoan = new AnotherLoan()

getTotalLoan()

setHouseLoanMonthlyIntetest() getHouseLoanMonthlyInterest()

Physical vs. Logical Structure

ALoan doubleprincipal

Loan

doublePrincipal

Yearly Interest

Monthly Interest

double

double

Physical

Logical

ALoanPair Instance

carLoan

houseLoanyearlyInterest

AnotherLoan double

ALoanPair Instance

TotalLoan

int

HouseLoan MonthlyInterest

CarLoanMonthlyInterest

int

Hierarchical Structures• int/double

– Atomic

• Loan/ALoan– Properties/variables are atomic

• LoanPair/ALoanPair– Properties/variables are themselves structured.

• Multi-level structure– Property can be atomic or structured

• Infinite-level structure– Descendent of type T can be of type T itself– Tree