03-object-oriented programming in java

48
1 17-214 Principles of Software Construction: Objects, Design, and Concurrency Object-Oriented Programming in Java Josh Bloch Charlie Garrod Darya Melicher

Upload: others

Post on 29-Dec-2021

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 03-Object-oriented programming in java

117-214

PrinciplesofSoftwareConstruction:Objects,Design,andConcurrency

Object-OrientedProgramminginJava

JoshBlochCharlieGarrod DaryaMelicher

Page 2: 03-Object-oriented programming in java

217-214

Administrivia

• Homework1dueThursday11:59p.m.– Everyonemustreadandsignourcollaborationpolicy

• FirstreadingassignmentdueTuesday– EffectiveJavaItems15and16

Page 3: 03-Object-oriented programming in java

317-214

KeyconceptsfromThursday

• Bipartitetypesystem– primitives&objectrefs– Singleimplementationinheritance–Multipleinterfaceinheritance

• Easiestoutput– println ,printf• Easiestinput– Commandlineargs,Scanner• Collectionsframeworkispowerful&easytouse

Page 4: 03-Object-oriented programming in java

417-214

Outline

I. Object-orientedprogrammingbasicsII. InformationhidingIII. Exceptions

Page 5: 03-Object-oriented programming in java

517-214

Objects

• Anobject isabundleofstateandbehavior• State– thedatacontainedintheobject– InJava,thesearethefields oftheobject

• Behavior– theactionssupportedbytheobject– InJava,thesearecalledmethods–MethodisjustOO-speakforfunction– Invokeamethod=callafunction

Page 6: 03-Object-oriented programming in java

617-214

Classes

• Everyobjecthasaclass– Aclassdefinesmethodsandfields–Methodsandfieldscollectivelyknownasmembers

• Classdefinesbothtypeandimplementation– Type≈wheretheobjectcanbeused– Implementation≈howtheobjectdoesthings

• Looselyspeaking,themethodsofaclassareitsApplicationProgrammingInterface(API)– Defineshowusersinteractwithinstances

Page 7: 03-Object-oriented programming in java

717-214

Classexample– complexnumbersclass Complex {private final double re; // Real Partprivate final 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) { ... }

}

Page 8: 03-Object-oriented programming in java

817-214

Classusageexamplepublic 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

Page 9: 03-Object-oriented programming in java

917-214

Interfacesandimplementations

• MultipleimplementationsofAPIcancoexist–MultipleclassescanimplementthesameAPI– Theycandifferinperformanceandbehavior

• InJava,anAPIisspecifiedbyinterfaceorclass– InterfaceprovidesonlyanAPI– ClassprovidesanAPIandanimplementation– Aclasscanimplementmultipleinterfaces

Page 10: 03-Object-oriented programming in java

1017-214

Aninterfacetogowithourclasspublic 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

Page 11: 03-Object-oriented programming in java

1117-214

Modifyingclasstouseinterface

class OrdinaryComplex implements Complex {final double re; // Real Partfinal 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) { ... }

}

Page 12: 03-Object-oriented programming in java

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

Page 13: 03-Object-oriented programming in java

1317-214

Interfacepermitsmultipleimplementations

class PolarComplex implements Complex {final double r;final 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) { ... }

}

Page 14: 03-Object-oriented programming in java

1417-214

Interfacedecouplesclientfromimplementationpublic 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

Page 15: 03-Object-oriented programming in java

1517-214

Whymultipleimplementations?

• Differentperformance– Chooseimplementationthatworksbestforyouruse

• Differentbehavior– Chooseimplementationthatdoeswhatyouwant– Behaviormust complywithinterfacespec(“contract”)

• Oftenperformanceandbehaviorboth vary– Providesafunctionality– performancetradeoff– Example:HashSet,TreeSet

Page 16: 03-Object-oriented programming in java

1617-214

Javainterfacesandclasses

• Atypedefinesafamilyofobjects– Eachtypeoffersaspecificsetofoperations– Objectsareotherwiseopaque

• Interfacesvs.classes– Interface:specifiesexpectations– Class:deliversonexpectations(theimplementation)

Page 17: 03-Object-oriented programming in java

1717-214

Classesastypes

• Classesdo definetypes– Publicclassmethodsusablelikeinterfacemethods– Publicfieldsdirectlyaccessiblefromotherclasses

• Butgenerallyprefertheuseofinterfaces– Useinterfacetypesforvariablesandparametersunlessyouknowasingleimplementationwillsuffice• Supportschangeofimplementation• Preventsdependenceonimplementationdetails

Set<Criminal> senate = new HashSet<>(); // Do this…HashSet<Criminal> senate = new HashSet<>(); // Not this

Page 18: 03-Object-oriented programming in java

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

Page 19: 03-Object-oriented programming in java

1917-214

Historicalnote:simulationandtheoriginsofOOprogramming• Simula 67wasthefirst object-orientedlanguage

• DevelopedbyKristinNygaard andOle-JohanDahlattheNorwegianComputingCenter

• Developedtosupportdiscrete-eventsimulation– Application:operationsresearch,e.g.trafficanalysis– Extensibilitywasakeyqualityattributeforthem– Codereusewasanother

Page 20: 03-Object-oriented programming in java

2017-214

Outline

I. Object-orientedprogrammingbasicsII. InformationhidingIII. Exceptions

Page 21: 03-Object-oriented programming in java

2117-214

Informationhiding

• Singlemostimportantfactorthatdistinguishesawell-designedmodulefromabadoneisthedegreetowhichithidesinternaldataandotherimplementationdetailsfromothermodules

• Well-designedcodehidesall implementationdetails– CleanlyseparatesAPIfromimplementation–Modulescommunicateonly throughAPIs– Theyareoblivioustoeachothers’innerworkings

• Knownasinformationhidingorencapsulation• Fundamentaltenetofsoftwaredesign[Parnas,‘72]

Page 22: 03-Object-oriented programming in java

2217-214

Benefitsofinformationhiding

• Decouples theclassesthatcompriseasystem– Allowsthemtobedeveloped,tested,optimized,used,understood,andmodifiedinisolation

• Speedsupsystemdevelopment– Classescanbedevelopedinparallel

• Easesburdenofmaintenance– Classescanbeunderstoodmorequicklyanddebuggedwithlittlefearofharmingothermodules

• Enableseffectiveperformancetuning– “Hot”classescanbeoptimizedinisolation

• Increasessoftwarereuse– Loosely-coupledclassesoftenproveusefulinothercontexts

Page 23: 03-Object-oriented programming in java

2317-214

Informationhidingwithinterfaces

• Declarevariablesusinginterfacetypes• Clientcanuseonlyinterfacemethods• Fieldsnotaccessiblefromclientcode• Butthisonlytakesussofar– Clientcanaccessnon-interfacemembersdirectly– Inessence,it’svoluntaryinformationhiding

Page 24: 03-Object-oriented programming in java

2417-214

MandatoryInformationhidingvisibilitymodifiers formembers• private – Accessibleonly fromdeclaringclass• package-private – Accessiblefromanyclassinthepackagewhereitisdeclared– Technicallyknownasdefaultaccess– Yougetthisifnoaccessmodifierisspecified

• protected – Accessiblefromsubclassesofdeclaringclass(andwithinpackage)

• public – Accessiblefromanywhere

Page 25: 03-Object-oriented programming in java

2517-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) { ... }

}

Page 26: 03-Object-oriented programming in java

2617-214

Discussion

• Youknowthebenefitsofprivatefields• Whatarethebenefitsofprivatemethods?

Page 27: 03-Object-oriented programming in java

2717-214

Bestpracticesforinformationhiding

• CarefullydesignyourAPI• Provideonly functionalityrequiredbyclients– All othermembersshouldbeprivate

• Youcanalwaysmakeaprivatememberpubliclaterwithoutbreakingclients– Butnotvice-versa!

Page 28: 03-Object-oriented programming in java

2817-214

Outline

I. Object-orientedprogrammingbasicsII. InformationhidingIII. Exceptions

Page 29: 03-Object-oriented programming in java

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

Page 30: 03-Object-oriented programming in java

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

Page 31: 03-Object-oriented programming in java

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

Page 32: 03-Object-oriented programming in java

3217-214

Exceptions

• Notifythecallerofanexceptionalconditionbyautomatictransferofcontrol

• Semantics:– Propagatesupstackuntilmainmethodisreached(terminatesprogram),orexceptioniscaught

• Sources:– Program– e.g.,IllegalArgumentException– JVM– e.g.,StackOverflowError

Page 33: 03-Object-oriented programming in java

3317-214

Control-flowofexceptions

public static void main(String[] args) {try {

test();} catch (IndexOutOfBoundsException e) {

System.out.println"("Caught index out of bounds");}

}

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

}}

Page 34: 03-Object-oriented programming in java

3417-214

Checkedvs.uncheckedexceptions

• Checkedexception–Mustbecaughtorpropagated,orprogramwon’tcompile

• Uncheckedexception– Noactionisrequiredforprogramtocompile– Butuncaughtexceptionwillcauseprogramtofail!

Page 35: 03-Object-oriented programming in java

3517-214

TheexceptionhierarchyinJava

Throwable

Exception

RuntimeException IOException

EOFException

FileNotFoundException

NullPointerException

IndexOutOfBoundsException

ClassNotFoundException… …

. . .

Object

Error

Page 36: 03-Object-oriented programming in java

3617-214

Designchoice:checkedanduncheckedexceptionsandreturnvalues

• Uncheckedexception– Programmingerror,otherunrecoverablefailure

• Checkedexception– Anerrorthateverycallershouldbeawareofandhandle

• Specialreturnvalue(e.g.,null fromMap.get)– Commonbutatypicalresult

• DoNOTusereturncodes• NEVERreturnnull toindicateazero-lengthresult– Useazero-lengthlistorarrayinstead

Page 37: 03-Object-oriented programming in java

3717-214

Onemorealternative– returnOptional<T>

• Optional<T> isasingleTinstanceornothing– Avalueissaidtopresent,ortheoptionalisempty– Canthinkofitasasubsingleton collection

• Similarinspirittocheckedexceptions– Force callertoconfrontpossibilityofnovalue

• Butoptionalsdemandlessboilerplateinclient• Canbetrickytodecidewhichalternativetouse• SeeEffectiveJavaItem55formoreinformation

Page 38: 03-Object-oriented programming in java

3817-214

AsampleuseofOptional<T>

// Returns maximum value in collection as an Optional<E>public static <E extends Comparable<E>>

Optional<E> max(Collection<E> c) {if (c.isEmpty())

return Optional.empty();

E result = null;for (E e : c)

if (result == null || e.compareTo(result) > 0)result = Objects.requireNonNull(e);

return Optional.of(result);}

Page 39: 03-Object-oriented programming in java

3917-214

Creatingandthrowingyourownexceptions

public class SpanishInquisitionException extends RuntimeException {public SpanishInquisitionException() {}

}

public class HolyGrail {public void seek() {

...if (heresyByWord() || heresyByDeed())

throw new SpanishInquisitionException();...

}}

Page 40: 03-Object-oriented programming in java

4017-214

Benefitsofexceptions

• Youcan’tforgettohandlecommonfailuremodes– Compare:usingaflagorspecialreturnvalue

• Providehigh-levelsummaryoferror,andstacktrace– Compare:coredumpinC

• Improvecodestructure– Separatenormalcodepathfromexceptional– Easetaskofrecoveringfromfailure

• Easetaskofwritingrobust,maintainablecode

Page 41: 03-Object-oriented programming in java

4117-214

Guidelinesforusingexceptions(1)

• Avoidunnecessarycheckedexceptions(EJItem71)• Favorstandardexceptions(EJItem72)– IllegalArgumentException – invalidparametervalue– IllegalStateException – invalidobjectstate– NullPointerException – nullparamwhereprohibited– IndexOutOfBoundsException – invalidindexparam

• Throwexceptionsappropriatetoabstraction(EJItem73)

Page 42: 03-Object-oriented programming in java

4217-214

Guidelinesforusingexceptions(2)

• Documentallexceptionsthrownbyeachmethod– Checkedandunchecked(EJItem74)– Butdon’tdeclare uncheckedexceptions!

• Includefailure-captureinfoindetailmessage(Item75)– throw new IlegalArgumentException(

"Modulus must be prime: " + modulus);

• Don’tignoreexceptions(EJItem77)// Empty catch block IGNORES exception – Bad smell in code!try {

...} catch (SomeException e) { }

Page 43: 03-Object-oriented programming in java

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

}

Page 44: 03-Object-oriented programming in java

4417-214

Manualresourceterminationisuglyanderrorprone• Evengoodprogrammersusuallygetitwrong– Sun’sGuidetoPersistentConnectionsgotitwrongincodethatclaimedtobeexemplary

– Solutiononpage88ofBlochandGafter’s JavaPuzzlersisbadlybroken;noonenoticedforyears

• 70%oftheusesoftheclosemethodintheJDKitselfwerewrongin2008(!)

• Even“correct”idiomsformanualresourcemanagementaredeficient

Page 45: 03-Object-oriented programming in java

4517-214

Thesolution:try-with-resources(TWR)Automaticallyclosesresources

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

Page 46: 03-Object-oriented programming in java

4617-214

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

}}

}

Page 47: 03-Object-oriented programming in java

4717-214

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

}

Page 48: 03-Object-oriented programming in java

4817-214

Summary

• Interface-baseddesignshandlechangewell• Informationhidingiscrucialtogooddesign• Exceptionsarefarbetterthanerrorcodes• Theneedforcheckedexceptionsisrare• try-with-resources(TWR)isabigwin