Reputation: 145
I'm new to Java and I am currently learning about Abstract classes. Currently I am creating a simple RPG. Suppose I have an abstract class called Person
, which extends to two other classes, Warrior
and Wizard
.
Now suppose that I have another abstract class called Weapon
where from there we can create different types of weapons(swords, axes, bows etc..) which share some basic methods, that can be overwritten by other inherited classes, such as attack()
or maintenance()
.
When a Person
(Wizard
or Warrior
) will call the attack()
method at some point in the game, I need to know who will be the attacker and who the defender (show I can modify their life bar status, durability of their weapons , etc) .
(Which essentially means, receiving two objects in the attack()
method as parameters).
So here is where I am stuck. The combination of attacker-defender could be Wizard-Warrior
, Wizard-Wizard, Warrior-Wizard or Warrior-Warrior
.
How should I implement the attack()
method in the Weapon
class so it can permit me to receive an object as a parameter, without caring if the object is going to be wizard or warrior ? Could this be possible?
doing something like this for example?
void attack(Person attacker, Person defender)
{
// add method logic here
}
Thanks in advance.
Upvotes: 1
Views: 170
Reputation: 11072
I'd like to propose a different alternative:
You have stated the attack
method is on the Weapon
class, however it seems the more logical place for this method would be in the Person
class. If we think about it in concrete terms, it is not the weapon that is attacking the opponent, it is the Person
, who is using the weapon, that is attacking.
It is difficult to give a concrete answer without seeing design of the game, however I will assume that your Person
maintains a target
field, pointing to whomever is being targeted by this Person
object.
Additionally, when a player is attacked, they will no doubt "defend" themselves in some fashion (this could be simply in the form of mitigated damage due to armour, or some active ability or action, for example).
So your class will look something like this:
public abstract class Person {
private Person target;
private Weapon weapon;
public void attack(){
target.defend(calculateRawDamage());
}
private int calculateRawDamage(){
// calculate weapon damage plus any modifiers, etc.
}
public void defend(int rawDamage){
// calculate actual damage based on damage-mitigation modifiers
}
}
This example makes a number of assumptions about how your game works, however as I said, it is simply an example, and hopefully illustrates a better way to implement game logic that does not reply on knowing the concrete Person
or Weapon
types, as each object will behave in their own specialized fashion according to their concrete type due to polymorphism.
Upvotes: 0
Reputation:
First step, derive Wizard
and Warrior
from Person
(you may consider making Person an interface).
Second step, implement attack(Person attacker, Person defender)
in terms of Person, not in terms of Warior or Wizard. All methohds common to Warrior and Wizard should be available to person. Any method not common should be made irrelevant to attack()
.
For example, if Wizard has castBestSpell(Person target)
method, while Warrior has hitWithWeapon(Person target)
, you need to reduce both methods to Person.attack(Person target)
. Wizard and warrior will implement attack(Person target)
differently: one by calling castBestSpell
, one by calling hitWithWeapon
.
Upvotes: 0
Reputation: 646
Not really answering the question, but why not move attack
to the Person
class, then you could write it out like
class Person
public void attack(Person target, int damage) {
target.setLife(life - damage);
// or target.damage(damage), or however else you want to implement that
...
}
then
myWarrior.attack(evilWizard, myWeapon.getDamage);
That just seems to make more sense to me, since the Person
will be doing the attacking.
Upvotes: 2
Reputation: 94
it's easy, Wizard and Warrior need to extend Person
public class Warrior extends Person { }
It's easy.
Then you can check what it is...
if (attacker instanceof Warrior) for example.
Upvotes: 0