Upload
dodiep
View
217
Download
1
Embed Size (px)
Citation preview
115-214
SchoolofComputerScience
PrinciplesofSoftwareConstruction:Objects,Design,andConcurrency
Object-OrientedProgramminginJava
JoshBloch CharlieGarrod
215-214
Administrivia
• FirsthomeworkduethisThursday,11:59PM
315-214
KeyconceptsfromTuesday
• Bipartitetypesystem– primitives&objectrefs– Singleimplementationinheritance–Multipleinterfaceinheritance
• Easiestoutput– println ,printf• Easiestinput– Commandlineargs,Scanner• Collectionsframeworkispowerful&easytouse
415-214
Collectionsusageexample3UnfinishedbusinessfromlastlecturePrintindexoffirstoccurrenceofeachwordclass Index {
public static void main(String[] args) {Map<String, Integer> index = new TreeMap<>();
// Iterate backwards so first occurrence winsfor (int i = args.length - 1; i >= 0; i--) {
index.put(args[i], i);}System.out.println(index);
}}
$ java Index if it is to be it is up to me to do it{be=4, do=11, if=0, is=2, it=1, me=9, to=3, up=7}
515-214
Outline
I. Object-orientedprogrammingbasicsII. InformationhidingIII. Exceptions
615-214
Objects
• Anobject isabundleofstateandbehavior• State– thedatacontainedintheobject– InJava,thesearethefields oftheobject
• Behavior– theactionssupportedbytheobject– InJava,thesearecalledmethods–MethodisjustOO-speakforfunction– invokeamethod=callafunction
715-214
Classes
• Everyobjecthasaclass– Aclassdefinesmethodsandfields–Methodsandfieldscollectivelyknownasmembers
• Classdefinesbothtypeandimplementation– type≈wheretheobjectcanbeused– implementation≈howtheobjectdoesthings
• Looselyspeaking,themethodsofaclassareitsApplicationProgrammingInterface(API)– Defineshowusersinteractwithinstances
815-214
Classexample– complexnumbersclass Complex {private double re; // Real Partprivate double im; // Imaginary Part
public Complex(double re, double im) {this.re = re;this.im = im;
}
public double realPart() { return re; }public double imaginaryPart() { return im; }public double r() { return Math.sqrt(re * re + im * im); }public double theta() { return Math.atan(im / re); }
public Complex add(Complex c) {return new Complex(re + c.re, im + c.im);
}public Complex subtract(Complex c) { ... }public Complex multiply(Complex c) { ... }public Complex divide(Complex c) { ... }
}
915-214
Classusageexample
public class ComplexUser {public static void main(String args[]) {
Complex c = new Complex(-1, 0);Complex d = new Complex(0, 1);
Complex e = c.plus(d);System.out.println(e.realPart() + " + "
+ e.imaginaryPart() + "i");e = c.times(d);System.out.println(e.realPart() + " + "
+ e.imaginaryPart() + "i");}
}
Whenyourunthisprogram,itprints-1.0 + 1.0i-0.0 + -1.0i
1015-214
Interfacesandimplementations
• MultipleimplementationsofAPIcancoexist–MultipleclassescanimplementthesameAPI– Theycandifferinperformanceandbehavior
• InJava,anAPIisspecifiedbyinterfaceorclass– InterfaceprovidesonlyanAPI– ClassprovidesanAPIandanimplementation– AClasscanimplementmultipleinterfaces
1115-214
Aninterfacetogowithourclass
public interface Complex {// No constructors, fields, or implementations!
double realPart();double imaginaryPart();double r();double theta();
Complex plus(Complex c);Complex minus(Complex c);Complex times(Complex c);Complex dividedBy(Complex c);
}
AninterfacedefinesbutdoesnotimplementAPI
1215-214
Modifyingclasstouseinterfaceclass OrdinaryComplex implements Complex {double re; // Real Partdouble im; // Imaginary Part
public OrdinaryComplex(double re, double im) {this.re = re;this.im = im;
}
public double realPart() { return re; }public double imaginaryPart() { return im; }public double r() { return Math.sqrt(re * re + im * im); }public double theta() { return Math.atan(im / re); }
public Complex add(Complex c) {return new OrdinaryComplex(re + c.realPart(), im + c.imaginaryPart());
}public Complex subtract(Complex c) { ... }public Complex multiply(Complex c) { ... }public Complex divide(Complex c) { ... }
}
1315-214
Modifyingclienttouseinterfacepublic class ComplexUser {
public static void main(String args[]) {Complex c = new OrdinaryComplex(-1, 0);Complex d = new OrdinaryComplex(0, 1);
Complex e = c.plus(d);System.out.println(e.realPart() + " + "
+ e.imaginaryPart() + "i");e = c.times(d);System.out.println(e.realPart() + " + "
+ e.imaginaryPart() + "i");}
}
Whenyourunthisprogram,itstillprints-1.0 + 1.0i-0.0 + -1.0i
1415-214
Interfacepermitsmultipleimplementations
class PolarComplex implements Complex {double r;double theta;
public PolarComplex(double r, double theta) {this.r = r;this.theta = theta;
}
public double realPart() { return r * Math.cos(theta) ; }public double imaginaryPart() { return r * Math.sin(theta) ; }public double r() { return r; }public double theta() { return theta; }
public Complex plus(Complex c) { ... } // Completely different implspublic Complex minus(Complex c) { ... }public Complex times(Complex c) { ... }public Complex dividedBy(Complex c) { ... }
}
1515-214
Interfacedecouplesclientfromimplementation
public class ComplexUser {public static void main(String args[]) {
Complex c = new PolarComplex(Math.PI, 1); // -1Complex d = new PolarComplex(Math.PI/2, 1); // i
Complex e = c.plus(d);System.out.println(e.realPart() + " + "
+ e.imaginaryPart() + "i");e = c.times(d);System.out.println(e.realPart() + " + "
+ e.imaginaryPart() + "i");}
}
Whenyourunthisprogram,itSTILL prints-1.0 + 1.0i-0.0 + -1.0i
1615-214
Whymultipleimplementations?
• Differentperformance– Chooseimplementationthatworksbestforyouruse
• Differentbehavior– Chooseimplementationthatdoeswhatyouwant– Behaviormust complywithinterfacespec(“contract”)
• Oftenperformanceandbehaviorboth vary– Providesafunctionality– performancetradeoff– Example:HashSet,TreeSet
1715-214
Javainterfacesandclasses
• Organizeprogramprogramobjectstypes– Eachtypeoffersaspecificsetofoperations– Objectsareotherwiseopaque
• Interfacesvs.classes– Interface:specifiesexpectations– Class:deliversonexpectations(theimplementation)
1815-214
Classesastypes
• Classesdo definetypes– Publicclassmethodsusablelikeinterfacemethods– Publicfieldsdirectlyaccessiblefromotherclasses
• Butprefertheuseofinterfaces– Useinterfacetypesforvariablesandparametersunlessyouknowoneimplementationwillsuffice• Supportschangeofimplementation• Preventsdependenceonimplementationdetails
Set<Criminal> senate = new HashSet<>(); // Do this…HashSet<Criminal> senate = new HashSet<>(); // Not this
1915-214
Checkyourunderstandinginterface Animal {
void vocalize();}class Dog implements Animal {
public void vocalize() { System.out.println("Woof!"); }}class Cow implements Animal {
public void vocalize() { moo(); }public void moo() {System.out.println("Moo!"); }
}
WhatHappens?1. Animal a = new Animal();
a. vocalize();2. Dog d = new Dog();
d.vocalize();3. Animal b = new Cow();
b.vocalize();4. b.moo();
2015-214
Historicalnote:simulationandtheoriginsofOOprogramming• Simula 67wasthefirst object-orientedlanguage
• DevelopedbyKristinNygaard andOle-JohanDahlattheNorwegianComputingCenter
• Developedtosupportdiscrete-eventsimulation– Application:operationsresearch,e.g.trafficanalysis– Extensibilitywasakeyqualityattributeforthem– Codereusewasanother
2115-214
Outline
I. Object-orientedprogrammingbasicsII. InformationhidingIII. Exceptions
2215-214
Informationhiding
• Singlemostimportantfactorthatdistinguishesawell-designedmodulefromabadoneisthedegreetowhichithidesinternaldataandotherimplementationdetailsfromothermodules
• Well-designedcodehidesall implementationdetails– CleanlyseparatesAPIfromimplementation–Modulescommunicateonly throughAPIs– Theareoblivioustoeachothers’innerworkings
• Knownasinformationhidingorencapsulation• Fundamentaltenetofsoftwaredesign[Parnas,‘72]
2315-214
Benefitsofinformationhiding
• Decouples theclassesthatcompriseasystem– Allowsthemtobedeveloped,tested,optimized,used,understood,andmodifiedinisolation
• Speedsupsystemdevelopment– Classescanbedevelopedinparallel
• Easesburdenofmaintenance– Classescanbeunderstoodmorequicklyanddebuggedwithlittlefearofharmingothermodules
• Enableseffectiveperformancetuning– “Hot”classescanbeoptimizedinisolation
• Increasessoftwarereuse– Loosely-coupledclassesoftenproveusefulinothercontexts
2415-214
Informationhidingwithinterfaces
• Declarevariablesusinginterfacetype• Clientcanuseonlyinterfacemethods• Fieldsnotaccessiblefromclientcode• Butthisonlytakesussofar– Clientcanaccessnon-interfacemembersdirectly– Inessence,it’svoluntary informationhiding
2515-214
MandatoryInformationhidingvisibilitymodifiers formembers
• private – Accessibleonly fromdeclaringclass• package-private – Accessiblefromanyclassinthepackagewhereitisdeclared– Technicallyknownasdefaultaccess– Yougetthisifnoaccessmodifierisspecified
• protected – Accessiblefromsubclassesofdeclaringclass(andwithinpackage)
• public – Accessiblefromanywhere
2615-214
HidinginteriorstateinOrdinaryComplex
class OrdinaryComplex implements Complex {private double re; // Real Partprivate double im; // Imaginary Part
public OrdinaryComplex(double re, double im) {this.re = re;this.im = im;
}
public double realPart() { return re; }public double imaginaryPart() { return im; }public double r() { return Math.sqrt(re * re + im * im); }public double theta() { return Math.atan(im / re); }
public Complex add(Complex c) {return new OrdinaryComplex(re + c.realPart(), im + c.imaginaryPart());
}public Complex subtract(Complex c) { ... }public Complex multiply(Complex c) { ... }public Complex divide(Complex c) { ... }
}
2715-214
Discussion
• Youknowthebenefitsofprivatefields• Whatarethebenefitsofprivatemethods?
2815-214
Bestpracticesforinformationhiding
• CarefullydesignyourAPI• Provideonly functionalityrequiredbyclients– All othermembersshouldbeprivate
• Youcanalwaysmakeaprivatememberpubliclaterwithoutbreakingclients– Butnotvice-versa!
2915-214
Outline
I. Object-orientedprogrammingbasicsII. InformationhidingIII. Exceptions
3015-214
Whatdoesthiscodedo?FileInputStream fIn = new FileInputStream(fileName);if (fIn == null) {switch (errno) {case _ENOFILE:
System.err.println(“File not found: “ + …);return -1;
default:System.err.println(“Something else bad happened: “ + …);return -1;
}}DataInput dataInput = new DataInputStream(fIn);if (dataInput == null) {System.err.println(“Unknown internal error.”);return -1; // errno > 0 set by new DataInputStream
}int i = dataInput.readInt();if (errno > 0) {System.err.println(“Error reading binary data from file”);return -1;
} // The Slide lacks space to close the file. Oh well.return i;
3115-214
Whatdoesthiscodedo?FileInputStream fIn = new FileInputStream(fileName);if (fIn == null) {switch (errno) {case _ENOFILE:
System.err.println(“File not found: “ + …);return -1;
default:System.err.println(“Something else bad happened: “ + …);return -1;
}}DataInput dataInput = new DataInputStream(fIn);if (dataInput == null) {System.err.println(“Unknown internal error.”);return -1; // errno > 0 set by new DataInputStream
}int i = dataInput.readInt();if (errno > 0) {System.err.println(“Error reading binary data from file”);return -1;
} // The Slide lacks space to close the file. Oh well.return i;
3215-214
Compareto:
FileInputStream fileInput = null; try {
fileInput = new FileInputStream(fileName);DataInput dataInput = new DataInputStream(fileInput);return dataInput.readInt();
} catch (FileNotFoundException e) {System.out.println("Could not open file " + fileName);
} catch (IOException e) {System.out.println("Couldn’t read file: " + e);
} finally {if (fileInput != null) fileInput.close();
}
3315-214
Exceptions
• Notifythecallerofanexceptionalconditionbyautomatictransferofcontrol
• Semantics:– Propagatesupstackuntilmainmethodisreached(terminatesprogram),orexceptioniscaught
• Sources:– Program– e.g.,IllegalArgumentException– JVM– e.g.,StackOverflowError
3415-214
Control-flowofexceptionspublic static void test() {
try {System.out.println("Top");int[] a = new int[10];a[42] = 42;System.out.println("Bottom");
} catch (NegativeArraySizeException e) {System.out.println("Caught negative array size");
}}
public static void main(String[] args) {try {
test();} catch (IndexOutOfBoundsException e) {
System.out.println"("Caught index out of bounds");}
}
3515-214
Checkedvs.uncheckedexceptions
• Checkedexception–Mustbecaughtorpropagated,orprogramwon’tcompile
• Uncheckedexception– Noactionisrequiredforprogramtocompile– Butuncaughtexceptionwillcauseprogramtofail!
3615-214
TheexceptionhierarchyinJava
Throwable
Exception
RuntimeException IOException
EOFException
FileNotFoundException
NullPointerException
IndexOutOfBoundsException
ClassNotFoundException… …
. . .
Object
Error
3715-214
Designchoice:checkedanduncheckedexceptionsandreturnvalues
• Uncheckedexception– Programmingerror,otherunrecoverablefailure
• Checkedexception– Anerrorthateverycallershouldbeawareofandhandle
• Specialreturnvalue(e.g.,null fromMap.get)– Commonbutatypicalresult
• DoNOTusereturncodes• NEVERreturnnull toindicateazero-lengthresult– Useazero-lengthlistorarrayinstead
3815-214
Creatingandthrowingyourownexceptionspublic class SpanishInquisitionException extends RuntimeException {
public SpanishInquisitionException() {}
}
public class HolyGrail {public void seek() {
...if (heresyByWord() || heresyByDeed())
throw new SpanishInquisitionException();...
}}
3915-214
Benefitsofexceptions
• Youcan’tforgettohandlecommonfailuremodes– Compare:usingaflagorspecialreturnvalue
• Providehigh-levelsummaryoferror,andstacktrace– Compare:coredumpinC
• Improvecodestructure– Separatenormalcodepathfromexceptional– Easetaskofrecoveringfromfailure
• Easetaskofwritingrobust,maintainablecode
4015-214
Guidelinesforusingexceptions(1)
• Avoidunnecessarycheckedexceptions(EJItem59)• Favorstandardexceptions(EJItem60)– IllegalArgumentException – invalidparametervalue– IllegalStateException – invalidobjectstate– NullPointerException – nullparamwhereprohibited– IndexOutOfBoundsException – invalidindexparam
• Throwexceptionsappropriatetoabstraction(EJItem61)
4115-214
Guidelinesforusingexceptions(2)
• Documentallexceptionsthrownbyeachmethod– Checkedandunchecked(EJItem62)– Butdon’tdeclare uncheckedexceptions!
• Includefailure-captureinfoindetailmessage(Item63)– throw new IlegalArgumentException(
"Modulus must be prime: " + modulus);
• Don’tignoreexceptions(EJItem65)// Empty catch block IGNORES exception – Bad smell in code!try {
...} catch (SomeException e) { }
4215-214
Rememberthisslide?Youcandomuchbetter!
FileInputStream fileInput = null; try {
FileInputStream fileInput = new FileInputStream(fileName);DataInput dataInput = new DataInputStream(fileInput);return dataInput.readInt();
} catch (FileNotFoundException e) {System.out.println("Could not open file " + fileName);
} catch (IOException e) {System.out.println("Couldn’t read file: " + e);
} finally {if (fileInput != null) fileInput.close();
}
4315-214
Manualresourceterminationisuglyanderrorprone• Evengoodprogrammersusuallygetitwrong– Sun’sguidetoPersistentConnectionsgotitwrongincodethatclaimedtobeexemplary
– Solutiononpage88ofBlochandGafter’s JavaPuzzlersisbadlybroken;noonenoticedforyears
• 70%oftheusesoftheclosemethodintheJDKitselfwerewrongin2008(!)
• Even“correct”idiomsformanualresourcemanagementaredeficient
43
4415-214
Thesolution:try-with-resourcesAutomaticallyclosesresources
try (DataInput dataInput = new DataInputStream(new FileInputStream(fileName))) {
return dataInput.readInt();} catch (FileNotFoundException e) {
System.out.println("Could not open file " + fileName);} catch (IOException e) {
System.out.println("Couldn’t read file: " + e);}
4515-214
FilecopywithoutARM
static void copy(String src, String dest) throws IOException {InputStream in = new FileInputStream(src);try {
OutputStream out = new FileOutputStream(dest);try {
byte[] buf = new byte[8 * 1024];int n;while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);} finally {
out.close();}
} finally {in.close();
}}
}45
4615-214
FilecopywithARM
static void copy(String src, String dest) throws IOException {try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest)) {byte[] buf = new byte[8 * 1024];int n;while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);}
}
46
4715-214
Summary
• Interfaces-baseddesignshandlechangewell• Informationhidingiscrucialtogooddesign• Exceptionsarewaybetterthanerrorcodes• Theneedforcheckedexceptionsisrare• Try-with-resources(ARMblock)isawin