session 6 comments on lab 3 & implications of inheritance

22
Session 6 Comments on Lab 3 & Implications of Inheritance

Upload: cecily-hodges

Post on 19-Jan-2016

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Session 6 Comments on Lab 3 & Implications of Inheritance

Session 6

Comments on Lab 3&

Implications of Inheritance

Page 2: Session 6 Comments on Lab 3 & Implications of Inheritance

Accumulator Example• a simple calculator app• classes needed:

– AdderApp - contains main– AddingFrame - GUI

– CloseableFrame - allows X button

– Accumulator - internal representation and implementation of the accumulator

Page 3: Session 6 Comments on Lab 3 & Implications of Inheritance

Refactoring Accumulator public void plus() {

currentSum+=currentNumber;

prepareForNextNumber();

}

public void minus() {

currentSum-=currentNumber;

prepareForNextNumber();

}

private void prepareForNextNumber() {

currentNumber=0;

displayNumber=currentSum;

}

public int getDisplay() {

return displayNumber;

}

} // end class AccumulatorV2

public class AccumulatorV2 { private int currentSum; private int currentNumber; private int displayNumber; public Accumulator() { clear(); } public void clear() { currentSum=0; currentNumber=0; displayNumber=0; } public void addDigit( int digit ) { currentNumber=currentNumber*10+digit; displayNumber=currentNumber; }

Page 4: Session 6 Comments on Lab 3 & Implications of Inheritance

Alternative structure of the program• But another way to structure this program would be to

create a relationship which is “wide and shallow”– AdderApp creates an an instance of Accumulator which it

passes to an instance of AddingFrame. public class AdderApp { public static void main( String[] args ) {

Accumulator a = new Accumulator();

AddingFrame f = new AddingFrame(a);

f.show();

} // end main

} // end class AdderApp

– This is a good example of composition. • We emphasize that AddingFrame is composed of an Accumulator

– This is a good example of writing code that is modular.• Now that we know the composition relation, we can compose

solutions using variations of Accumulator.

Page 5: Session 6 Comments on Lab 3 & Implications of Inheritance

CountedAccumulator Solutionpublic class CountedAccumulator extends Accumulator {

private int numberOfOperations;

public CountedAccumulator() {

super(); // calls the superclass’ constructor

numberOfOperations=0;

}

public void plus() {

super.plus();

numberOfOperations++;

}

public void minus() {

super.minus();

numberOfOperations++;

}

public int getOperations() {

return numberOfOperations;

}

} // end class CountedAccumulator

Page 6: Session 6 Comments on Lab 3 & Implications of Inheritance

CountedAccumulator Solution• Now, before we can really work with this

we need to modify other files in our application. 

• We need to set up the AddingFrame so that it works with a CountedAccumulator rather than a regular Accumulator.  We do this in the AdderApp class for simplicity.

Accumulator a = new CountedAccumulator();

AddingFrame f = new AddingFrame(a);

Page 7: Session 6 Comments on Lab 3 & Implications of Inheritance

A solution• Why do we do this in the AdderApp rather than

leave it alone and modify the AddingFrame?  – Because in the end this makes our AddingFrame

slightly more versatile. 

– Think about it...AddingFrame works with an Accumulator (or CountedAccumulator).  If one is provided, it uses it.  If one is not provided, it creates it. 

– THAT, is more versatile than telling an AddingFrame to now always create a CountedAccumulator.

Page 8: Session 6 Comments on Lab 3 & Implications of Inheritance

Lab 3 Exercise

Create a class named EvenOddAccumulator that subclasses Accumulator to implement this behavior.

EvenOddAccumulators respond to all the same messages as regular Accumulators. But, in response to plus() and minus() messages, an EvenOddAccumulator both computes the new sum and writes a congratulatory message if the sum is even.

Page 9: Session 6 Comments on Lab 3 & Implications of Inheritance

Toward a Solution

Here is the critical new piece of the EvenOddAccumulator class:

if ( currentSum % 2 == 0 ) {System.out.println( "Hurray! You made an even number." );

}

The big question is, what else is a part of the class?

Page 10: Session 6 Comments on Lab 3 & Implications of Inheritance

Toward a Solution

• Here where I thought you would get into trouble during Lab 3 yesterday…

Page 11: Session 6 Comments on Lab 3 & Implications of Inheritance

A Problem Accessing Inherited Data$ javac EvenOddAccumulator.javaEvenOddAccumulator.java:17: currentSumhas private access in Accumulatorif ( currentSum % 2 == 0 )^EvenOddAccumulator.java:24: currentSumhas private access in Accumulatorif ( currentSum % 2 == 0 )^2 errors

Oops!currentSum is declared as a private instance variable in class Accumulator. private means private: no code outside the Accumulator class can access

that variable.

Page 12: Session 6 Comments on Lab 3 & Implications of Inheritance

A Possible Solution for Accessing Inherited Data

• Change currentSum to be public or protected.

public class Accumulator {

protected int currentSum;

...

}

Page 13: Session 6 Comments on Lab 3 & Implications of Inheritance

A Better Solutionfor Accessing Inherited Data

(2) Add a protected “accessor” method to theAccumulator class. Use that method to access thecurrentSum instance variable in the subclass.

public class Accumulator {...protected int getCurrentSum() {

return currentSum;}

}

Then use getCurrentSum() in EvenOddAccumulator.

Page 14: Session 6 Comments on Lab 3 & Implications of Inheritance

Programming with Inheritance

Inheritance is an object-oriented programming construct that enables us to add behavior to an existing system without modifying the existing classes.

Page 15: Session 6 Comments on Lab 3 & Implications of Inheritance

Programming with InheritanceOur new EvenOddAccumulator class adds behavior to a program

that uses Accumulators without modifying:• the behavior of the existing Accumulator class or• the existing AddingFrame class!

That means...• No chance of introducing an unnecessary, unexpected errors

into the working Accumulator class.• No need to modify programs that use instances of

Accumulator but which don’t need instances of EvenOddAccumulator.

• The ability to use EvenOddAccumulators in programs that expect to use Accumulators.

Page 16: Session 6 Comments on Lab 3 & Implications of Inheritance

Programming with Inheritance

We could have achieved some of these results without using inheritance by creating a new class named EvenOddAccumulator that simply duplicated the behavior of existing Accumulator class.

Using inheritance means that...• No need to reimplement existing methods.• No need to duplicate code.

One of the most important features of object-oriented programming is that it encourages us to create new classes that reuse existing code as much as possible. Without inheritance, you have only one tool for doing that, composition. With inheritance, you have two tools.

Page 17: Session 6 Comments on Lab 3 & Implications of Inheritance

Polymorphism• polymorphism comes from the Greek root for “many

shapes”• polymorphism is about how we can use different objects

in the same place in our program, i.e., polymorphism depends on objects that are substitutable for one another

• A polymorphic variable can hold many different types of values

• Object-oriented languages often restrict the types of values to being subclasses of the declared type of the variable.

Page 18: Session 6 Comments on Lab 3 & Implications of Inheritance

Polymorphic Variables in Java• Java achieve polymorphic variables by two ways:

1) Interfaces: a variable defined using an interface can hold an object of any class implementing that interface, e.g., in MemoPad, “MemoDatabase datebase” could be assigned either a DefaultMemoDatabase or MyMemoDatabase object.

2) Inheritance: a variable defined using a superclass can hold any instance of a subclass, e.g., in AdderApp:

public class AdderApp {

public static void main( String[] args ) { Accumulator a = new CountedAccumulator(); AddingFrame f = new AddingFrame(a); f.show();

} // end main} // end AdderApp

Page 19: Session 6 Comments on Lab 3 & Implications of Inheritance

Implications of Inheritance/Polymorphism

• At compile-time, the amount of memory for polymorphic variables cannot be determined, so all objects reside in the heap

• Because values reside in the heap, reference semantics is used for assignment and parameter passing

• Most natural interpretation of equality is identity. Since programmers often require a different meaning two operators are needed

• Garbage collection needed since it is hard for a programmer to know if/when an object is no longer referenced

Page 20: Session 6 Comments on Lab 3 & Implications of Inheritance

Typical Memory Layout

Program

Global variables

Stack

Heap

Page 21: Session 6 Comments on Lab 3 & Implications of Inheritance

Stack-based Memory

• Objects are stored on the heap• When a method is called, an activation record is allocated on the

stack to hold:– return address (where to return after execution)– parameters– local variables (stuff declared in the method)

• When a method returns, the activation record is popped

Main:ObjA a = new ObjA();ObjB b = new ObjB();

a.do(5, b)

public class ObjA { int x = 100; public void do (int y, ObjB myB) { int loc = 6; int t = myB.doMore(loc);... }

}

public class ObjB {

int z = 30;

public int doMore(int i) {

z = z + i;

return z;

}

}

Page 22: Session 6 Comments on Lab 3 & Implications of Inheritance

Consider Factorial Exampleclass FacTest { static public void main (String [] args) {

int f = factorial(3); // * System.out.println(“Factorial of 3 is “ + f);

}

static public int factorial (int n) { int c = n – 1; int r;

if (c > 0) { r = n * factorial(c); // ** } else { r = 1; } return r; }}