I'm trying to understand the basics of Java OOP concepts so I've a question about the interfaces as it confuses me a little. Below I was playing around with two classes. One which implements the SizeComparable interface and the other which doesn't but works too.
public interface SizeComparable {
int isHigher(SizeComparable obj);
}
public class Interesting implements SizeComparable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(SizeComparable obj) {
Interesting otherInteresting = (Interesting)obj;
if(this.getHeight() > otherInteresting.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
How is the code above better than the code bellow? Personally I don't understand because the code bellow those it's job great too. Am I missing some concepts behind the interface idea?
public class Interesting {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(Interesting obj) {
if(this.getHeight() > obj.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
I was trying to understand it (here), but I'm still unsure about this. Sorry if the question is a little silly, i just want to understand it completely.
If you have Interesting, Boring, Indifferent and Crazy classes which all represent some objects comparable by height, then all of them can implement the SizeComparable interface and thus be comparable to each other.
Without the interface you would need n methods in each class to compare it with itself and all the others.
At the beginning it probably won't make much sense, however when you will start injecting dependencies, start testing or will write more than one implementation of interface, than it will really give you boost.
Also it allows for multiple inheritance. Sometimes you want thing like comparable - very generic interface that may be used by a lot of classes in your system. That will come with bigger systems and larger class hierarchies.
Right now just trust rest of java world, and use them interfaces :)
and good luck
An interface is a contract that any class wishing to implement the interface agrees to follow. The reason for using an interface is to allow some other class or method to access the interface functions without requiring that the your class inherit from a common class... I'll modify your example to make it clearer:
public interface HeightCapable {
int getHeight();
}
public class Interesting implements HeightCapable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
}
public class SomeOtherClass {
public boolean isHigher(HeightCapable obj1, HeightCapable obj2) {
// ... do something interesting
if (obj1.getHeight() > obj2.getHeight()) {
return true;
}
}
In the example above, any class implementing the HeightCapable interface can call SomeOtherClass.isHigher(). Without the interface, any class wishing to call SomeOtherClass.isHigher() would need to inherit from a common class. Java lacks multiple inheritance.
If you want to have your SizeComparable objects comparable not to all other SizeComparable objects, but only to those of some type, you could use generic types.
interface SizeComparable<X> {
/**
* returns true if this object is higher than that object.
*/
boolean isHigher(X that);
}
Then you could create your implementations like this:
public class Interesting implements SizeComparable<Interesting> {
...
public boolean isHigher(Interesting obj) {
return this.getHeight() > obj.getHeight();
}
}
Or, you could even have another interface
public interface HeigthHaving extends SizeComparable<HeightHaving> {
/**
* returns the height of this object.
*/
public int getHeigth();
/**
* compares this object's height with another objects height.
* #return true if this.getHeight() > that.getHeight, else false.
*/
public boolean isHigher(HeightHaving that);
}
Now every implementation of HeightHaving must implement the isHigher(HeightHaving) method (this would be the case even if we did not repeat it here), and should do that according to the specification here. Other SizeComparable implementations are not affected of this, though.
The good thing here is that now for example sort algorithms can sort lists/arrays of any type X implementing SizeComparable, so you don't have to write it again for every new type of object you may want to sort by height.
(In fact, there is already a similar interface Comparable<X> in the standard API. Maybe you want to use this instead of your SizeComparable.)
By the way, for a isXXX method usually a boolean return type is quite more sensible than an integer.
Related
I have something like this:
Figures fig = new Line();
on which Line extends Figure. Figure is an abstract class that only has a method getType() that tells me which figure it is by returning a String;
I have 3 types, Rectangle, Circle and Figure. All of them extend Figures.
Now the real question. I store every single one inside of a List<Figures> and I want to get access to some methods on each object like getStartX(); and getStartY(); and I can't, I only can access the methods that are on Figures also.
Your abstract class should define the getStartX and getStartY method. Either abstract if you want Rectangle, Circle and Figure to have a different behaviour and force them to Override those methods. Else just put the method in Figures it'll be available for use (with the appropriate keyword : public/protected depending your needs).
If you want to use methods that are specific to a class you'll need to check of which instance it is. Something like
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof Circle) {
System.out.println("Oh no a Circle!");
int radius = ((Circle)figure).getRadius();
...
}
}
For your Rectangle/Line you can define an interface with your 2 methods:
public interface HasEndpoints {
int getEndX();
int getEndY();
}
public class Rectangle implements HasEndpoints {
...
public int getEndX() {return endx;}
...
}
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof HasEndpoints) { // Rectangle and Line will go there
System.out.println("HasEndpoints implementor");
int endX = ((HasEndpoints)figure).getEndX();
...
}
}
You can use instanceof with if...else and cast dynamically your object
Figure fig = new //Circle()/Triangle()/Rectangle();
if( fig instanceof Circle) {
((Circle) fig).getRadius(); //This method is only available in Circle class
}
You can always cast the Figure to Line, but not the best choice. Depending on the problem, you can apply Visitor Pattern or add those methods to Figure, even when the Circle doesn't have a starting and ending point.
For example
public abstract class Figure{
public abstract void visit(FigureVisitor visitor);
}
public class Line extends Figure{
public void visit(FigureVisitor visitor){
visitor.visitLine(this);
}
}
public interface FigureVisitor{
public void visitLine(Line figure);
public void visitCircle(Circle figure);
}
public class StartingPointsVisitor implements FigureVisitor{
private Double startX;
private Double startY;
private Double endX;
private Double endY;
public void visitLine(Line figure){
this.startX = figure.getStartX(); //No cast needed
...
}
public void visitCircle(Circle figure){
//Stub-method
}
//Getters to read the results
}
Is a more complex solution, but as i said, it depends on the problem, and most of the complex remains in the Visitor
Either getStartX() and getStartY() should be declared in Figure class or you need to cast the object to Line class:
Figure figure = figures.get(0);
if ("line".equals(figure.getType())) {
Line line = (Line)figure;
}
Another option is to use reflection. But you still need to be sure, that the requested method can be called.
I am using the Vector2 class of the libGDX API, and if I want to check the equality of two vectors I have to do the following:
Vector2 vectA = new Vector2(0, 1);
Vector2 vectB = new Vector2(1, 1);
if (vectA.x == vectB.x && vectA.y == vectB.y) {
return true;
}
This is very uncomfortable and I am thinking about creating an equals() method for this scenario. Which should be the better to do:
Creating a wrapper for the Vector2 class with an equals(Vector2) method
Creating an EqualUtil class with an equals(Vector2, Vector2) method
The first would look better (in my opinion), but it may not be a 'nice' solution while the other is much cleaner but also a bit simplistic. Different ideas also welcome.
Yes you should.
In my opinion, it is better to create a Wrapper (and you should also override hashCode() to match the new behavior).
Not only doing so will result in more readable code, it will also allow you to use collections such as a HashSet or other methods that rely on the equals() behavior.
It also makes sense logically, because you are trying to create a method that gives data on the specific object - what better way to show it then to do it as an instance method?
I'll go with, overriding both equals() as well as hashCode() method inside a Vector2 class.
From Joshua Bloch Item -9
Always override hashCode when you override equals
Edited:
Scroll down to page 45
Page 45: Item-9
public interface CheckObject(){
public abstract boolean and(CheckObject checkobject);
}
public abstract class AbstractObject()
implements CheckObject
{
public AbstractObject()
{
}
public abstract boolean and(CheckObject checkobject);
protected void beforeObjectChecked(Object obj)
throws IllegalArgumentException
{
}
public class EqualUtil extends AbstractObject {
private int point1;
private int point2;
}
protected EqualUtil(int point1,int point2){
this.point1=point1;
this.point1=point2;
}
public boolean and(CheckObject checkobject){
beforeObjectChecked(checkobject);
return(this.getPoint1()==checkobject.getpoint1() && this.getPoint2()==checkobject.getpoint2()));
}
public int getPoint1() {
return point1;
}
public void setPoint1(int point1) {
this.point1 = point1;
}
public int getPoint2() {
return point2;
}
public void setPoint2(int point2) {
this.point2 = point2;
}
Now you can use it from Main Class
Wrapper's are a good and understandable way to add in new behaviour when the original designers did not include it for some reason. Given that the original API class just uses the java.lang.object equals method, creating a wrapper seems a sensible option to me.
I'm writing a game engine in Java for Android games and my engine handles collision detection for different shapes. Each shape is its own class (Square, Circle, etc.), and derives from a common abstract parent Collidable. I have a physics manager class which basically checks if any of the existing objects in the game are colliding with another, and then does the appropriate action when collision is detected. The check for collision is implemented inside each physics shape child class as in the code below.
public abstract class Collidable
{
}
public class Square extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class Circle extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class Triangle extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class PhysicsMgr
{
public boolean Collides(Collidable p1, Collidable p2)
{
return p1.Collides(p2);
// This obviously won't work because there is no Collides
// method in Collidable. I want it to somehow call the child's
// method and pass in p2 as its child type rather than as
// a parent. Or somehow do this:
return (p1.child()).Collides(p2.child());
// I know that obviously nothing like this exists.
}
}
I am aware of "instanceof" and really don't want to check the child type of p1 and p2 versus every single collision shape I have. There must be a better way. I'm looking for either a workaround for my current problem, or preferably a redesign of my current collision detection system to avoid this problem altogether.
Thanks!
you should read about the visitor pattern
For starters, I wouldn't make Collidable an abstract class. Even though there are probably good arguments for it; it just seems to me like this is an "is a" situation where a lot of objects could be collidable.
So, that being said, here is what I would recommend:
// Assuming you're working in 2 dimensions
public class Coordinates {
public Coordinates(float x, float y) {
// etc etc etc
}
}
public interface ICollidable {
// Using unusually long name to illustrate point,
// but feel free to rename.
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector);
public Coordinates getCenterOfMass();
}
And then, for Square, Triangle, and Circle, I would implement the interface.
public class Square implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.lengthOfSide;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
public class Circle implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.radius;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
public class Triangle implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.lengthOfSide;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
Then, in your PhysicsMgr...
public class PhysicsMgr {
public boolean Collides(ICollidable p1, ICollidable p2) {
Coordinates cm1 = p1.getCenterOfMass();
Coordinates cm2 = p2.getCenterOfMass();
int length = Math.sqrt(Math.pow(cm1.x - cm2.x, 2) + Math.pow(cm1.y - cm2.y, 2))
// It is a misnomer to use coordinates as a unit vector, but if I defined a
// UnitVector class, it would be exactly the same with the exception of
// the class name for this situation.
Coordinates unitVector = new Coordinates((cm1.x - cm2.x)/length, (cm1.y - cm2.y)/length);
int collisionDistance1 = p1.getMaxDistanceFromCenterOfMass(unitVector);
int collisionDistance2 = p2.getMaxDistanceFromCenterOfMass(unitVector);
return (length - collisionDistance1 - collisionDistance2) <= 0;
}
}
The one major caveat here is that using the maxDistance from center of mass literally will only give you an approximation for the Square and Triangle. To be exact, you will have to declare some orientation, theta, and calculate the distance from the center of mass of the object to the edge along the unit vector (which will be tricky, but exact).
Another thing that is nice about this is that it allows you to easily add other collidable objects as your engine becomes more sophisticated. This also makes it so that none of the objects have to know about each other.
I was a physics TA for 3 years and it was actually how I got my first exposure to programming. If you're interested in the extra work, here is a reference to the book we used: http://matterandinteractions.org/ It is great for programmers because it teaches physics by using coding examples in python (specifically, vpython http://vpython.org/ ). So this would be a very good reference to have for physics programming.
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
You are going to need separate implementations for the various combinations of shapes (because there is no common algorithm, I think). So at one point, there will be the need to call instanceof. I am afraid having an abstract method or interface method public boolean Collides(Collidable) is not going to help here, and what you have now cannot be significantly improved upon. This is a textbook case of the limitations of OOP, because these collision detection methods cannot be neatly attached to any of the shape classes, they live somewhere in between, in something like your physics manager.
I'd like to extend ArrayList to add a few methods for a specific class whose instances would be held by the extended ArrayList. A simplified illustrative code sample is below.
This seems sensible to me, but I'm very new to Java and I see other questions which discourage extending ArrayList, for example Extending ArrayList and Creating new methods. I don't know enough Java to understand the objections.
In my prior attempt, I ending up creating a number of methods in ThingContainer that were essentially pass-throughs to ArrayList, so extending seemed easier.
Is there a better way to do what I'm trying to do? If so, how should it be implemented?
import java.util.*;
class Thing {
public String name;
public int amt;
public Thing(String name, int amt) {
this.name = name;
this.amt = amt;
}
public String toString() {
return String.format("%s: %d", name, amt);
}
public int getAmt() {
return amt;
}
}
class ThingContainer extends ArrayList<Thing> {
public void report() {
for(int i=0; i < size(); i++) {
System.out.println(get(i));
}
}
public int total() {
int tot = 0;
for(int i=0; i < size(); i++) {
tot += ((Thing)get(i)).getAmt();
}
return tot;
}
}
public class Tester {
public static void main(String[] args) {
ThingContainer blue = new ThingContainer();
Thing a = new Thing("A", 2);
Thing b = new Thing("B", 4);
blue.add(a);
blue.add(b);
blue.report();
System.out.println(blue.total());
for (Thing tc: blue) {
System.out.println(tc);
}
}
}
Nothing in that answer discourages extending ArrayList; there was a syntax issue. Class extension exists so we may re-use code.
The normal objections to extending a class is the "favor composition over inheritance" discussion. Extension isn't always the preferred mechanism, but it depends on what you're actually doing.
Edit for composition example as requested.
public class ThingContainer implements List<Thing> { // Or Collection based on your needs.
List<Thing> things;
public boolean add(Thing thing) { things.add(thing); }
public void clear() { things.clear(); }
public Iterator<Thing> iterator() { things.iterator(); }
// Etc., and create the list in the constructor
}
You wouldn't necessarily need to expose a full list interface, just collection, or none at all. Exposing none of the functionality greatly reduces the general usefulness, though.
In Groovy you can just use the #Delegate annotation to build the methods automagically. Java can use Project Lombok's #Delegate annotation to do the same thing. I'm not sure how Lombok would expose the interface, or if it does.
I'm with glowcoder, I don't see anything fundamentally wrong with extension in this case--it's really a matter of which solution fits the problem better.
Edit for details regarding how inheritance can violate encapsulation
See Bloch's Effective Java, Item 16 for more details.
If a subclass relies on superclass behavior, and the superclass's behavior changes, the subclass may break. If we don't control the superclass, this can be bad.
Here's a concrete example, lifted from the book (sorry Josh!), in pseudo-code, and heavily paraphrased (all errors are mine).
class CountingHashSet extends HashSet {
private int count = 0;
boolean add(Object o) {
count++;
return super.add(o);
}
boolean addAll(Collection c) {
count += c.size();
return super.addAll(c);
}
int getCount() { return count; }
}
Then we use it:
s = new CountingHashSet();
s.addAll(Arrays.asList("bar", "baz", "plugh");
And it returns... three? Nope. Six. Why?
HashSet.addAll() is implemented on HashSet.add(), but that's an internal implementation detail. Our subclass addAll() adds three, calls super.addAll(), which invokes add(), which also increments count.
We could remove the subclass's addAll(), but now we're relying on superclass implementation details, which could change. We could modify our addAll() to iterate and call add() on each element, but now we're reimplementing superclass behavior, which defeats the purpose, and might not always be possible, if superclass behavior depends on access to private members.
Or a superclass might implement a new method that our subclass doesn't, meaning a user of our class could unintentionally bypass intended behavior by directly calling the superclass method, so we have to track the superclass API to determine when, and if, the subclass should change.
I don't think extending arrayList is necessary.
public class ThingContainer {
private ArrayList<Thing> myThings;
public ThingContainer(){
myThings = new ArrayList<Thing>();
}
public void doSomething(){
//code
}
public Iterator<Thing> getIter(){
return myThings.iterator();
}
}
You should just wrap ArrayList in your ThingContainer class. ThingContainer can then have any processing methods you need. No need to extend ArrayList; just keep a private member.
Hope this helps.
You may also want to consider creating an interface that represents your Thing Class. This gives you more flexibility for extensibility.
public Interface ThingInterface {
public void doThing();
}
...
public OneThing implements ThingInterface {
public void doThing(){
//code
}
}
public TwoThing implements ThingInterface {
private String name;
public void doThing(){
//code
}
}
Here is my suggestion:
interface ThingStorage extends List<Thing> {
public int total();
}
class ThingContainer implements ThingStorage {
private List<Thing> things = new ArrayList<Thing>();
public boolean add(Thing e) {
return things.add(e);
}
... remove/size/... etc
public int total() {
int tot = 0;
for(int i=0; i < size(); i++) {
tot += ((Thing)get(i)).getAmt();
}
return tot;
}
}
And report() is not needed actually. toString() can do the rest.
I am a first year programming student. I have coved the basics of precedual programming in c++. I am now fairly new to Java.
Recently i have taken a keen interest into game programming.
my situation:
my situation:
I have a hero class and a rival class. each with thier own members and methods.
how can i make it possible for the hero to interact with the rival, do i do this through the use of interfaces? for example an interface with an undefined attack method
and have both the class implement that interface?
if so
what should the code look like in the attack method of both classes
something likes this
example:
// heros version of implemented method
public int attack()
{
// idealy when hero attacks, the health value will be reduced by 15 of what it is.
rival1.getHealth(- 15)
}
// rival version of implemented method
public int attack()
{
// idealy when rival attacks, the health value will be reduced by 15 of what it is.
hero1.getHealth(- 15)
}
Please help me understanding why we use interefaces and , the anwser to my question
any help or suggestions will be greatly appreciated :) .
I would say you should not use an interface. A better approach would be to use a superclass. With a superclass you can avoid redefining many of the methods that will, presumably, be shared by both the rival and the hero. Here is an example implementation:
Superclass:
public abstract class ExampleFighter {
private String name;
private int health;
private boolean isDead = false;
public ExampleFighter(String name, int health) {
this.name = name;
this.health = health;
}
public void attack(ExampleFighter ef) {
int damage = 0;
//calculate damage dealt
damage = 10;
ef.takeDamage(damage);
}
public void takeDamage(int damage) {
//manipulate the amount of damage taken
if(health - damage <= 0) {
health = 0;
isDead = true;
} else {
health -= damage;
}
}
public boolean isDead() {
return isDead;
}
}
Subclasses:
public class ExampleHero extends ExampleFighter {
int reputation; //the general opinion of the hero
public ExampleHero() {
super("Hero Oreh of Herosville", 100);
reputation = 0;
}
public void improveReputation() {
reputation++;
}
}
public class ExampleRival extends ExampleFighter {
public ExampleRival() {
super("Your greatest rival", 101);
}
}
The side effect of this system is that it requires a fourth class to actually play the game:
public class ExampleGame {
private ExampleHero hero;
private ExampleRival rival;
public static void main(String... args) {
ExampleGame game = new ExampleGame();
game.start();
}
public ExampleGame() {
hero = new ExampleHero();
rival = new ExampleRival();
//what ever other game setup you need to do.
//alternately you could have a load() method
//that takes care of most of this.
}
private void start() {
//make your run loop or query the user for input
//or whatever you need to do. I will create an
//example run loop
boolean running = true;
while(running) {
//this whole block should be moved
//to another method called gameUpdate()
//or something similar but since this
//is a quick example I'll just leave it
//here
hero.attack(rival);
rival.attack(hero);
if(rival.isDead()) {
hero.improveReputation();
System.out.println(“Your rival is dead!");
running = false;
} else if(hero.isDead()) {
System.out.println("you died :(");
running = false;
}
}
}
}
Now this might seem a bit complicated but it illustrates a very important concept: separation of concerns. Separation of concerns involves putting code and making classes that make sense. A player should not know who it’s rival is, player might not even know that enemies exist or what sort of terrain it’s standing on. But a player should know how to manage it's health, it's name, how to take damage, etc. In contrast a Game object would need to know about all the players and enemies so it can tell them to fight and move around on the screen. This is an informal definition of seperation of concerns, for more accurate information read the wikipedia page. In this example I separated the hero and the rival so that, later, you can add more enemies without having to modify your hero code every time. This system also allows you to expand on the game's UI without affecting the player or rival. If you wanted to add a GUI to your game you could add an initialize() method in ExampleGame that setup the GUI. Then in the game loop you could call methods to draw images and graphics onto the GUI. With seperation of concerns you can make the system far more modular and easy to use.
Your second question is: why do we use interfaces? Interfaces are a way of making sure that other classes have a behavior you need them to have, without specifying exactly how they should do it. A classic example of the use of interfaces is the Comparable interface. The Comparable interface has one method that it’s must be implemented: compareTo(). The purpose of this method is to allow a ranking of value objects (think String or File) that cannot use the standard boolean mathematical operations (<, >, ==, etc.) You can think of it as like signing a contract. You (the class implementing the interface) agree to have a certain set of functionality however you make that functionality is up to you. For more information read the java tutorial
I should add a caveat to this answer: Inheritance is not the best option. If you want to know how to do it right you should look up MVC (Model View Controller) and Component Based Design. Even these may not the best choice for what you're doing but they're good starting points.
I think you're going to want to break it up into a Fighter class and a FightController class. Then the Fighter would be assigned to either the hero or the rival in the FightController.
So, it would essentially be something like the following (don't mind the sloppy rudimentary code, I haven't written Java in ~2 years, I just slapped this together and I'm not sure it will compile):
public class Fighter {
private int health;
private boolean isTheHero;
public Fighter(int startHealth, boolean hero) {
health = startHealth;
isTheHero = hero;
}
public void adjustHealth(int change) {
if (change > health) {
return 0;
}
health -= change;
return health;
}
public boolean isHero() {
return is_hero;
}
public boolean wasBeaten() {
return health <= 0;
}
}
public class FightController {
private Fighter hero;
private Fighter rival;
private boolean isHerosTurn;
public FightController() {
hero = new Fighter(startHealth, true);
rival = new Fighter(startHealth, false);
isHerosTurn = true;
}
public void takeATurn() {
int hitValue = 15; //Do something to figure out the hit
remainder = 0;
if (hero.wasBeaten() or rival.wasBeaten()) {
sys.out.println("This match is already over");
} else {
if (isHerosTurn) {
remainder = rival.adjustHealth(hitValue);
if (remainder == 0) {
sys.out.println("The HERO wins!!!");
}
} else {
remainder = hero.adjustHealth(hitValue);
if (remainder == 0) {
sys.out.println("The Rival wins. Boo!");
}
}
isHerosTurn = !isHerosTurn;
}
}
}
Then you can do something like:
controller = new FightController();
controller.takeATurn();
controller.takeATurn();
controller.takeATurn();
controller.takeATurn();
on and on until the game is over.
You need to think in terms of a framework for java gaming.
Here's another post addressing the issue,
Game programming in Java?
Objects interact by sending messages. Look at it this way: when a player attacks, then he sends it's violent message to another players reveiveHit method.
Or, to implement it with a common design pattern: a player could send out attacks and other players observe it's behaviour and determine, if they have been hit.
What you shouldn't do: make one player depend on another one (like in your example). If you want to model a match, then add some sort of manager/referee that does the bookkeeping of attacks and effects.
Please help me understanding why we
use interfaces
Implementing an interface allows a class to become more formal about the behavior it promises to provide also they form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.
1 . Why we are implementing interfaces ?
2. Why do we need interfaces in Java?
and , the anwser to my question
Since your code has common attack( ) method in both the classes i.e Rival and Hero, best way would be to declare the method in an interface.
Remember, following is just a code-snippet, not the complete code. You can complete it yourself.
public interface Fight {
public int attack();
}
public class Hero implements Fight {
public int attack() {
rival1.getHealth(-15);
}
}
public class Rival implements Fight {
public int attack() {
hero1.getHealth(-15);
}
}
This is the interface for the character in the game which interact with each other.
public interface Character{ ... }
This is the interface if the character is able to attack or not.
public interface Fightable{
public void attack(Character character);
}
These are the two classes in your game which implements both the interfaces.
public class Hero implements Character, Fightable
{
// heros version of implemented method
public int attack(Character character)
{
// idealy when hero attacks, the health value will be reduced by 15 of what it is.
character.setHealth(-15);
}
}
public class Villon implements Character, Fightable
{
// rival version of implemented method
public int attack(Character character)
{
// idealy when rival attacks, the health value will be reduced by 15 of what it is.
character.setHealth(- 15);
}
}