Nathan Sprague
We are developing a super-fun text-based video game:
public class Creature
{
private int xPos;
private int yPos;
private int health;
public Creature(int xPos, int yPos, int health)
{
this.xPos = xPos;
this.yPos = yPos;
this.health = health;
}
public String makeFace()
{
return "OvO";
}
public int getXPos()
{
return xPos;
}
public int getYPos()
{
return yPos;
}
public void setXPos(int xPos)
{
this.xPos = xPos;
}
public void setYPos(int yPos)
{
this.yPos = yPos;
}
public int getHealth()
{
return health;
}
public void setHealth(int health)
{
this.health = health;
}
}Of course... the game will need several different creature types. Let's add a monster class with a different appearance:
public class Monster
{
private int xPos;
private int yPos;
private int health;
private boolean angry;
public Monster(int xPos, int yPos, int health)
{
this.xPos = xPos;
this.yPos = yPos;
this.health = health;
this.angry = false;
}
public String makeFace()
{
if (angry)
{
return ":(>)";
}
else {
return ":)";
}
}
public int getXPos()
{
return xPos;
}
public int getYPos()
{
return yPos;
}
public void setXPos(int xPos)
{
this.xPos = xPos;
}
public void setYPos(int yPos)
{
this.yPos = yPos;
}
public int getHealth()
{
return health;
}
public void setHealth(int health)
{
angry = health < 3;
this.health = health;
}
}What's wrong with this class?
What is the solution?
Monster "is-a" Creature.
Monster inherits all Creature attributes.Monster can have additional methods and variables.Monster can override existing methods.public class Monster extends Creature
{
private int xPos;
private int yPos;
private int health;
private boolean angry;
public Monster(int xPos, int yPos, int health)
{
super(xPos, yPos, health);
this.xPos = xPos;
this.yPos = yPos;
this.health = health;
this.angry = false;
}
public String makeFace()
{
if (angry)
{
return ":(>)" + " " + health;
}
else {
return ":)" + " " + health;
}
}
public void setHealth(int health)
{
angry = health < 3;
this.health = health;
}
}What will be printed by this code snippet:
Monster monster = new Monster(50, 50, 10);
System.out.println(monster.getHealth());
System.out.println(monster.makeFace());
monster.setHealth(1);
System.out.println(monster.getHealth());
System.out.println(monster.makeFace())10
:) 10
10
:(>) 110
:) 10
10
:) 1010
:) 10
1
:(>) 110
:) 10
1
:) 10public class Monster extends Creature
{
private boolean angry;
public Monster(int xPos, int yPos, int health)
{
super(xPos, yPos, health);
this.angry = false;
}
public String makeFace()
{
if (angry)
{
return ":(>)";
}
else {
return ":)";
}
}
public void setHealth(int health)
{
//...
}setHealth MethodWe want the Monster to become angry when its health falls below 3.
Which implementation works?
public void setHealth(int health)
{
angry = health < 3;
this.health = health;
}public void setHealth(int health)
angry = health < 3;
setHealth(health);
}public void setHealth(int health)
angry = health < 3;
super.setHealth(health);
}public void setHealth(int health)
angry = health < 3;
super.health = health;
}public class Monster extends Creature
{
private boolean angry;
public Monster(int xPos, int yPos, int health)
{
super(xPos, yPos, health);
this.angry = false;
}
public String makeFace()
{
if (angry)
{
return ":(>)";
}
else {
return ":)";
}
}
public void setHealth(int health)
{
angry = health < 3;
super.setHealth(health);
}public class Monster extends Creature
{
private boolean angry;
public Monster(int xPos, int yPos, int health)
{
super(xPos, yPos, health);
this.angry = false;
}
public String makeFace()
{
if (angry)
{
return ":(>)";
}
else {
return ":)";
}
}
public void setHealth(String health)
{
super.setHealth(Integer.parseInt(health));
angry = getHealth() < 3;
}What will be printed by the following code snippet?
Monster monster = new Monster(50, 50, 10);
monster.setHealth(1);
System.out.println(monster.getHealth());
System.out.println(monster.makeFace());
monster.setHealth("2");
System.out.println(monster.getHealth());
System.out.println(monster.makeFace())1
:(>)
2
:(>)10
:)
2
:(>)1
:)
1
:)1
:)
2
:(>)@OverrideThe problem here is that the author intended to override the setHealth method of the superclass, but overloaded it instead.
This type of error can be avoided by using the @Override annotation. It informs the compiler that you intend a method to override a method defined in the superclass.
This wouldn't compile, because Creature has no method with this signature.
@Override
public void setHealth(String health)
{
super.setHealth(Integer.parseInt(health));
angry = getHealth() < 3;
}Let's add a toString method to Creature:
public class Creature
{
// Other code not shown.
public String toString()
{
return makeFace() + " " + xPos + " " + yPos;
}
}What will be printed when this code snippet executes?
Creature c1 = new Creature(20, 30, 10);
Monster m1 = new Monster(15, 17, 8);
System.out.println(c1);
System.out.println(m1);OvO 20 30
OvO 15 17OvO 20 30
:) 15 17B. Calling makeFace on an object of type Monster will always execute the Monster version of the method.