Lecture 9: Extends, Casting, Higher Order Functions

9/16/2020

Implementation Inheritance: Extends

The Extends Keyword

RotatingSLList

public class RotatingSLList<Item> extends SLList<Item> { // Rotates list to the right public void rotateRight() { Item x = removeLast(); addFirst(x); } }

Another Example: VengefulSLList

public class VengefulSLList<Item> extends SLList<Item> { SLList<Item> deletedItems; public VengefulSLList() { super(); // Optional line deletedItems = new SLList<Item>(); } @Override public Item removeLast() { Item x = super.removeLast(); // Calls Superclass's version of removeLast() deletedItems.addLast(x); return x; } // Prints deleted items public void printLostItems() { deletedItems.print(); } }

Constructor Behavior is Slightly Weird

Calling Other Constructors

public class VengefulSLList<Item> extends SLList<Item> { SLList<Item> deletedItems; public VengefulSLList() { super(); // Optional line deletedItems = new SLList<Item>(); } public VengefulSLList(Item x) { super(x); // NOT OPTIONAL! (calls no-argument constructor otherwise) deletedItems = new SLList<Item>(); } }

The Object Class

Is-a vs. Has-A

Encapsulation

Complexity: The Enemy

Modules and Encapsulation

A Cautionary Tale

Abstraction Barriers

Implementation Inheritance Breaks Encapsulation

public void bark() { barkMany(1); } public void barkMany(int N) { for (int i = 0; i < N; i += 1) { System.out.println("bark"); } } @Override public void barkMany(int N) { System.out.println("As a dog, I say: ") { for (int i = 0; i < N; i += 1) { bark(); // calls inherited bark method } } }

Type Checking and Casting

Reminder: Dynamic Method Selection

Compile-Time Type Checking

Compile-Time Types and Expressions

Compile-Type Types and Expressions

Poodle frank = new Poodle("Frank", 5); Poodle frankJr = new Poodle("Frank Jr." 15); dog largerDog = maxDog(frank, frankJr); Poodle largerPoodle = maxDog(frank, frankJr); // Compilation Error! // RHS has compile-time type Dog

Casting

Poodle frank = new Poodle("Frank", 5); Poodle frankJr = new Poodle("Frank Jr." 15); dog largerDog = maxDog(frank, frankJr); Poodle largerPoodle = (Poodle) maxDog(frank, frankJr); // Compilation OK! // RHS has compile-time type Poodle
Poodle frank = new Poodle("Frank", 5); Malamute frankSr = new Malamute("Frank Sr.", 100); Poodle largerPoodle = (Poodle) maxDog(frank, frankSr);

Higher Order Functions (A First Look)

Higher Order Functions

def tenX(x): return 10*x def do_twice(f, x): return f(f(x)) print(do_twice(tenX, 2))

Higher Order Functions in Java 7

// Represents a function that takes in an integer, and returns an integer public interface IntUnaryFunction { int apply(int x); }
public class TenX implements IntUnaryFunction { /** Returns ten times the argument */ public int apply(int x) { return 10 * x; } }
// Demonstrates higher order functions in Java public class HofDemo { public static int doTwice(IntUnaryFunction f, int x) { return f.apply(f.apply(x)); } public static void main(String[] args) { IntUnaryFunction tenX = new TenX(); System.out.println(doTwice(tenX, 2)); } }

Implementation Inheritance Cheatsheet