Safely Creating Correct Subclasses without Seeing Superclass Code PowerPoint PPT Presentation

presentation player overlay
1 / 20
About This Presentation
Transcript and Presenter's Notes

Title: Safely Creating Correct Subclasses without Seeing Superclass Code


1
Safely Creating Correct Subclasses without Seeing
Superclass Code
  • Clyde Ruby and Gary T. Leavens (Iowa St.)
  • OOPSLA 2000
  • Presented by James Caverlee

2
Motivation
  • Usually, the source code for OO frameworks and
    class libraries is unavailable to programmers
  • We would like to create new subclasses for a
    framework or a class library
  • But, we may introduce non-termination or
    unexpected behavior through downcalls

3
Whats a downcall?
  • When a superclass method calls a method that is
    overriden in the subclass

public class A ... public void foo()
bar() public void bar()
System.out.println (Hello world!)
...
public class B extends A ... public void
bar() // unexpected behavior // or
non-termination // code goes here ...
4
The Problem
  • Semantic Fragile Subclassing Problem
  • How can we safely override superclass methods so
    that the subclass is free from downcall problems
  • In the absence of superclass source code

5
The Solution
  • (1) A formal specification
  • The documentation
  • JML for public, protected specification, and a
    subclass contract
  • (2) A set of rules
  • Using the documentation
  • A reasoning technique for determining which
    methods should be overridden

6
Novelty of the Paper
  • The set of formal rules for when it is necessary
    to override superclass methods
  • Showcases these rules with respect to the
    specification language
  • Synthesizes and formalizes some earlier work in
    the context of subclass safety

7
(1) Formal specification
  • Public and Protected Specifications
  • Describes the behavior of each public/protected
    method and constructor
  • Preconditions, postconditions, modifiable
    variables
  • Subclassing Contract
  • Lists the variables accessed and methods called
    by each method and constructor
  • Statically-generated from original source code of
    superclass (so, some approximate knowledge)

8
(2) The Set of Rules
  • New instance variables
  • Temporary side-effects
  • Subclass invariants
  • Mutually recursive methods
  • Method refinement
  • Concrete data refinement
  • Super-calls

9
Example New Instance Variable
  • Consider a superclass Point
  • We only have its specification and subclass
    contract no source code
  • We want to write subclass PointPlusTotal
  • It maintains a new instance variable totalDist
    that captures the total distance the point has
    ever moved
  • We write a getTotalDistance() method
  • Are we done?

10
Are we done? No!
  • Intuitively, we know that all methods that move
    the point will have to be overridden
  • Lets show how the authors more formally approach
    the problem ...

11
Public Specification Point
  • public class Point
  • //_at_ public model int xCoord, yCoord
  • //_at_ public model int oldX, oldY
  • /_at_ public_normal_behavior
  • _at_ modifiable xCoord, yCoord, oldX, oldY
  • _at_ ensures xCoord newX yCoord newY
  • _at_ oldX \old(xCoord)
  • _at_ oldY \old(yCoord)
  • _at_/
  • public void move(int newX, int newY)

12
Subclassing Contract Point
  • public class Point
  • /_at_ also
  • _at_ subclassing contract
  • _at_ accessible x, y
  • _at_ callable moveX(int), moveY(int)
  • _at_/
  • public void move(int newX, int newY)

13
Writing the Subclass
  • public class PointPlusTotal extends Point
  • //_at_ public model int totalDist
  • //_at_ public depends xCoord -gt totalDist
  • //
  • //
  • //
  • //_at_ public depends yCoord -gt totalDist
  • //_at_ public_normal_behavior ensures \result
    totalDist
  • public int getTotalDistance()

xCoord depends on totalDist
14
Codependency
  • Variables V and W are codependent in method M if
    there is some variable X such that X depends on
    both V and W, and X is modifiable by M
  • xCoord(X) depends on xCoord(V)
  • xCoord(X) depends on totalDist(W)
  • xCoord(X) is modifiable by move(M)
  • xCoord and totalDist are codependent in move()

15
Intuition
  • If V and W are codependent in M, then V and W are
    modifiable in M
  • Any method that modifies xCoord must be
    overridden, since totalDist could change as well
  • Additional side-effects

16
The Rule
  • Additional side-effects rule
  • Let V (xCoord) be a superclass variable
  • Let W (totalDist) be a new subclass instance
    variable.
  • If V and W are codependent in a method M (move),
    then M must be overridden
  • (Unless the subclasss specification of M
    prohibits modification of W.)

17
Writing the Subclass (again)
  • public class PointPlusTotal extends Point
  • //_at_ public model int totalDist
  • //_at_ public depends xCoord -gt totalDist
  • // xCoord depends on totalDist
  • //_at_ public depends yCoord -gt totalDist
  • ...
  • //_at_ public_normal_behavior ensures \result
    totalDist
  • public int getTotalDistance()
  • /_at_ also
  • _at_ public_normal_behavior
  • _at_ modifiable totalDist
  • _at_ ensures totalDist
  • _at_ \old(totalDist) distance(xCoord -
    oldX,
  • _at_ yCoord -
    oldY) _at_/
  • public void move(int newX, int newY)

Plus moveX and moveY
18
Conclusions
  • Set of new rules for reasoning about which
    methods must be overridden
  • Can iteratively apply rules, to guarantee that a
    new subclass is free from downcall problems

19
My thoughts
  • If superclass implementation changes, need to
    propagate new subclass contract to programmer
  • Proof of correctness/completeness of rules?
  • Rules work only in conjunction with specification
    forces us to generate these behavioral specs in
    the first place can we guarantee that they are
    even correct?

20
Related Work
  • Syntactic-based (no JML-like behavioral layer)
  • Kiczales and Lamping (92) informal
    documentation, no static checks
  • Lamping (93) entire groups are overridden, not
    just invalidated methods
  • Steyaert, Lucas, et al (96,97) reuse
    contracts, manually determine methods to
    consider concerned primarily with superclasses,
    not new subclasses
  • Semantic-based
  • Perry and Kaiser (90) testing-focused limited
    severely need to retest
  • Stata and Guttag (95) requires subclasses
    implement behavioral subtypes all methods within
    a component must be overridden
  • Mezini (97) cooperation contracts (requires a
    metaobject protocol extension)
  • None reason about supercalls making downcalls
  • Most require manual generation of proper
    documentation
Write a Comment
User Comments (0)
About PowerShow.com