Beruflich Dokumente
Kultur Dokumente
2
COMBINING OBJECTS: ASSOCIATION RELATIONSHIPS (1)
3
COMBINING OBJECTS: ASSOCIATION RELATIONSHIPS (2)
this.name = name;
this.coordinates = coordinates;
this.speed = speed;
this.totalDistance = totalDistance;
this.repairDistance = repairDistance;
4
REPRESENTING ASSOCIATION RELATIONSHIPS IN CLASS DIAGRAMS (1)
• The first number represents the lower bound (the least number of
objects of Class B there can be stored in Class A).
• The second number (following the three dots) represents the upper
bound (the maximum number number of Class B objects there can be
in Class A).
😴 8
OBJECT OWNERSHIP (2)
• All the instances of Class B that are used by Class A only exist
within instances of Class A.
We place a filled
diamond next to the
class that owns
objects of the
connected class, to
differentiate
composition from
association.
12
OBJECTIVES: COMBINING OBJECTS
• Inheriting from a class such that (an object of) one class
IS-A (object of an)other class.
We will also:
14
A MEDIEVAL VILLAGE
15
A VILLAGER
16
A VILLAGER: IN CODE
return name;
} 17
A SWORDSMAN
18
A SWORDSMAN: IN CODE (FIRST PASS)
20
FLEXIBLE OBJECTS (2)
}
public String getAttack() {
Villager.java
}
Swordsman.java
Part of this issue comes from the fact that with a HAS-A
relationship we are only able to express when things own other
things not when they are other things, and thus share a common
interface.
How do we do this? 23
CLASS INHERITANCE (1)
public name)
public Villager(String class {Swordsman extends Villager {
this.name = name;
public Swordsman(String name) {
} super(name);
}
🤓 24
CLASS INHERITANCE (2)
One class inherits (copies) all of the code from another, thus
assuming the same interface.
🤓 25
CLASS INHERITANCE (3)
28
INDICATING INHERITANCE IN A CLASS DIAGRAM
29
CONCEPTUAL INHERITANCE
Like most of the concepts in object-oriented programming the
concept of inheritance is linked to the real world.
}
Swordsman.java
} 32
THE EXTENDS KEYWORD (2): WHAT CAN WE ACCESS (2)
} 33
THE EXTENDS KEYWORD (2): WHAT CAN WE ACCESS (3)
}
From
Swordsman.java
Villager
} }
currentPage = 1;
this.totalPages = totalPages;
public Book() {
currentPage = 1;
this(0);
totalPages = 0;
} }
We can’t override fields from the parent class in the same way.
this.answer = answer;
this.mark = mark;
return answer;
}
41
The next few slides are tough, stay with me…
42
POLYMORPHISM (1)
43
BACK TO THE MEDIEVAL VILLAGE (FIRST PASS)
44
INHERITANCE AND TYPES
We’ve seen that both arrays and arraylists can only store values
of the same type.
🤓 46
POLYMORPHISM (3)
We can iterate through this list, and call any method in the
parent type.
🤓 48
THE VILLAGE (FIRST PASS): POLYMORPHISM (AND FIGHTING TROLLS) (2)
We can iterate through this list, and call any method in the parent
type.
Villagers and
Swordsman share a
common interface, but
Villager Swordsman this doesn’t mean that
the Swordsman cannot
add to this interface
(more shortly).
50
POLYMORPHISM (METHODS AND RETURN TYPES) (1)
}
Any type of Villager
public void addVillager(Villager villager) { can be added to a
villagers.add(villager); Village.
}
villagers.add(randomVillager());
}
🤓 51
POLYMORPHISM (METHODS AND RETURN TYPES) (2)
System.out.println(fight(villager));
Village.java 🤓 52
POLYMORPHISM (METHODS AND RETURN TYPES) (3)
Village.java 🤓 53
TROLL FIGHT (PART 1)
village.addRandomVillager();
village.allFight();
54
POLYMORPHISM (REUSABILITY)
🤓 55
Inheritance And The Java Library
56
OBJECT
In a driving class:
Coordinates planeCoordinates = new Coordinates(10, 30);
System.out.println(planeCoordinates);
😴 58
TOSTRING
60
REMEMBER: BACK TO COPYING STRINGS: ASKING ABOUT COPIES
String a = "A";
We ask the JVM, `are you sharing the
String b = "A"; same string copy between a and b’?
String d = "A";
System.out.println(a == b);
This answer one of our open questions
} about the flexibility of relational
operators.
In order to confirm that the JVM is sharing copies between
our variables, we can use the familiar comparison operator.
System.out.println(mart + in);
System.out.println(martin);
System.out.println(martin == mart + in);
System.out.println(martin.equals(mart + in));
}
😴 62
COMPARING OBJECTS (1)
Because Strings are objects, then the way in which objects are
compared more generally should be similar to the way in which we
compare Strings.
• Like Strings, two objects may have similar values in their fields,
and thus be considered equal, but be held separately in memory.
village.addRandomVillager();
village.allFight();
66
BACK TO THE MEDIEVAL VILLAGE: MAGES
67
MAGES: IN CODE
} 68
POLYMORPHISM (METHODS AND RETURN TYPES) (2)
if ( selection == 0 ) {
...
totalDamage += villager.getDamage();
72
REMEMBER: ASIDE: CASTING
😴 73
THE DANGERS OF CASTING
74
INSTANCE OF
We need a way to look past the Villager interface and test the
actual type of the object in the array to see if it is of the same
type that we wish to cast to.
This operator
for ( Villager villager : villagers ) {
takes an object as
System.out.println(fight(villager)); its first operand
and a type as its
if ( villager instanceof Mage ) {
second.
damage += ((Mage)villager).getDamage();
}
Village.java
75
EXAMPLE: COMPARING COORDINATES (2): IMPLEMENTING EQUALS (1)
78
SERVICE PROVIDERS (1)
A valid question here is, why override equals? Why not simply compare objects
using a method with a name of our own choosing or just using accessor
methods?
• In our Noughts and Crosses game, we simply used a method called matches.
• In our Villager class, we saw that no matter which type of Villager (one
that already exists, or a new type) is passed to the fight method, they can
have the method getAttack invoked on them.
System.out.println(fight(villager));
🤓 80
SERVICE PROVIDERS (2)
To use this service (fight), we must pass an object that is capable of supporting
the task carried out by the service; an object that has a getAttack method; a
villager that can fight.
• This makes the service exclusive. We will look at this idea in the final
section of the topic.
• Otherwise the method from the superclass (Villager) will be called instead.
• If, for example, the string `Run Away’ were returned, then the output would
not be as expected. 81
SERVICE PROVIDERS (3)
System.out.println(coordinates.contains(aeroplaneCoordinates));
85
CONTAINS EXAMPLE: FINDING AN EQUAL COORDINATE (2)
Coordinates aeroplaneCoordinates =
new Coordinates(110, 135);
}
🙈 86
CONTAINS EXAMPLE: FINDING AN EQUAL COORDINATE (2)
ArrayList<Coordinates> coordinates
Coordinates aeroplaneCoordinates =
new Coordinates(110, 135);
return true;
ArrayList<Coordinates> coordinates
Coordinates aeroplaneCoordinates =
new Coordinates(110, 135);
😴 92
ASIDE: METHOD OVERLOADING AS A FORM OF POLYMORPHISM (1)
This idea extends to any method, such that we can use the same name
for two methods, so long as the parameters in those method are
different:
public void addVillagerToParty(Villager villager) {
villagers.add(villager);
This neatens things up
} if methods perform
public void addVillagerToParty() {
broadly the same
functionality, except
villagers.add(randomVillager()); rely on different input.
} 93
ASIDE: METHOD OVERLOADING AS A FORM OF POLYMORPHISM (1)
System.out.println(villager.getAttack());
return villager.getAttack();
} private
public String getAttack() {
Villager.java
return getName() + " swings a sword";
}
Swordsman.java
Given that access modifier and return type are not enough
to differentiate a method, is it ok if we change them in the
subclass (i.e. the overridden method)? 95
ASIDE: REDUCING VISIBILITY IN THE INTERFACE (2)
}
public String getAttack() {
Villager.java
return getName() + " swings a sword"; 96
ASIDE: CLASS HIERARCHY
😴 97
ASIDE: ARE HAS-A RELATIONSHIPS NOW USELESS? (1)
}
98
ASIDE: ARE HAS-A RELATIONSHIPS NOW USELESS? (2)
Can we extend this idea, such that we just ditch the HAS-A
relationship and extend everything? Absolutely not. Would
the following make sense?
100
TYING YOURSELF TO A SINGLE IS-A RELATIONSHIP
102
BACK TO THE VILLAGE… (2)
} return hitPoints;
} }
return true;
} Village.java TrollFight.java
103
THE FUN OF A TROLL (1)
}
}
} }
Village.java
public int getBashRange() { … }
105
BRINGING FRIENDS (2)
Werewolves can intimidate with their howl, but are too small
to bash, and giants can bash, but they do not shout.
public class Werewolf { public class Giant {
Because these two creatures can also fight with the villagers, we
could create a common super class Enemy, and place hit point
information inside this class, such that Troll, Werewolf and
Giant all extend this class:
Werewolf.java
private int hitPoints;
}
public class Troll extends Enemy {
public int getHitPoints() {
Troll.java
return hitPoints;
Then any enemy can fight:
}
Villager.java
107
SHOUTING AND BASHING (1)
108
SHOUTING AND BASHING (2)
} }
return phrase;
return bashRange;
}
}
}
}
109
SHOUTING AND BASHING (3)
} }
Village.java Village.java
public class Shouter extends Enemy { public class Basher extends Enemy {
111
GIVING THE TROLL WHAT HE WANTS
} }
Village.java Village.java
• The troll could tie himself to being a shouter, but then he also
can’t be be a basher (or an enemy) and thus can’t destroy, and
vice-versa.
But, in this case, the troll still cannot use the services offered by both
intimidate and destroy because it is still only one of these things (it
bashes like a troll but doesn’t shout like a troll).
115
THE PROBLEM WITH MULTIPLE INHERITANCE: IN SHORT
One class inherits (copies) all of the code from another, thus
assuming the same interface.
🤓 117
EMPTY METHODS? (1)
} }
What if all the classes we inherited from didn’t have any code
in their methods?
🤓 118
EMPTY METHODS? (2)
} }
🤓 119
EMPTY METHODS? (3)
} }
} }
In the previous slide we used the word interface in two different ways:
And hopefully it’s clear that this has nothing to do with graphical user
interfaces.
🤓 122
INTERFACES: RULES
} }
Because there are then rules for the form of this class.
🤓 123
INTERFACES: RULE 1 - EMPTY METHODS
} }
} }
125
INTERFACES: RULES 3 AND 4 - PUBLIC AND FIELDS
} }
} }
}
public Troll(String phrase, int bashRange) {
this.phrase = phrase;
this.bashRange = bashRange; public interface Shouter {
return phrase;
in the same way as
} overriding a Here we are saying that a Troll
method from a IS-A Shouter and IS-A Basher
public int getBashRange() {
superclass.
return bashRange;
so it has to behave like it.
At the same time, these methods know that only an object that
implements the interface type (e.g. Shouter and Basher), can be
passed as an argument.
} }
Village.java Village.java 129
NON-EXCLUSIVE SERVICE PROVIDERS (2)
} }
Village.java Village.java 130
THE FUN OF A TROLL (3)
public class Troll implements Shouter, Basher { And now the troll is free
private String phrase;
to intimidate and bash
private int bashRange; as he pleases, along with
public Troll(String phrase, int bashRange) {
his friends, should they
wish to:
this.phrase = phrase;
this.bashRange = bashRange; public void intimidate(Shouter shouter) {
} System.out.println(shouter.shout());
return bashRange; }
Village.java
} public class Werewolf implements Shouter {
132
IMPLEMENTING AN INTERFACE VS. EXTENDING A BASE CLASS (1)
• For example, should our methods now only accept interfaces for
maximum flexibility?
Base classes (that can be extended) and interfaces play different roles:
134
TREEMAP
137
IMPLEMENTING COMPARABLE (1)
} Customer.java
138
ASIDE: GENERIC INTERFACES
You will have noticed that we were able to type the Comparable
interface in the previous example in the same way that we can
type lists, using the diamond notation.
return name.compareTo(o.name);
} Customer.java
shop.addProduct(diamond);
shop.addProduct(crownJewels);
shop.addProduct(silverLocket);
shop.updateTotalSpend(martin, 100);
shop.updateTotalSpend(tomas, 100);
shop.updateTotalSpend(asad, 100);
System.out.println(shop.getCustomerTotalSpend());
141
IMPLEMENTING AN INTERFACE VS. EXTENDING A BASE CLASS (2)
144
COLLECTIONS AND INTERFACES
return shoppingBasket;
What if I want to store things
}
in a different format?
146
SWAPPING THE UNDERLYING IMPLEMENTATION (2)
return shoppingBasket;
} Lots of changes!
147
SWAPPING THE UNDERLYING IMPLEMENTATION (3)
return shoppingBasket;
148
SWAPPING THE UNDERLYING IMPLEMENTATION (4)
return shoppingBasket;
151
PARTIAL FUNCTIONALITY? (1)
This might suggest that List should be a normal base class, such
that this functionality can be inherited.
implements
extends
implements
implements
For
inherits readability
only
implements
156
ABSTRACT CLASSES: INTERFACE FEATURES
158
WHY ARE ABSTRACT CLASSES USEFUL? (2)
}
160
ASIDE: WHY WOULD I WANT TO INHIBIT INSTANCES OF A CLASS? (2)
But what is a ship? It doesn’t have a size, so it’s not really a thing;
it’s just part of an idea.
162
WHY WOULD WE WANT TO USE INTERFACE IN OUR OWN CODE?
if ( containsEdge(sourceVertex, targetVertex) ) {
// The unique cost to the traverser, based upon their traversals so far
double uniqueCost = 0.0;
System.out.println("Boo!");
An
}
implementation
of that interface.
});
165
REMEMBER: ASIDE: OBJECTS IN MEMORY
We’ll look at
this in more
detail next
semester.