You are on page 1of 52

CSE/IT 213 New Mexico Tech

September 18, 2011

Overloading methods
Not the same as overriding a method
Methods in subclasses that have different signatures
(parameter types)
Can have different return types as well
Can change access modifier

Overriding Methods
Have to have the same signature
Have to have compatible return types
class Animal {
public Animal getSnack() {
....
}
}
class Dog extends Animal {
public Dog getSnack() {
...
}
}
2

This is okay because a sublcass can do anything a parent class can do.
Have to keep the access levels the same or less restrictive
Cant go from public to private, but can go from
private to public.
Usually keep access levels the same
Overriding leads to polymorphism

Polymorphism
Polymorphism allows the reference type and object type
to be different.
You can treat specialized objects as more general types
of objects while still taking advantage of their specialized behaviors.
Dynamic binding happens at runtime
Use @override annotation

class Animal

public void sleep() {


System.out.println("The animals are sleeping");
}
public static void main(String[] args) {
Animal [] animalFarm = new Animal[4];
animalFarm[0] = new Animal();
animalFarm[1] = new Pig();
animalFarm[2] = new Horse();
animalFarm[3] = new Dog();
4

for ( Animal a : animalFarm) {


a.sleep();
}
}
}
class Dog extends Animal {
public void sleep() {
System.out.println("Dog is sleeping");
}
}

class Pig extends Animal {


public void sleep() {
System.out.println("Pig is sleeping");
}
}
class Horse extends Animal {
public void sleep() {
System.out.println("Horse is sleeping");
}
}
5

$ java Animal
The animals are sleeping
Pig is sleeping
Horse is sleeping
Dog is sleeping

Loops through array animalFarm and calls the Animal


sleep method, but knows how to call the right subclass
method.
Allows you to write flexible code
Polymorphism allows you to use superclass types as
argument types, return types, and array types.
Get to add new subtypes without rewriting code to deal
with the new subtypes.

class Animal

public void sleep() {


System.out.println("The animals are sleeping");
}
public static void main(String[] args) {
Animal [] animalFarm = new Animal[4];
animalFarm[0] = new Animal();
animalFarm[1] = new Pig();
animalFarm[2] = new Horse();
animalFarm[3] = new Dog();
Food food = new Food;
8

for ( Animal a : animalFarm) {


a.sleep();
food.getFood(a);
}
}
}
class Food {
public void getFood(Animal a) {
System.out.println(a.getFood());
}
}

class Dog extends Animal {


@override
public void sleep() {
System.out.println("Dog is sleeping");
}
public String getFood() {
return "dog eat dog food";
}
}

class Pig extends Animal {


@override
public void sleep() {
System.out.println("Pig is sleeping");
}
public String getFood() {
return "pigs eat slop";
}

class Horse extends Animal {


public void sleep() {
System.out.println("Horse is sleeping");
}
public String getFood() {
return "horses love hay";
}

10

$ java Animal
The animals are sleeping
animals eat everything
Pig is sleeping
pigs eat slop
Horse is sleeping
horses love hay
Dog is sleeping
dog eat dog food

11

Any class that extends Animal would also work in the


Food class.
This means you can write code for objects that dont
exist.

12

Abstract Classes
The above example is bad design
You really wont ever create a new Animal()
What is an Animal really?
Class Animal describes general characteristics that subclasses will inherit.
No need to implement specific methods for class Animal
Do this by declaring classes abstract, a YAM
13

class AnimalTest {
public static void main(String[] args) {
Animal [] animalFarm = new Animal[3];
animalFarm[0] = new Pig();
animalFarm[1] = new Horse();
animalFarm[2] = new Dog();
Food food = new Food();
for ( Animal a : animalFarm) {
a.sleep();
food.getFood(a);
}
}
14

}
abstract class Animal

abstract public void sleep();


abstract public String getFood();
}
$ java AnimalTest
Pig is sleeping
pigs eat slop
Horse is sleeping
horses love hay

Dog is sleeping
dog eat dog food

Abstract methods have no body terminate signature


with semi-colon.
If a class contains one or more abstract methods, must
declare class abstract
Can mix and match. Classes can contain a combination
of abstract and non-abstract methods
Key cannot instantiate any class that is declared
abstract

15

This throws a compiler error


class AnimalTest {
public static void main(String[] args) {
Animal b = new Animal();
Animal [] animalFarm = new Animal[3];
animalFarm[0] = new Pig();
animalFarm[1] = new Horse();
animalFarm[2] = new Dog();
Food food = new Food();
for ( Animal a : animalFarm) {
16

a.sleep();
food.getFood(a);
}
}
}
$ javac AnimalTest.java
AnimalTest.java:5: Animal is abstract; cannot be instantiated
Animal b = new Animal();

What about the Array declaration?


work?

Why does that

Animal [] animalFarm = new Animal[3];


Java only creates reference variables in Array declarations. So this is okay.
From the Java Language Specification: Arrays with
an abstract class type as the component type are allowed. The elements of such an array may have as
their value a null reference or instances of any subclass
of the abstract class that is not itself abstract.
17

To use an abstract class, it must be subclassed and its


abstract methods overridden with methods that implement a body.
Subclasses do not need to implement all abstract methods, but if doesnt need to be declared abstract as well.
Abstract classes and methods provide a framework.
The details are implemented in the subclasses.
Abstract classes need to be extended.
Abstract methods need to overridden.
18

Say you had this class hierarchy


abstract class Animal
abstract class Mammal
abstract class Canine
class Dog
class Dog would have to implement all abstract methods from Animal, Mammal, and Canine.
Somewhere along the line, abstract methods must have
their body implemented.
Java has abstract and concrete classes. Concrete classes
implement abstract classes.
The first concrete class must implement all abstract
methods.
19

ArrayList Revisited
Every class extends Object
The mother of all classes think polymorphic!
ArrayList has a bunch of methods that return or has
parameters that are Objects
public Object clone()
Returns a shallow copy of this ArrayList instance.
public boolean remove(Object o)
Removes the first occurrence of the specified element
from this list, if it is present.
20

import java.util.*;
class AnimalTest {
public static void main(String[] args) {
ArrayList<Animal> animalFarm = new ArrayList<Animal>();
Pig pig = new Pig();
animalFarm.add(pig);
Horse horse = new Horse();
animalFarm.add(horse);
Dog dog = new Dog();
animalFarm.add(dog);
Food food = new Food();
21

for (int i = 0; i < animalFarm.size(); i++) {


animalFarm.get(i).sleep();
food.getFood(animalFarm.get(i));
}
}
}
$ java AnimalTest
Pig is sleeping
pigs eat slop
Horse is sleeping
horses love hay
Dog is sleeping
dog eat dog food

If everything is an object, should be able to use it as


polymorphic argument.
import java.util.*;
class AnimalTest {
public static void main(String[] args) {
ArrayList<Object> animalFarm = new ArrayList<Object>();
Pig pig = new Pig();
animalFarm.add(pig);
Horse horse = new Horse();
animalFarm.add(horse);
Dog dog = new Dog();
animalFarm.add(dog);
22

Food food = new Food();


for (int i = 0; i < animalFarm.size(); i++) {
animalFarm.get(i).sleep();
food.getFood(animalFarm.get(i));
}
}
}
$javac AnimalTest.java
AnimalTest.java:16: cannot find symbol
symbol : method sleep()
location: class java.lang.Object
animalFarm.get(i).sleep();
^

AnimalTest.java:17: getFood(Animal) in Food


cannot be applied to (java.lang.Object)
food.getFood(animalFarm.get(i));
^
2 errors

Why the errors?


Class Object has no idea about the existence of Animal.sleep()
and Food.getFood() methods.
The references to Object destroys their Animalness.
Calling on references here. Methods must be part of
the classes reference type. Makes no difference what
the object is actually is.
Compiler checks the reference variable for available methods not the object on the right-hand side of the assignment.
23

This works - calls are to methods in the Object class.

import java.util.*;
class AnimalTest {
public static void main(String[] args) {
ArrayList<Object> animalFarm = new ArrayList<Object>();
Pig pig = new Pig();
animalFarm.add(pig);
Horse horse = new Horse();
animalFarm.add(horse);
for (int i = 0; i < animalFarm.size(); i++) {
System.out.println("getClass(): " +
24

animalFarm.get(i).getClass());
System.out.println("hashCode(): " +
animalFarm.get(i).hashCode());
System.out.println("toString(): " +
animalFarm.get(i).toString());
}
}
}
$ java AnimalTest
getClass(): class Pig
hashCode(): 870314914
toString(): Pig@33dff3a2
getClass(): class Horse
hashCode(): 871639881
toString(): Horse@33f42b49

Another example
Added new method to dog class bark().

class Dog extends Animal {


public void sleep() {
System.out.println("Dog is sleeping");
}
public void bark() {
System.out.println("woof! woof!");
}
}
25

import java.util.*;
class AnimalTest {
public static void main(String[] args) {
ArrayList<Animal> animalFarm = new ArrayList<Animal>();
Pig pig = new Pig();
animalFarm.add(pig);
Horse horse = new Horse();
animalFarm.add(horse);
Dog dog = new Dog();
animalFarm.add(dog);
for (int i = 0; i < animalFarm.size(); i++) {
if (animalFarm.get(i) instanceof Dog) {

animalFarm.get(i).bark();
}
}
}
}
$ javac AnimalTest.java
AnimalTest.java:17: cannot find symbol
symbol : method bark()
location: class Animal
animalFarm.get(i).bark();

The ArrayList is of type Animal. Those references only


know about Animals (or its parent classes), not about
Dogs.
The fix cast the object back to a Dog. (Will see a
better fix later - generics)
Make sure object is what you are casting it to. Otherwise will produce a ClassCastException error at runtime, crashing the program

26

This will make the dog bark...


import java.util.*;
class AnimalTest {
public static void main(String[] args) {
ArrayList<Animal> animalFarm = new ArrayList<Animal>();
Pig pig = new Pig();
animalFarm.add(pig);
Horse horse = new Horse();
animalFarm.add(horse);
Dog dog = new Dog();
animalFarm.add(dog);
for (int i = 0; i < animalFarm.size(); i++) {
27

if (animalFarm.get(i) instanceof Dog) {


Dog d = (Dog) animalFarm.get(i);
d.bark();
}
}
}
}
$ java AnimalTest
woof! woof!

Bottom Line
Can only call method if the class of the reference variable has that method.

28

Interfaces
What do you do if you want to use Dog in a new way?
If I want to use it in a Vet class.
Do I have to add abstract methods to the Animal class?
If so, I have to implement them and is every animal
going to see a vet?
If I put the new Vet methods only inside the classes that
need them, then I destroy polymorphism.

29

If we could inherit more than one class....but Java only


has single inheritance mechanism.
Problems with multiple inheritance.
Suppose we have the following classes
class Player {
play();
}
class CDPlaer extends Player() {
play();
}
class DVDPlayer extends Player() {
play();
30

}
class BluRayPlayer extends Player() {
play();
}
What happens when you want to create an Universal
Player, one that plays CDs, DVDs, and Blu-Ray? What
play() method would you call if you inherited all three?

Java uses Interfaces to get around the need for multiple


inheritance.
Interfaces are easy to declare. All methods are declared
abstract.
Subclasses must implement the methods. abstract methods must be implemented in the first concrete subclass.

31

To define an interface
public interface <ClassName> { }
To implement an interface use the implements keyword
public class <ClassName> extends <ParentClass> implements
<100% Abstract Class> {}
For example
public class Dog extends Animal implements Vet {}

32

Interface syntax
For methods
just need the return type, the signature followed by a
semi-colon.
No need for public abstract implicitly defined for you
//delaration
interface Vet {
boolean isSick();
Date takeShot();
}
33

//implementation
class Dog extends Animal implements Vet {
public boolean isSick() {
....
}
public Data takeShot() {
....
}
}

Interfaces are polymorphic.


Interface can be used as return types and arguments.
Anything that implements the interface can be used as
the return value or as an argument.
Classes from different inheritance trees can implement
the same interface.
When you use polymorphic classes as return and parameter types, objects of subclasses must be from the
same inheritance tree.

34

If you want to use interfaces in a polymorphic manner,


i.e. use them as return and parameter types, can use
objects of classes that implement the interface. No
requirement that they share any ancestry.
Classes can implement multiple interfaces
class Dog extends Animal implements Vet, Pet, Canine

35

You might also like