תרגול מספר 9
1
אז מה נלמד היום?
• שעה ראשונה
– ממשקים Interfaces
• שעה שנייה:
– מחלקות אבסטקטיות abstract class
2
Interface
• Is a way for the coder to tell the compiler:
“limit me, make me work by the contract”.
• An interface is similar to a class but has many differences and
is used for different reasons.
• An interface declares public variables and methods,
but does not implement them.
• An interface will be implemented by classes.
Interface: example
public interface Predator
{
boolean chasePrey(Prey p);
void eatPrey(Prey p);
}
For example, a cat is a predator
because it eats mice.
A frog is also a predator
because it eats bugs.
So we will have:
public class Cat implements Predator
{
public boolean chasePrey(Prey p)
{
// code to chase prey p
// (specifically for a cat)
run();
}
public void eatPrey (Prey p)
{
// code to eat prey p
// (specifically for a cat)
chew(p);
swallow(p);
}
…
}
Interface: example
public interface Predator
{
boolean chasePrey(Prey p);
void eatPrey(Prey p);
}
public class Frog implements Predator
{
public boolean chasePrey(Prey p) {
// code to chase prey p
// (specifically for a frog)
jump();
}
public void eatPrey (Prey p) {
// code to eat prey p
// (specifically for a frog)
swallow(p);
}
*Remember: you cannot create an
object from an interface.
…
}
Interface
Another example –
public interface Vehicle {
public void startEngine();
public void honk();
public void drive(int speed);
}
A car is a vehicle.
A motorcycle is a vehicle.
A bus is a vehicle.
Interface
public interface Vehicle {
public void startEngine();
public void honk();
public void drive(int speed);
}
*Notice that Car has
a variable of its own (numOfDoors)
that not all vehicles will have.
For example,
a motorcycle does not have doors
So the variable is unnecessary
for the Motorcycle class.
public class Car implements Vehicle {
private int numOfDoors;
//Constructor:
public Car() {
numOfDoors = 4;
}
public void startEngine() {
//code to start the engine of a car
turnKey();
}
void honk(){
System.out.println (“beep beep”)
}
void drive(int speed) {
//code to drive specific for a car
}
}
Interface
public interface Vehicle {
public void startEngine();
public void honk();
public void drive(int speed);
}
*Notice that the motorcycle class
has an extra method
“popAWheelie”
that can only be done
by motorcycles.
None of the other vehicles
can pop a wheelie.
public class Motorcycle implements Vehicle
{
//constructor
public Motorcycle() {
}
public void startEngine() {
//code to start motorcycle engine
turnKey();
}
void honk(){
System.out.println(“waka waka”)
}
void drive(int speed) {
//code to drive a motorcycle
}
void popAWheelie() {
//code to pop a wheelie
}
}
Interface
public interface Vehicle {
public void startEngine();
public void honk();
public void drive(int speed);
}
*typeOfBus can be
“School Bus”
or
“City Bus”…
public class Bus implements Vehicle {
String typeOfBus;
//constructor
public Bus(String type) {
typeOfBus = type;
}
public void startEngine() {
//code to start the engine of a bus
}
void honk(){
System.out.println(“Blaaaaaaaaah”)
}
void drive(int speed) {
//code to drive specific speed for a bus
}
void ghostRide() {
//code to ghost ride the bus
}
}
Interface
• All variables in an interface are: final static
• Should be used with the syntax: Interface.variable
Interface
Implementing
2 interfaces for 1 class:
interface Inter
{
public int TEST = 3;
public void printTest();
}
interface Inter1
{
public int TEST = 5;
}
class Test implements Inter, Inter1
{
//wrong version:
public void printTest()
{
System.out.print(TEST);
//compiler error even if there was 1 interface
}
}
Interface
Implementing
2 interfaces for 1 class:
interface Inter
{
public int TEST = 3;
public void printTest();
}
interface Inter1
{
public int TEST = 5;
}
automatically: final static
class Test implements Inter, Inter1
{
//correct version:
public void printTest() {
System.out.print(Inter.TEST);
}
}
Interface
Implementing
2 interfaces for 1 class:
interface Inter
{
public int TEST = 3;
public void printTest();
}
interface Inter1
{
public int TEST = 5;
}
automatically: final static
class Test implements Inter, Inter1
{
//correct version:
public void printTest() {
System.out.print(Inter.TEST);
}
}
Class Main{
public static void main(String[] args) {
Inter t = new Test();
Test t2 = new Test();
int x = t.TEST; //wrong usage
int y = ((Inter1)t).TEST //wrong usage
}
Interface
Implementing
2 interfaces for 1 class:
interface Inter
{
public int TEST = 3;
public void printTest();
}
interface Inter1
{
public int TEST = 5;
}
automatically: final static
class Test implements Inter, Inter1
{
//correct version:
public void printTest() {
System.out.print(Inter.TEST);
}
}
Class Main{
public static void main(String[] args) {
Inter t = new Test();
Test t2 = new Test();
int x = Inter.TEST; //correct usage
int y = Inter1.TEST; //correct usage
}
Interface as a contract
public interface OrderedPair
{
//list of methods
public Object getFirst();
public Object getSecond();
public boolean equals(OrderedPair
another);
}
public class Pair implements OrderedPair
{
private Object first, second;
public Pair(Object x, Object y){
first = x;
second = y;
}
public Object getFirst(){
return first;
}
public Object getSecond() {
return second;
}
public boolean equals(OrderedPair another) {
return (first.equals(another.getFirst()) &
second.equals(another.getSecond()) );
}
}
… >,ממשק >,<2ממשק > implements <1שם מחלקה< • public class
• על המחלקה לממש את הפונקציות של כל הממשקים.
• אם מחלקה מיישמת שני ממשקים בעלי שיטה בעלת שם זהה foo
אז:
– אם לשתי ה fooיש חתימה שונה אז המחלקה מיישמת חייבת לממש את
שתיהן.
– אם לשתי ה fooיש אותה חתימה אך טיפוס מוחזר שונה -טעות קומפילציה.
(לא ניתן לממש את שני הממשקים יחד).
מחלקות אבסטרקטיות
• על מנת להבין את הצורך בשימוש במחלקות
אבסטקטיות נממש משחקים מתורת המשחקים
ע"י הורשה כפי שלמדנו בתרגול הקודם:
17
הגדרת המשחק
• משחק מוגדר על ידי מערכת של פעולות אפשריות
• במשחק משחקים שני שחקנים כאשר שני
השחקנים בוחרים פעולה בו-זמנית.
• בהינתן שתי הבחירות של שני השחקנים יקבלו
השחקנים ניקוד על פי הבחירה המשותפת.
18
דוגמא למשחק :אבן נייר ומספריים
•
•
•
•
19
שני השחקנים מגלים את בחירתם מבין שלוש
הפעולות האפשריות (אבן נייר או מספריים) .
אבן שוברת מספריים.
מספריים גוזרים נייר.
נייר עוטף אבן.
דוגמא נוספת למשחק:דילמת האסיר
•
•
•
•
•
•
20
דוגמא קלאסית מתורת המשחקים.
המשטרה עצרה שני עבריינים שביצעו פשע משותף ,ומפרידה
ביניהם לצורך חקירה.
למשטרה אין די ראיות להעמידם לדין ,ולכן היא מציעה לכל אחד
מהם להעיד נגד רעהו ,וכפרס מובטח לעד עונש מופחת.
אם שני האסירים יקבלו את הצעת המשטרה ,ייכנס כל אחד מהם
לכלא לחמש שנים.
אם רק אחד מהם יעיד ורעהו ישתוק ,העד יצא מיד לחופשי וחברו
ייכלא ל 15-שנה.
אם שני האסירים יישתקו,ייכנס כל אחד מהם לשנה בכלא.
המחלקות שעלינו לממש
• פעולה Action
– שם הפעולה ("אבן")
• שחקן Player
– שם השחקן (" )" Andrea Farina
– מספר נקודות
– בחירת פעולה(מהלך) מתוך קבוצת פעולות אפשריות.
21
המחלקות שעלינו לממש
• משחק Game
– קבוצת פעולות אפשריות("אבן,נייר,מספריים").
– 2שחקנים.
– שם המשחק.
22
מימוש המחלקה של פעולה
public class Action {
private String name;
public Action(String n) {
name = new String(n); // name = n; will work too
}
public String getName(){
return name;
}
}
23
מימוש המחלקה של שחקן כללי
public class Player {
private String m_name;
private int m_score;
public Player(String nm){
m_name=nm;
m_score =0;
}
public Action selectAction(Action[] actions){
return actions[0];
}
public boolean isWinner(Player p){
return (m_score > p.getScore());
}
public void updateScore(int score){
m_score = m_score + score;
}
public int getScore(){
return m_score;
}
public String toString(){
return m_name;
}
?מה נכתוב כאן
}
24
מימוש שחקן אקראי
public class RandomPlayer extends Player{
public RandomPlayer(String name)
{
super(name);
}
//The selection methods – different implementation
public Action selectAction(Action[] actions)
{
return actions[(int)(Math.random()*actions.length)];
}
}
25
מימוש שחקן עיקבי
public class ConsecutivePlayer extends Player{
private int m_lastSelection;
public ConsecutivePlayer (String name)
{
super(name);
m_lastSelection = 0;
}
//The selection methods – different implementation
public Action selectAction(Action[] actions)
{
m_lastSelection = (m_lastSelection + 1)% actions.length;
return actions[m_lastSelection];
}
}
26
מימוש משחק כללי
public class Game {
private Action[] actions; // the set of actions
private Player p1, p2;
private String name; //game name
public Game (int numActions, Player p1, Player p2, String name) {
actions = new Action[numActions];
this.p1 = p1;
this.p2 = p2;
this.name = name;
}
public void addAction(int index, Action a) {
actions[index] = a;
}
public void play(int turnCount) {
for (int i=0; i<turnCount; i=i+1)
playSingleTurn();
}
private void playSingleTurn() {
/*the selection order is not important as each player does not know the choice of the other player*/
Action a1 = p1.selectAction(actions);
Action a2 = p2.selectAction(actions);
rewardPlayers(a1, a2);
}
27
)מימוש משחק כללי(המשך
public void rewardPlayers(Action a1, Action a2) {
//this is not a specific game and therefore there is no real score//
p1.updateScore(0);
p2.updateScore(0);
}
public Player getWinner () {
if (p1.isWinner(p2))
return p1;
else return p2;
}
public Player getFirstPlayer() {
return p1;
}
public Player getSecondPlayer() {
return p2;
}
public String toString() { return name; }
}
28
מימוש המשחק אבן נייר ומספריים
public class RockPaperScissors extends Game{
public RockPaperScissors(Player p1, Player p2)
{
super(3,p1,p2, "Rock Paper Scissors");
addAction(0,new Action("rock"));
addAction(1,new Action("paper"));
addAction(2,new Action("scissors"));
}
29
public void rewardPlayers(Action a1, Action a2)
{
if (a1.getName().equals(a2.getName()))
{
getFirstPlayer().updateScore(0);
getSecondPlayer().updateScore(0);
}
if ((a1. getName().equals("rock")) & (a2.getName().equals("paper")))
{
getFirstPlayer().updateScore(-1);
getSecondPlayer().updateScore(1);
}
if ((a1. getName().equals("rock")) & (a2. getName().equals("scissors")))
{
getFirstPlayer().updateScore(1);
getSecondPlayer().updateScore(-1);
}
if ((a1. getName().equals("paper")) & (a2. getName().equals("scissors")))
{
getFirstPlayer().updateScore(-1);
getSecondPlayer().updateScore(1);
}
}
}
30
מימוש המשחק דילמת האסיר
public class PrisonerDilemmas extends Game{
public PrisonerDilemmas(Player p1, Player p2)
{
super(2,p1,p2, "Prisoner's dilemma");
addAction(0,new Action("silent"));
addAction(1,new Action("blame"));
}
31
public void rewardPlayers(Action a1, Action a2)
{
if ((a1. getName().equals("blame")) & (a2. getName().equals("blame")))
{
getFirstPlayer().updateScore(-5);
getSecondPlayer().updateScore(-5);
}
if ((a1. getName().equals("silent")) & (a2. getName().equals("blame")))
{
getFirstPlayer().updateScore(-15);
getSecondPlayer().updateScore(0);
}
if ((a1. getName().equals("blame")) & (a2. getName().equals("silent")))
{
getFirstPlayer().updateScore(0);
getSecondPlayer().updateScore(-15);
}
if ((a1. getName().equals("silent")) & (a2. getName().equals("silent")))
{
getFirstPlayer().updateScore(-1);
getSecondPlayer().updateScore(-1);
}
}
}
32
הצורך במחלקות אבסטקטיות
היינו רוצים ליצור מחלקה:
– שתהיה מחלקת האב של כל המשחקים שתדע לעשות
את כל הדברים המשותפים.
– שתכיל הגדרה של כל השיטות המשותפות ,כדי
שאפשר יהיה לקרוא ,לדוגמא ,באופן כללי
rewardPlayersבלי לדעת מהו המשחק.
– שתשאיר מקום לכל משחק לממש את השיטות
האופייניות שלו.
– שתחייב כל משחק לממש את השיטות האופייניות שלו.
33
משחק כמחלקה אבסטרקטית
public abstract class Game {
protected Action[] actions;
protected Player p1, p2;
protected String name;
public Game (int numActions, Player p1, Player p2, String name) {
actions = new Action[numActions];
this.p1 = p1;
this.p2 = p2;
this.name = name;
}
public abstract void rewardPlayers(Action a1, Action a2);
34
public void addAction(int index, Action a) {
actions[index] = a;
}
public void play(int turnCount) {
for (int i=0; i<turnCount; i=i+1)
playSingleTurn();
}
private void playSingleTurn() {
Action a1 = p1.selectAction(actions);
Action a2 = p2.selectAction(actions);
rewardPlayers(a1, a2);
}
public Player getWinner () {
if (p1.isWinner(p2))
return p1;
else return p2;
}
public Player getFirstPlayer() {
return p1;
}
public Player getSecondPlayer() {
return p2;
}
public String toString() { return name; }
}
35
מחלקות אבסטרקטיות
{>public abstract class <name
;) public abstract void <method name> ( ...
…
}
• במחלקה אבסטרקטית יכולות להיות פונקציות
רגילות ,כמו בכל מחלקה.
• בנוסף יכולות להיות לה פונקציות אבסטרקטיות:
פונקציות שההגדרה שלהן קיימת אבל אין להן
מימוש.
• אנו מכריזים על מחלקה או על שיטה
כאבסטרקטית בעזרת המילה השמורה .abstract
36
מחלקות אבסטקטיות(המשך)
• בגלל שמחלקה אבסטרקטית מכילה שיטות שאינן
מוגדרות (שיטות אבסטרקטיות) לא ניתן ליצור
ממנה מופעים.
– ;)(Game g = new Game
שגיאת קומפילציה
• מחלקה שמרחיבה מחלקה אבסטרקטית ולא
מממשת את כל השיטות האבסטרקטיות ,חייבת
להיות אבסטרקטית בעצמה.
37
מחלקות אבסטקטיות(המשך)
• מחלקה יכולה להיות אבסטרקטית ,גם אם אין לה
פונקציות אבסטרקטיות .בצורה זו אנו מונעים
מהמשתמש ליצור ממנה מופע.
38
מימוש המשחק דילמת האסיר
אבסטקטית ועל כן אנו חייביםGame • המחלקה
.rewardPlayers לממש את השיטה
.• זהה לחלוטין למימוש שהצגנו קודם
public class PrisonerDilemmas extends Game{
public PrisonerDilemmas(Player p1, Player p2)
{
super(2,p1,p2, "Prisoner's dilemma");
addAction(0,new Action("silent"));
addAction(1,new Action("blame"));
}
39
public void rewardPlayers(Action a1, Action a2)
{
if ((a1. getName().equals("blame")) & (a2. getName().equals("blame")))
{
getFirstPlayer().updateScore(-5);
getSecondPlayer().updateScore(-5);
}
if ((a1. getName().equals("silent")) & (a2. getName().equals("blame")))
{
getFirstPlayer().updateScore(-15);
getSecondPlayer().updateScore(0);
}
if ((a1. getName().equals("blame")) & (a2. getName().equals("silent")))
{
getFirstPlayer().updateScore(0);
getSecondPlayer().updateScore(-15);
}
if ((a1. getName().equals("silent")) & (a2. getName().equals("silent")))
{
getFirstPlayer().updateScore(-1);
getSecondPlayer().updateScore(-1);
}
}
}
40
שחקן כמחלקה אבסטרקטית
public abstract class Player {
private String m_name;
private int m_score;
public Player(String nm)
{
m_name=nm;
m_score =0;
}
public abstract Action selectAction(Action[] actions);
41
מחלקות אבסטרקטיות
ממשקים
לא ניתן ליצור מופעים
לא ניתן ליצור מופעים
שימוש במחלקה אבסטרקטית ע"י ירושה
extends
שימוש בממשק מתבצע ע"י מימושו
implements
מחלקה אבסטרקטית יכולה להכיל קוד של
חלק מהשיטות
הממשק הינו רשימה של שיטות ללא כל
מימוש
יורשי מחלקה זו יהיו בעלי יישומים דומים
(הקוד המשותף) וכן בעלי יישומים שונים
(השיטות האבסטרקטיות)
ממשק הוא רעיון מופשט אשר ליורשיו אין אף
יישום משותף.
מחלקה יכולה לרשת מחלקה אבסטרקטית
אחת בלבד
מחלקה יכולה לממש מספר ממשקים
אין הגבלה על המשתנים
כל משתנה חייב להיות
static final
42
© Copyright 2026 Paperzz