pet-able! lecture 6 interfaces 1 of 58. inheritance - review (part i) ●review of inheritance o a...

59
Pet- able! Lecture 6 Interfaces 1 of 58

Upload: aileen-casey

Post on 18-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Pet-able!

Lecture 6Interfaces

1 of 58

Inheritance - Review (Part I)

● Review of Inheritance

o a method of modeling similar capabilities among similar objects

● Abstract methods and classes

● Interfaces

o method of modeling similar capabilities among dissimilar objects

● Interface Examples

● Classes vs Interfaces

2 of 58

Inheritance - Review (Part I)

● Last lecture we covered inheritance

o specialized class (subclass) inherits properties and capabilities from more general class (superclass)

● Subclass can override or partially override methods inherited from its superclass, allowing the subclass to behave in a more specialized manner

3 of 58

● Here’s the inheritance hierarchy we saw last class

● BrownCSStudent is a subclass of BrownStudent and the superclass of CS15Student

● Let’s review how these classes are implemented

Inheritance Diagram

BrownStudent

BrownCSStudent

CS15Student CS17Student

Inheritance - Review (Part II)

4 of 58

Inheritance - Review (Part III)

● The BrownStudent class implements the method study

● When told to study, a BrownStudent will go to the SciLi, open a book, read, check Facebook, and then take a nap

public class BrownStudent {

/* Constructor elided */

public void study() { this.goToSciLi(); this.openBook(); this.read(); this.checkFacebook(); this.takeNap(); }}

5 of 58

public class BrownCSStudent extends BrownStudent {

public BrownCSStudent() { // constructor code goes here! }

@Override public void study() { this.goToSunlab(); this.logIn(); this.reviewLectureSlides(); }

public void code() { // code to code (ha) goes here! }}

● BrownCSStudent extends BrownStudent, so it automatically inherits the study method

● However, since BrownCSStudents study completely differently than normal BrownStudents, BrownCSStudent’s study() overrides BrownStudent’s study()

● When an instance of BrownCSStudent is told to study, she will go to the Sunlab, log in, and review lecture slides

6 of 58

● BrownCSStudent class also defines its own method that other BrownStudents don’t have: code

● This means the code method may be called on any BrownCSStudent, but not just on any BrownStudent

public class BrownCSStudent extends BrownStudent {

public BrownCSStudent() { // constructor code goes here! }

@Override public void study() { this.goToSunlab(); this.logIn(); this.reviewLectureSlides(); }

public void code() { // code to code (ha) goes here! }}

7 of 58

public class CS15Student extends BrownCSStudent {

/* Constructor elided */

@Override public void study() { super.study(); this.startYesterday(); }

public void startYesterday() { // implementation elided }}

● CS15Student extends BrownCSStudent, so it automatically inherits the study and code methods

● Since CS15Students code the same way all BrownCSStudents do, CS15Student does not override that method

● However, CS15Student needs to add additional, specialized steps to generic BrownCSStudent’s study method

8 of 58

● The CS15Student class partially overrides BrownCSStudent’s study method.

● First, the study method calls super.study() to execute the superclass’s version of the method.

● After this is done, the CS15Student will have gone to the Sunlab, logged in, and reviewed lecture slides. She’s now ready to start coding her project super early!

public class CS15Student extends BrownCSStudent {

/* Constructor elided */

@Override public void study() { super.study(); this.startYesterday(); }

public void startYesterday() { // implementation elided }}

9 of 58

Making sure superclass’s instance variables are initialized

public class Convertible extends Vehicle {

private ConvertibleTop _top;

public Convertible() { // how does _driver get // initialized? _top = new ConvertibleTop(); }

public void dragRace() { this.getDriver().stepOnIt(); }}

● Convertible may declare its own instance variables, which it initializes in its constructor

● Wait… when we instantiate a Convertible, how do superclass Vehicle’s private instance variables get initialized?

10 of 58

super(): Invoking Superclass’s Constructor

public class Convertible extends Vehicle {

private ConvertibleTop _top;

public Convertible() { super(); _top = new ConvertibleTop(); }

public void dragRace() { this.getDriver().stepOnIt(); }}

● Vehicle’s instance variables (like _driver) are initialized in Vehicle’s constructor

● To make sure that _driver is initialized whenever we instantiate a Convertible, we need to call the superclass’s constructor

● The syntax for doing this is “super()”

● Here super() is parent’s constructor; before it was the parent itself (verb vs. noun) 11 of 58

public class Convertible extends Vehicle {

private ConvertibleTop _top;

public Convertible() { super(); _top = new ConvertibleTop(); }

public void dragRace() { this.getDriver().stepOnIt(); }}

● We call super from the subclass’s constructor to make sure the superclass’s instance variables are initialized properly

● Can only make this call once, and it must be the very first line in the subclass’s constructor

o This rule doesn’t apply for calling any of superclass’s other methods

super(): Invoking Superclass’s Constructor

12 of 58

Method

Met

hod

Method

Method Method

MutatorMethod

Met

hod

Accessor

Method

inherited from

superclass

defined by

subclass

Instance Vars

public class Vehicle {

private Human _driver;

public Vehicle(Human driver) { _driver = driver; }

public void setDriver(Human driver) { _driver = driver; }

public Human getDriver() { return _driver; }}

● What if the superclass’s constructor takes in a parameter?

● We’ve modified Vehicle’s constructor to take in a Human as a parameter, rather than instantiating one itself

● After all, doesn’t really make sense for a car to create its driver-- we should be able to create a Vehicle for a pre-existing Human to drive

● How do we invoke this constructor correctly from the subclass?

super(): Invoking Superclass’s Constructor

14 of 58

public class Convertible extends Vehicle {

private ConvertibleTop _top;

public Convertible(Human driver) { super(driver); _top = new ConvertibleTop(); }

public void dragRace() { this.getDriver().stepOnIt(); }}

● In this case, need the Convertible’s constructor to also take in a Human

● This way, Convertible can pass on the instance of Human it receives to Vehicle’s constructor

● The Human is passed as an argument to super-- now Vehicle’s constructor will initialize _driver to the instance of Human that was passed to the Convertible

super(): Invoking Superclass’s Constructor

15 of 58

public class Convertible extends Vehicle {

private ConvertibleTop _top;

public Convertible(Human driver) { // oops! We forgot to call super _top = new ConvertibleTop(); }

public void dragRace() this.getDriver().stepOnIt(); }}

● What if we forget to call super()?

● If you don’t explicitly call super() first thing in your constructor, Java automatically calls it for you, passing in no arguments

● But if superclass’s constructor requires a parameter, you’ll get an error!

● In this case, we get a compiler error saying that there is no constructor “public Vehicle()” since it was declared with a parameter

What if we don’t call super()?

16 of 58

public class Convertible extends Vehicle {

private ConvertibleTop _top;

public Convertible(Human driver) { super(driver); _top = new ConvertibleTop(); }

public void dragRace() { this.getDriver().stepOnIt(); }}

● When calling superclass’s constructor in subclass’s constructor:

o can only call super() once!

o must be first

● When calling any other methods of superclass (for example, when partially overriding methods) these rules don’t apply

o call super.<method>() however many times you want, from wherever you want

super: The Rules

17 of 58

● super(), the superclass constructor, only initializes the superclass’ instance variables. It does not create an instance of the superclass (with abstract classes you can’t even create an instance – next slide)

● You cannot call something like super.super to access grandparent’s method implementations. This would violate encapsulation—a subclass should act like its parent, not its grandparent

● When overriding a superclass’s method, you must preserve its signature (name; number, order & type of parameters)

Inheritance: Clarifications

18 of 58

abstract Methods and abstract Classes

● Every Vehicle should know how to move

● Makes sense to declare a move method in the Vehicle class

● But how would we fill it in? Vehicles are varied enough that each subclass would need to fully override the method-- airplanes and bicycles are both vehicles, but move completely differently

19 of 58

abstract Methods and abstract Classes

● We declare a method abstract when any implementation in the superclass doesn’t make sense

● In this case, we know that all Vehicles should move, but each subclass will move very differently

● abstract method is declared in superclass, but not defined-- up to subclasses farther down hierarchy to provide their own implementations

20 of 58

public abstract class Vehicle {

private Human _driver;

public Vehicle(Human driver) { _driver = driver; }

public abstract void move();

/* Other methods elided */}

● Here, we’ve modified Vehicle to make move an abstract method

● We therefore also declare Vehicle abstract: if one of a class’s methods is abstract, class itself must also be declared abstract

● An abstract method is only declared by the superclass, not implemented-- use semicolon after declaration instead of curly braces

abstract Methods and abstract Classes

21 of 58

public class CS15Mobile extends Vehicle { /* Other methods elided */

@Override public void move() { // code to move at moderate // speed }}

public class Convertible extends Vehicle { /* Other methods elided */

@Override public void move() { // code to move super fast! }}

public class Van extends Vehicle {

/* Other methods elided */

@Override public void move() { // code to putter along // slowly }}

● All concrete subclasses of Vehicle provide an implementation for Vehicle’s abstract move method

● Method signature must match the one that Vehicle declared

22 of 58

● abstract classes cannot be instantiated!

o this makes sense-- shouldn’t be able to just instantiate a generic Vehicle

o instead, provide implementation of move in concrete subclass, and instantiate subclass

● Subclass at any level in inheritance hierarchy can make abstract method concrete by providing implementation

● Even though abstract class can’t be instantiated, its constructor must still be invoked via super() by a subclass (to initialize its own instance variables)

abstract Methods and abstract Classes

23 of 58

Under the Hood: Method Resolution● When we call move on some instance of Van, or study on

some instance of CS15Student, how does Java know which version of the method to call?

● Starts by looking at the instance’s class, regardless of where class is in the inheritance hierarchy

o If method is defined in the instance’s class, Java calls it

o Otherwise, it checks the superclass

- If method is explicitly defined in superclass, Java calls it

- Otherwise, checks the superclass up one level…etc.24 of 58

Under the Hood: Method Resolution

● Essentially, Java “walks up the class inheritance tree” from subclass to superclass until it either:

o finds the method, and calls it

o doesn’t find the method, and generates a compile-time error. You can’t send a message for which there is no method!

BrownStudent

BrownCSStudent

CS15Student

study

studycode

study

25 of 58

● This process is called method resolution o When we call study on a

CS15Student instance, CS15Student’s implementation of study is called

o When we call code on a CS15Student, BrownCSStudent’s implementation of code is called

Under the Hood: Method Resolution

BrownStudent

BrownCSStudent

CS15Student

study

studycode

study

26 of 58

That’s It For Inheritance!

● Things you might find in an inheritance hierarchy:o superclass specifies a method, and subclasses inherit it

o superclass not only defines general methods common to all subclasses, but each subclass adds its own specialized methods

o superclass delegates implementation of an abstract method to its subclasses

o superclass specifies a method, and subclasses choose to completely override it

o superclass specifies a method, and subclasses choose to partially override it, thus making use of parent’s code but augmenting it

27 of 58

Demo!

28 of 58

Modeling Similarity● Subclasses can respond to

same message in different ways

o Sportscar, CS15Mobile, and Van all responded to move() slightly differently

● These three classes have a lot in common

● Makes sense to model this similarity with Vehicle inheritance hierarchy

29 of 58

● What if a group of classes has very little in common, except for the ability to respond to a particular message?

● Vehicle, Animal, Ball might all have a move method

● They have almost nothing else in common, except for being Objects

● Doesn’t make sense to model this with inheritance hierarchy

Modeling Similarity

30 of 58

Introducing… Interfaces!

● Interfaces model similar capabilities of classes that might otherwise be very different

● Interfaces model “act as” relationships while inheritance models “is a”

● Vehicle, Animal, and Ball all could implement a Mover interface, because they can all “act as” Movers: objects that have the capability to move

● They could implement Move in their own way without using Mover interface, but implementing it induces consistency, and lets compiler check that they’ve done it consistently

31 of 58

Interfaces

● An interface’s only role is to declare methods that all implementing classes must have

● It cannot define any of these methods

● Every class that implements a particular interface must define all methods declared in the interface (if it’s an abstract class, may leave definition to concrete subclasses)

o interface acts as a contract that Java can enforce

● An interface is similar to an abstract superclass, but even more abstract—every single method is abstract

32 of 58

Why Interfaces?

● A class may only extend one superclass, but it may implement an unlimited number of interfaces!

● A class may extend a superclass and also implement any number of interfaces

● Basically, interfaces are super flexible and general!

● No code sharing - purely a contract that Java can enforce

● See their real power in next lecture on polymorphism…

33 of 58

Interface Example

public interface Mover {

public void move();

}

● Here’s the Mover interface!

● (Yep, that’s the whole thing)

● An interface belongs in its own .java file, just as a class does. The Mover interface would be in the file Mover.java

34 of 58

Interface Example

● Notice we declare it as an interface rather than a class

public interface Mover {

public void move();

}

35 of 58

Interface Example

● Here, we declare the methods that all implementing classes must define - the contract

● In this case, only one method is required: move

● An interface’s methods are by definition abstract, so we can leave out that keyword

public interface Mover {

public void move();

}

36 of 58

Interface Example

● Interfaces are not allowed to define any methods! Can only declare them

● That’s why we end method declaration with semicolon rather than curly braces

public interface Mover {

public void move();

}

37 of 58

Implementing an Interface: Concrete Class

public class Ball {

public Ball() { // this is the constructor }

public void bounce() { // code for ball to bounce }

}

● Let’s modify concrete class Ball so that it implements the Mover interface

● Right now, Ball only has one method: bounce

38 of 58

Implementing an Interface: Concrete Class

public class Ball implements Mover {

public Ball() { // this is the constructor }

public void bounce() { // code for ball to bounce }

}

● First, add “implements Mover” to class declaration

● This promises the compiler that Ball will define all methods in the Mover interface: in this case, the move method

39 of 58

Implementing an Interface: Concrete Class

public class Ball implements Mover {

public Ball() { // this is the constructor }

public void bounce() { // code for ball to bounce }

public void move() { // code for ball to move }}

● Next, honor the contract by defining move method

● Method signature (name and number/type of arguments) must match method signature declared in interface

● If Mover had multiple methods, Ball would have to implement all of them

40 of 58

Implementing an Interface: Abstract Class

public abstract class Vehicle {

private Human _driver;

public Vehicle(Human driver) { _driver = driver; }

public abstract void move();

/* Other methods elided */}

● Let’s look at abstract superclass Vehicle and its subclasses

● Now we’ll modify this example so Vehicle implements the Mover interface

41 of 58

public abstract class Vehicle implements Mover {

private Human _driver;

public Vehicle(Human driver) { _driver = driver; }

public abstract void move();

/* Other methods elided */}

● First, we add “implements Mover” to class declaration

● Now we’ve promised that all Vehicles will know how to move

● This means that everything that “is a” Vehicle (all subclasses of Vehicle) must know how to move

Implementing an Interface: Abstract Class

42 of 58

public abstract class Vehicle implements Mover {

private Human _driver;

public Vehicle(Human driver) { _driver = driver; }

public abstract void move();

/* Other methods elided */}

● Previously declared abstract move method to make sure all concrete subclasses implemented it

● Now that Vehicle implements Mover, this declaration is no longer necessary-- all subclasses now also must implement Mover by default

Implementing an Interface: Abstract Class

43 of 58

public abstract class Vehicle implements Mover {

private Human _driver;

public Vehicle(Human driver) { _driver = driver; }

/* Other methods elided */}

● Compiler wouldn’t yell at us for leaving move declaration in there, but we’ll take it out since it’s now redundant, given the Mover interface

Implementing an Interface: Abstract Class

44 of 58

public class Sportscar extends Vehicle {

/* Other methods elided */

@Override public void move() { // code to move super fast! }}

● Concrete subclass Sportscar must define move method!

● Don’t have to specify in class declaration that Sportscar “implements Mover”—this is implicit since we’ve already declared superclass Vehicle implements Mover

Implementing an Interface: Concrete Subclass

45 of 58

Another Interface Example

import java.awt.Color;

public interface Colorable {

public void setColor(Color color); public Color getColor();

}

● Here’s code for another interface that Ball might implement: Colorable

● This interface declares accessor and mutator methods for an object’s color

● Again, note the ;) instead of braces with an actual body – it’s a contract, not an implementation!

46 of 58

import java.awt.Color;

public class Ball implements Mover, Colorable {

private Color _color;

public Ball() { _color = Color.WHITE; }

public void move() { // code for ball to move }

public void setColor(Color color) { _color = color; }

public Color getColor() { return _color; } // other methods elided}

● Now we’ve modified the Ball class to implement two interfaces: Mover and Colorable

● Let’s walk through how we’ve implemented the Colorable interface and defined the capabilities it declares

47 of 58

● We’ve added Colorable to the class declaration as an implemented interface

● All of a class’s implemented interfaces are declared in a comma-separated list

● If we wanted Ball to also extend a superclass, the declaration might look something like “public class Ball extends SportsEquipment implements Mover, Colorable {”

import java.awt.Color;

public class Ball implements Mover, Colorable {

private Color _color;

public Ball() { _color = Color.WHITE; }

public void move() { // code for ball to move }

public void setColor(Color color) { _color = color; }

public Color getColor() { return _color; } // other methods elided}

48 of 58

● The Colorable interface declares accessor and mutator methods for an instance variable

● Ball creates an instance variable called _color and gives it an initial value in the constructor

import java.awt.Color;

public class Ball implements Mover, Colorable {

private Color _color;

public Ball() { _color = Color.WHITE; }

public void move() { // code for ball to move }

public void setColor(Color color) { _color = color; }

public Color getColor() { return _color; } // other methods elided}

49 of 58

● We follow the standard pattern for accessor and mutator methods to define setColor and getColor

import java.awt.Color;

public class Ball implements Mover, Colorable {

private Color _color;

public Ball() { _color = Color.WHITE; }

public void move() { // code for ball to move }

public void setColor(Color color) { _color = color; }

public Color getColor() { return _color; } // other methods elided}

50 of 58

● What happens if we forget to define a method declared by an implemented interface?

● We get a compiler error, because we didn’t fulfill the contract laid out by the interface!

import java.awt.Color;

public class Ball implements Mover, Colorable {

private Color _color;

public Ball() { _color = Color.WHITE; }

public void move() { // code for ball to move }

public void setColor(Color color) { _color = color; }

// // oops! We forgot to define getColor! //

}51 of 58

Conflicting Methods in Two Interfaces

What if a class implements two interfaces that contain a method of the same name?

● If they have same exact signature, i.e., not only identical name but also parameter list, they should specify same behavior, so only need to define method once

● If they have different signatures, should specify different behaviors, and must define each method separately

● Note: return types are not part of a method’s signature—”The compiler does not consider return type when differentiating methods, so you cannot declare two methods with the same signature even if they have a different return type.” <JavaDocs>

52 of 58

Interfaces & Inheritance

● Like classes, interfaces can extend other interfaces...

● But interfaces can extend any number of other interfaces

o This is because interfaces never specify implementation

o To extend multiple interfaces, just provide interfaces as a comma-separated list after keyword “extends”: for example, “public interface Artistic extends Colorable, Decorable”

53 of 58

Classes vs. InterfacesClass:

● Models an object with properties and capabilities

● Factors out common properties and capabilities of similar objects

● Declares methods and may define some or all of them

● Can extend only one superclass (but can implement any number of interfaces)

Interface:

● Models a role; defines a set of responsibilities

● Factors out common capabilities, not properties, of (often) dissimilar objects

● Declares but does not define methods

● Can extend multiple interfaces

54 of 58

“Plastics” Interface Example

● What if we defined an interface for being a Plastic? After all being a Plastic is a contract.

● Can you think of any more methods that might go in this interface?

public interface Plastic {

public void onWednesdaysWeWearPink();

}

55 of 58

● Interfaces factor out common capabilities from otherwise unrelated objects. They model an “acts as” relationship

● An interface defines a contractual obligation

o implementing classes must provide definitions for all methods declared in interface

o Java compiler verifies this at compile-time

● A class can implement as many interfaces as it wants, and an interface can extend as many interfaces as it want

● The core Java library uses interfaces a lot, especially for graphics

Interfaces: Summary

56 of 58

Why Use Interfaces?

● Interfaces are a way to provide a ‘checklist’ of methods that a class should implement--this makes it easier for the compiler to check for errors

● This isn’t that strong a motivation: different classes (like Ball and Vehicle) could all just declare separate move methods on their own without implementing an interface

● The real motivation for interfaces is polymorphism; stay tuned for next lecture

57 of 58

Collaboration

● We already found 2 cases of disallowed collaboration on HW2 with nearly identical wording of wrong answers. Video is for fun; message is serious.

58 of 58

Announcements

59 of 59

• LiteBrite early handin tonight at 11:59PM, on time Thursday at 11:59PM, and late Saturday at 10:00PM

• TASafehouse project and DQs out Thursday. DQs due Sunday at 2PM, TASafehouse help session Sunday at 6PM.