Episode 3: Abstraction – Making Hero an Abstract Class
Goal: Learn how to use abstract classes to enforce that all heroes implement key behaviors while allowing flexibility in implementation.
Episode 3: Abstraction – Making Hero an Abstract Class
1. Project Structure
Create the following folder layout:
1
2
3
4
5
6
src/
└── model/
├── Hero.java (now abstract)
├── Warrior.java
└── Mage.java
2. Update Hero.java to be abstract
Create the file: src/main/Main.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package model;
public abstract class Hero {
protected String name;
protected int hp;
protected int attack;
public Hero(String name, int hp, int attack) {
this.name = name;
this.hp = hp;
this.attack = attack;
}
public void takeDamage(int damage) {
this.hp -= damage;
if (this.hp < 0) this.hp = 0;
System.out.println(name + " now has " + hp + " HP.");
}
public String getName() {
return name;
}
public int getHp() {
return hp;
}
// Abstract method: subclasses must implement this
public abstract void attack(Hero target);
}
3. Override attack() in subclasses
Warrior.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package model;
public class Warrior extends Hero {
public Warrior(String name) {
super(name, 150, 20);
}
@Override
public void attack(Hero target) {
System.out.println(this.name + " attacks " + target.getName() + " with a sword for " + this.attack + " damage.");
target.takeDamage(this.attack);
}
public void heavyStrike(Hero target) {
int damage = this.attack + 10;
System.out.println(this.name + " uses Heavy Strike on " + target.getName() + " for " + damage + " damage!");
target.takeDamage(damage);
}
}
Mage.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package model;
public class Mage extends Hero {
public Mage(String name) {
super(name, 100, 25);
}
@Override
public void attack(Hero target) {
System.out.println(this.name + " casts a magic missile at " + target.getName() + " for " + this.attack + " magic damage.");
target.takeDamage(this.attack);
}
public void fireball(Hero target) {
int damage = this.attack + 5;
System.out.println(this.name + " casts Fireball on " + target.getName() + " for " + damage + " magic damage!");
target.takeDamage(damage);
}
}
4. Test in Main.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import model.*;
public class Main {
public static void main(String[] args) {
Hero garen = new Warrior("Garen");
Hero ahri = new Mage("Ahri");
garen.attack(ahri);
ahri.attack(garen);
((Mage) ahri).fireball(garen);
((Warrior) garen).heavyStrike(ahri);
}
}
This post is licensed under CC BY 4.0 by the author.