Implementing the Standard Methods 27 February 2019 OSU CSE 1 - - PowerPoint PPT Presentation

implementing the standard methods
SMART_READER_LITE
LIVE PREVIEW

Implementing the Standard Methods 27 February 2019 OSU CSE 1 - - PowerPoint PPT Presentation

Implementing the Standard Methods 27 February 2019 OSU CSE 1 Loose Ends In implementing several kernel interfaces so far, you have been given code in the skeletons for the Standard methods The code for these methods is very stylized


slide-1
SLIDE 1

Implementing the Standard Methods

27 February 2019 OSU CSE 1

slide-2
SLIDE 2

Loose Ends

  • In implementing several kernel interfaces

so far, you have been given code in the skeletons for the Standard methods

  • The code for these methods is very

stylized and easy to adapt to a new situation, even if the code itself is hardly transparent!

– Several new Java issues arise ...

27 February 2019 OSU CSE 2

slide-3
SLIDE 3

newInstance

TF newInstance()

  • Returns a new object with the same dynamic

type as this, having an initial value. If the type TF has a no-argument constructor, then the value of the new returned object satisfies its

  • contract. Otherwise, the value of the new

returned object satisfies the contract of the constructor call that was used to initialize this.

  • Ensures:

is_initial(newInstance)

27 February 2019 OSU CSE 3

slide-4
SLIDE 4

newInstance

TF newInstance()

  • Returns a new object with the same dynamic

type as this, having an initial value. If the type TF has a no-argument constructor, then the value of the new returned object satisfies its

  • contract. Otherwise, the value of the new

returned object satisfies the contract of the constructor call that was used to initialize this.

  • Ensures:

is_initial(newInstance)

27 February 2019 OSU CSE 4

Throughout this set of slides, TF stands for the type family interface whose kernel you are implementing; it is not a generic type parameter!

slide-5
SLIDE 5

newInstance

TF newInstance()

  • Returns a new object with the same dynamic

type as this, having an initial value. If the type TF has a no-argument constructor, then the value of the new returned object satisfies its

  • contract. Otherwise, the value of the new

returned object satisfies the contract of the constructor call that was used to initialize this.

  • Ensures:

is_initial(newInstance)

27 February 2019 OSU CSE 5

So, is_initial means what it says above...

slide-6
SLIDE 6

Implementing newInstance

  • Java already offers a method to make a

new instance that is “like” an existing

  • bject, but it is messy to call it
  • The reason for the Standard method

newInstance is simply to make it easy to call Java’s method for doing this, by wrapping the mess inside a method body

  • The same code works for any type, so you

can just copy the code that follows

27 February 2019 OSU CSE 6

slide-7
SLIDE 7

Code for newInstance

@SuppressWarnings("unchecked") @Override public final Queue<T> newInstance() { try { return this.getClass() .getConstructor().newInstance(); } catch (ReflectiveOperationException e) { throw new AssertionError( "Cannot construct object of type " + this.getClass()); } }

27 February 2019 OSU CSE 7

slide-8
SLIDE 8

Code for newInstance

@SuppressWarnings("unchecked") @Override public final Queue<T> newInstance() { try { return this.getClass() .getConstructor().newInstance(); } catch (ReflectiveOperationException e) { throw new AssertionError( "Cannot construct object of type " + this.getClass()); } }

27 February 2019 OSU CSE 8

The return type is whatever type family interface TF you are implementing; Queue<T> is shown here for definiteness.

slide-9
SLIDE 9

Code for newInstance

@SuppressWarnings("unchecked") @Override public final Queue<T> newInstance() { try { return this.getClass() .getConstructor().newInstance(); } catch (ReflectiveOperationException e) { throw new AssertionError( "Cannot construct object of type " + this.getClass()); } }

27 February 2019 OSU CSE 9

This tells the compiler not to issue a warning about “unchecked conversion” ...

slide-10
SLIDE 10

Code for newInstance

@SuppressWarnings("unchecked") @Override public final Queue<T> newInstance() { try { return this.getClass() .getConstructor().newInstance(); } catch (ReflectiveOperationException e) { throw new AssertionError( "Cannot construct object of type " + this.getClass()); } }

27 February 2019 OSU CSE 10

... which it would otherwise warn you about on this statement (even though it cannot cause any trouble).

slide-11
SLIDE 11

Code for newInstance

@SuppressWarnings("unchecked") @Override public final Queue<T> newInstance() { try { return this.getClass() .getConstructor().newInstance(); } catch (ReflectiveOperationException e) { throw new AssertionError( "Cannot construct object of type " + this.getClass()); } }

27 February 2019 OSU CSE 11

The try/catch block and exceptions are Java constructs to be explained later in the course.

slide-12
SLIDE 12

clear

void clear()

  • Resets this to an initial value. If the type

TF has a no-argument constructor, then this satisfies its contract. Otherwise, this satisfies the contract of the constructor call that was used to initialize #this.

  • Clears: this

27 February 2019 OSU CSE 12

slide-13
SLIDE 13

clear

void clear()

  • Resets this to an initial value. If the type

TF has a no-argument constructor, then this satisfies its contract. Otherwise, this satisfies the contract of the constructor call that was used to initialize #this.

  • Clears: this

27 February 2019 OSU CSE 13

So, the parameter mode clears means what it says above, i.e., is_initial is true for that parameter.

slide-14
SLIDE 14

Implementing clear

  • Because this code has to do the same thing

as the no-argument (or maybe some other) constructor, it is a good idea to factor out the code that initializes the instance variables into a separate private method

  • For the no-argument constructor (usual

case):

private void createNewRep() { // initialize instance variables }

27 February 2019 OSU CSE 14

slide-15
SLIDE 15

Code for createNewRep

  • Again, code from Queue2<T> is shown:

private void createNewRep() { this.preFront = new Node(); this.preFront.next = null; this.rear = this.preFront; this.length = 0; }

27 February 2019 OSU CSE 15

slide-16
SLIDE 16

Code for clear

@Override public final void clear() { this.createNewRep(); }

27 February 2019 OSU CSE 16

slide-17
SLIDE 17

Code for clear

@Override public final void clear() { this.createNewRep(); }

27 February 2019 OSU CSE 17

If there isn’t a no-argument constructor, then createNewRep needs some parameters (like a constructor with parameters); see a SortingMachine implementation for an example.

slide-18
SLIDE 18

transferFrom

void transferFrom(TF source)

  • Sets this to the incoming value of source, and

resets source to an initial value; source must have the same dynamic type as this. If the type TF has a no-argument constructor, then source satisfies its

  • contract. Otherwise, source satisfies the contract of

the constructor call that was used to initialize #source.

  • Replaces: this
  • Clears: source
  • Ensures:

this = #source

27 February 2019 OSU CSE 18

slide-19
SLIDE 19

Implementing transferFrom

  • This code simply copies the values of all

the instance variables from source to this, and then re-initializes source

– For an instance variable of a reference type, the reference value is copied—but aliases are eliminated before transferFrom returns

27 February 2019 OSU CSE 19

slide-20
SLIDE 20

Code (Pt 1) for transferFrom

@Override public final void transferFrom(Queue<T> source) { assert source != null : "Violation of:" + " source is not null"; assert source != this : "Violation of:" + " source is not this"; assert source instanceof Queue2<?> : "" + "Violation of: source is of dynamic" + " type Queue2<?>"; ... }

27 February 2019 OSU CSE 20

slide-21
SLIDE 21

Code (Pt 1) for transferFrom

@Override public final void transferFrom(Queue<T> source) { assert source != null : "Violation of:" + " source is not null"; assert source != this : "Violation of:" + " source is not this"; assert source instanceof Queue2<?> : "" + "Violation of: source is of dynamic" + " type Queue2<?>"; ... }

27 February 2019 OSU CSE 21

The parameter type is whatever type family interface TF you are implementing; Queue<T> shown here for definiteness.

slide-22
SLIDE 22

Code (Pt 1) for transferFrom

@Override public final void transferFrom(Queue<T> source) { assert source != null : "Violation of:" + " source is not null"; assert source != this : "Violation of:" + " source is not this"; assert source instanceof Queue2<?> : "" + "Violation of: source is of dynamic" + " type Queue2<?>"; ... }

27 February 2019 OSU CSE 22

First two asserts check for normal problems: null and repeated arguments.

slide-23
SLIDE 23

Code (Pt 1) for transferFrom

@Override public final void transferFrom(Queue<T> source) { assert source != null : "Violation of:" + " source is not null"; assert source != this : "Violation of:" + " source is not this"; assert source instanceof Queue2<?> : "" + "Violation of: source is of dynamic" + " type Queue2<?>"; ... }

27 February 2019 OSU CSE 23

This assert checks for a mismatch between the dynamic types of source and this, using the instanceof operator.

slide-24
SLIDE 24

Code (Pt 1) for transferFrom

@Override public final void transferFrom(Queue<T> source) { assert source != null : "Violation of:" + " source is not null"; assert source != this : "Violation of:" + " source is not this"; assert source instanceof Queue2<?> : "" + "Violation of: source is of dynamic" + " type Queue2<?>"; ... }

27 February 2019 OSU CSE 24

Because of a problem in Java called type erasure, you can check

  • nly that the dynamic type is

Queue2<?>, meaning “Queue2 of something”; more on this later.

slide-25
SLIDE 25

Code (Pt 2) for transferFrom

@Override public final void transferFrom(Queue<T> source) { ... Queue2<T> localSource = (Queue2<T>) source; this.preFront = localSource.preFront; this.rear = localSource.rear; this.length = localSource.length; localSource.createNewRep(); }

27 February 2019 OSU CSE 25

slide-26
SLIDE 26

Code (Pt 2) for transferFrom

@Override public final void transferFrom(Queue<T> source) { ... Queue2<T> localSource = (Queue2<T>) source; this.preFront = localSource.preFront; this.rear = localSource.rear; this.length = localSource.length; localSource.createNewRep(); }

27 February 2019 OSU CSE 26

This cast cannot fail since the assert above would have stopped execution in that case; so, source must be of dynamic type Queue2<?>, and the ? must be T or the call would not have compiled.

slide-27
SLIDE 27

The Cast and Why It Works Here

27 February 2019 OSU CSE 27

preFront length 16 this rear

some abstract value of type Queue<T>

source

slide-28
SLIDE 28

The Cast and Why It Works Here

27 February 2019 OSU CSE 28

preFront length 16 this rear

some abstract value of type Queue<T>

source

Queue2<T> Queue<T>

The compiler thinks things look like this picture because of the declared types of this and source, shown below.

slide-29
SLIDE 29

The Cast and Why It Works Here

27 February 2019 OSU CSE 29

preFront length 16 this rear source

Queue2<T> Queue<T>

preFront length 482 rear localSource

Queue2<T>

The initialization of localSource claims that the dynamic type of source is Queue2<T>, as shown here—and it is!

slide-30
SLIDE 30

How transferFrom Works

27 February 2019 OSU CSE 30

preFront length 16 this rear source preFront length 482 rear localSource Start here ...

slide-31
SLIDE 31

How transferFrom Works

27 February 2019 OSU CSE 31

preFront length 482 this rear source preFront length 482 rear localSource ... update this ...

slide-32
SLIDE 32

How transferFrom Works

27 February 2019 OSU CSE 32

preFront length 482 this rear source preFront length rear localSource ... clear source ...

slide-33
SLIDE 33

How transferFrom Works

27 February 2019 OSU CSE 33

preFront length 482 this rear source preFront length rear ... and return.

slide-34
SLIDE 34

Code (Pt 2) for transferFrom

@Override public final void transferFrom(Queue<T> source) { ... Queue2<T> localSource = (Queue2<T>) source; this.preFront = localSource.preFront; this.rear = localSource.rear; this.length = localSource.length; localSource.createNewRep(); }

27 February 2019 OSU CSE 34

To check your understanding: could this code be used in place of the last line shown in the body? source.clear();