class variables & methods more on dependencies representation and representation errors...
Post on 20-Dec-2015
227 views
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
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
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
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);
}
Another Loan Representation
int yearlyInterest
setYearlyInterest()
setMonthlyInterest()
getYearlyinterest()
setPrincipal() getPrincipal()
getMonthlyInterest()
write read
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
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
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 (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