Effective Java: Classes and Interfaces - PowerPoint PPT Presentation

About This Presentation
Title:

Effective Java: Classes and Interfaces

Description:

Title: INFS 501 Discrete Mathematics Author: Richard Bechtold Last modified by: pammann Created Date: 1/19/2002 6:08:50 PM Document presentation format – PowerPoint PPT presentation

Number of Views:68
Avg rating:3.0/5.0
Slides: 45
Provided by: RichardB86
Learn more at: https://cs.gmu.edu
Category:

less

Transcript and Presenter's Notes

Title: Effective Java: Classes and Interfaces


1
Effective Java Classes and Interfaces
  • Last Updated Fall 2008

2
Agenda
  • Material From Joshua Bloch
  • Effective Java Programming Language Guide
  • Cover Items 13 through 22
  • Classes and Interfaces
  • Was Items 12 through 18 in 1st Edition
  • Moral
  • Inheritance requires careful programming

3
Item 13 Minimize Accessibility of Classes and
Members
  • Standard advice for information
    hiding/encapsulation
  • Decouples modules
  • Allows isolated development and maintenance
  • Java has an access control mechanism to
    accomplish this goal

4
Make Each Class or Member as Inaccessible as
Possible
  • Standard list of accessibility levels
  • private
  • package-private (aka package friendly)
  • protected
  • public
  • Huge difference between 2nd and 3rd
  • package-private part of implementation
  • protected part of public API

5
Exception Exposing Constants
  • Public constants must contain either primitive
    values or references to immutable objects
  • Wrong Potential Security Hole
  • public static final Type VALUES
  • Problem
  • VALUES is final entries in VALUES are not!

6
Exposing Constants - Solutions
  • Correct
  • private static final Type PRIVATE_VALUES
  • public static final List VALUES
  • Collections.unmodifiableList(Arrays.asList
  • (PRIVATE_VALUES))
  • Also Correct
  • private static final Type PRIVATE_VALUES
  • public static final Type values()
  • return (Type) PRIVATE_VALUES.clone()

7
Item 14 In Public Classes, Use Accessors, Not
Public Fields
  • Avoid code such as
  • Class Point public double x public double y
  • No possibility of encapsulation
  • Use get/set methods instead
  • Public double getX() return x
  • Public void setX(double x) this.x x
  • Advice holds for immutable fields as well
  • Limits possible ways for class to evolve

8
Item 15 Minimize Mutability
  • Reasons to make a class immutable
  • Easier to design
  • Easier to implement
  • Easier to use
  • Less prone to error
  • More secure
  • Easier to share
  • Thread safe

9
5 Rules to Make a Class Immutable
  • Dont provide any mutators
  • Ensure that no methods can be overridden (more
    detail)
  • Make all fields final (more detail)
  • Make all fields private
  • Ensure exclusive access to any mutable components
    (more detail)

10
Rule 2 No Overridden Methods
  • Prevents careless or malicious subclasses from
    compromising the immutable behavior of the class
  • How to implement
  • Make class final (easiest)
  • Make methods final (allows subclassing)
  • Make all constructors private or package-private
  • Requires static factories, which are better anyway

11
Rule 3 Make All Fields Final
  • Clearly expresses intent
  • System enforcement of immutability
  • Issues with object instantiation and thread
    access
  • Sometimes, making fields final is too strong
  • Lazy initialization may be preferable

12
Rule 5 Exclusive Access to Mutable Components
  • Never initialize a mutable field to a client
    provided reference
  • Never return a reference to a mutable field
  • Make defensive copies
  • See Liskov Exposing the rep

13
Typical Transformation
  • Typical method in mutable class Foo
  • public void foo(T1 t1, T2, t2, ) modify this
  • Immutable version of Foo
  • public Foo foo(T1 t1, T2, t2, )
  • Foo f
  • return f
  • Functional programming vs. procedural
    programming.
  • See Liskovs Poly for an example

14
Disadvantage Performance
  • Typical approach
  • Provide immutable class
  • Provide mutable companion class for situations
    where performance is an issue
  • Clients choose on performance needs
  • Example in Java Library
  • String (Immutable)
  • StringBuilder (Companion Mutable Class)
  • Static factories can cache frequently used items
  • More on this in Liskov 15

15
Item 16 Favor Composition over Inheritance
  • Issue ONLY for implementation inheritance
  • Interface inheritance does NOT have these
    problems
  • Inheritance breaks encapsulation!
  • Difficult to evolve superclass without breaking
    subclasses
  • Difficult for superclass to maintain invariants
    in face of malicious/careless subclass

16
Example Broken Subtype
  • public class IHashSet extends HashSet
  • private int addCount 0 // add() calls
  • public IHashSet()
  • public IHashSet(Collection c) super(c)
  • public boolean add(Object o)
  • addCount return super.add(o)
  • public boolean addAll(Collection c)
  • addCount c.size() return
    super.addAll(c)

17
Broken Example, continued
  • So, whats the problem?
  • IHashSet s new IHashSet()
  • s.addAll(Arrays.asList(new String Snap,
    Crackle, Pop))
  • What does addCount() return?
  • 3?
  • 6?
  • Internally, HashSets addAll() is implemented on
    top of add(), which is overridden. Note that
    this is an implementation detail, so we cant get
    it right in IHashSet

18
Source of Difficulty Overridden Methods
  • Overriding methods can be tricky
  • May break the superclass invariant
  • Overridden method does not maintain invariant
  • May break subclass invariant
  • New methods may be added to superclass
  • What if new method matches subclass method?
  • Also, recall problems with equals() and hashCode()

19
Composition
  • Fortunately, composition solves all of these
    problems even though it makes the programmer
    work harder
  • // Inheritance
  • public Class Foo extends Fie
  • // Composition
  • public class Foo
  • private Fie f
  • // Note forwarded methods

20
Revisiting the Example
  • public class ISet implements Set
  • private final Set s
  • private int addCount 0
  • public ISet (Set s) this.s s
  • public boolean add(Object o)
  • addCount return s.add(o)
  • public boolean addAll (Collection c)
  • addCount c.size()
  • return s.addAll(c)
  • // forwarded methods from Set interface

21
A more elegant version (without generics See
Bloch for these)
// Reusable Forwarding Class public class
ForwardingSet implements Set private final
Set s public ForwardingSet (Set s) this.s
s public void clear()
s.clear() public boolean
contains(Object o) return s.contains(o) //
plus all the other methods // Wrapper class
public class ISet extends ForwardingSet
private int addCount 0 public ISet (Set s)
super(s) _at_Override public boolean
add(Object o) addCount return
super.add(e) // other instrumented
methods
22
This is Cool!
  • Consider temporarily instrumenting a Set
  • Note that Set is an interface
  • static void f(Set s)
  • ISet myS new ISet (s)
  • // use myS instead of s
  • // all changes are reflected in s!

23
A Variation That Doesnt Work
  • public class ICollection implements Collection
  • private final Collection c
  • private int addCount 0
  • public ICollection (Collection c) this.c
    c
  • public boolean add(Object o)
  • public boolean addAll (Collection c)
  • // forwarded methods from Collection interface
  • public boolean equals(Object o)
  • return c.equals(o) // Now, were
    dead!

24
This is no longer Cool!
  • Consider temporarily instrumenting a Set
  • Note Set is a subtype of Collection
  • Set s new HashSet()
  • ICollection t new ICollection(s)
  • s.equals(t) // c is not a Set, so false
  • t.equals(s) // t.c s, so true
  • Issue Set has a uniform equals contract
    Collection does not (and should not)
  • Keep this in mind when using this model.

25
Item 17 Design and Document for Inheritance
  • Or else prohibit it.
  • First, document effects of overriding any method
  • Document self use, as in IHashSet example
  • This is implementation detail, but unavoidable,
    since subclass sees implementation.
  • Inheritance violates encapsulation!

26
Efficiency May Require Hooks
  • protected methods may be required for efficient
    subclasses.
  • Example
  • protected removeRange() method in AbstractList
  • Not of interest to List clients
  • Only of interest to implementers of AbstractList
    provides fast clear() operation
  • Alternative O(n2) clear operation

27
Inheritance is Forever
  • A commitment to allow inheritance is part of
    public API
  • If you provide a poor interface, you (and all of
    the subclasses) are stuck with it.
  • You cannot change the interface in subsequent
    releases.

28
Constructors Must Not Invoke Overridable Methods
  • // Problem constructor invokes overridden m()
  • public class Super
  • public Super() m()
  • public void m()
  • public class Sub extends Super
  • private final Date date
  • public Sub() date new Date()
  • public void m() // access date variable

29
What Is the Problem?
  • Consider the code
  • Sub s new Sub()
  • The first thing that happens in Sub() constructor
    is a call to constructor in Super()
  • The call to m() in Super() is overridden
  • But date variable is not yet initialized!
  • Further, initialization in Super m() never
    happens!
  • Yuk!

30
Inheritance and Cloneable, Serializable
  • Since clone() and readObject() behave a lot like
    constructors, these methods cannot invoke
    overridable methods either.
  • Problem access to uninitialized state
  • For Serializable
  • readResolve(), writeReplace() must be protected,
    not private (or they will be ignored in subclass.)

31
Bottom Line
  • Be sure you want inheritance, and design for it,
    or
  • Prohibit inheritance
  • Make class final, or
  • Make constructors private (or package-private)

32
Item 18 Prefer Interfaces to Abstract Classes
  • Existing classes can be easily retrofitted to
    implement a new interface
  • Same is not true for abstract classes due to
    single inheritance model in Java
  • Interfaces are ideal for mixins
  • Example Comparable interface
  • Interfaces arent required to form a hierarchy
  • Some things arent hierarchical

33
More Interfaces
  • Wrapper idiom a potent combination with
    interfaces
  • See ISet example
  • Possible to provide skeletal implementations for
    interfaces
  • java.util does this with AbstractCollection,
    AbstractSet, AbstractList, and AbstractMap

34
Example for AbstractList
  • static List intArrayAsList(final int a)
  • if (a null throw new NPE()
  • return new AbstractList()
  • public Object get(int i)
  • return new Integer(ai)
  • public int size() return a.length
  • public Object set(int i, Object o)
  • int oldVal ai
  • ai ((Integer) o).intValue()
  • return new Integer(oldVal)

35
This Implementation Does a Lot!
  • The List interface includes many methods.
  • Only 3 of them are explicitly provided here.
  • This is an anonymous class example
  • Certain methods are overridden
  • Note that it is possible to add a method to an
    abstract class in a new release
  • It is not possible to add a method to an
    interface

36
Item 19 Use Interfaces Only to Define Types
  • Example that fails the test
  • Constant interface avoid
  • public interface PhysicalConstants
  • static final double AVOGADROS
  • Why is this bad?
  • Users of a class that implements this interface
    dont care about these constants!
  • Think about the client, not the implementor

37
Alternative to Constants in Interfaces
  • Constant utility class
  • public class PhysicalConstants
  • public static final double AVOGADROS

38
Item 20 Prefer Class Hierarchies to Tagged
Classes
  • //Tagged Class vastly inferior to a class
    hierarchy
  • class Figure
  • enum Shape RECTANGLE, CIRCLE
  • final Shape shape // Tag field
  • double length double width // for RECTANGLE
  • double radius // for CIRCLE
  • Figure (double length, double width) //
    RECTANGLE
  • Figure (double radius) // CIRCLE
  • double area()
  • switch (shape)
  • case RECTANGLE return lengthwidth
  • case CIRCLE return Math.PI(radius
    radius)
  • default throw new AssertionError()

39
Item 20 Continued A much better solution
  • //Class hierarchy replacement for a tagged class
  • abstract class Figure // Note NOT
    instantiable!
  • abstract double area()
  • class Circle extends Figure
  • final double radius
  • Circle(double rad) radius rad
  • double area()
  • return Math.PI(radiusradius)
  • class Rectangle extends Figure
  • final double length final double width
  • Rectangle (double len double wid) length
    len width wid
  • double area()
  • return lengthwidth

40
Item 21 Use Function Objects to Represent
Strategies
  • In Java, cant pass functions directly
  • Only Objects can be arguments
  • So, pass Objects to pass functions
  • Example Instances of Comparator
  • We covered this in Liskov 8

41
Item 22 Favor Static Member Classes Over
Nonstatic
  • Nested classes
  • Defined within another class
  • Four flavors
  • Static member class
  • Nonstatic member class (inner)
  • Anonymous class (inner)
  • Local class (inner)

42
Static vs NonStatic
  • Static requires no connection to enclosing
    instance.
  • Nonstatic always associated with enclosing
    instance
  • Possible performance issue
  • Possible desire to create by itself
  • Hence recommendation to favor static
  • See Iterator implementations

43
Anonymous class (another) example
  • // Typical use of an anonymous class
  • Arrays.sort (args, new Comparator()
  • public int compare(Object o1, Object o2)
  • return ((String) o1).length()
  • (String) o2).length()
  • )
  • Question Does this satisfy the compare()
    contract?

44
Local classes
  • Declared anywhere a local variable may be
    declared
  • Same scoping rules
  • Have names like member classes
  • May be static or nonstatic (depending on whether
    context is static or nonstatic)
Write a Comment
User Comments (0)
About PowerShow.com