So apologies if this question has been answered already, although I did have an extensive look but couldnt quite find the answer. To sum up the situation I am trying to create a simulator program that deals with different predator and prey creatures and currently have the issue of getting each creature to check what type of creature it is next to, which I would prefer to do checking if the instance belongs to the same object.
So say for example I did this:
private class Creature {
...
Creature [] fish = new Creature();
Creature [] shark = new Creature();
Creature [] penguin = new Creature();
}
and then created several instances (creatures) of each type in a loop like so:
for (int f=1;f<rnd;f++) {
fish[f] = new Creature();
//set attributes of creature
and then so the program can tell where they are located in relation to each other I created a grid system like so:
Creature [][] gridloc = new Creature[x][y]; //relates to number of spaces tiles that determines movement.
Creature [] crloc = new Creature[tc]; //stores a reference to all creatures created.
...
crloc[tc] = fish[f]; gridloc[x][y]=crloc[tc] //or fish[f]
}
Anyway to sum even tho I summarised the code there quite a lot, that all works but when getting each creature to check next to it in gridloc for what is there e.g. a predator I am unsure of a way to check if it finds another creature to determine if that is an instance of the same object type or a different one. So something like:
if (!gridloc[x][y].getObject().equals(gridloc[x+1][y].getObject()) //if the current creature is not the same as the one next to it.
I am aware of things like instanceof but that only works with checking if an object is an instance of a class, not if a instance belongs to the same type of object. I also can't simply use fish[1].equals(fish[2]) because they have different attributes and that would check if they are exactly the same.
Any ideas/suggestions would be welcome. Thanks!
You need to look into Polymorphism (http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html). You declare a Creature as a base class (or interface) and extend/implement from Creature class for each type of a creature you have. Each subclass will implement it's own methods to override Creature and allow you to correctly use the methods and also to detect the type using the class metadata that each instance will have.
It's an issue with your design. You have to create a Super class called Creature and sub classes for fish , penguin and all others. Then create the arrays with those sub class types. Then you can do the instanceof checks with your adjacent objects of the grid.
This design is based on Polymorphism.
In the long run this is the best approach since code is more clean and structured. If you do this way, even after few years when you take a look at the code; still it will make sense.
One option (and perhaps the best in the long run, see answers by #AlexC and #Don) would be to make subclasses of Creature, called Fish, Shark, Penguin etc. Then you can use instanceof.
To combine that with polymorphism, you'd add a method public boolean eats(Creature other) As an aside, when I helped babysit a 4 year old his favorite game with little plastic animal figures was "what eats what" with loud screams of delight.
In Creature, the code would be return false; (though arguably fish eat fish?)
In Penguin, the code would be return other instanceof Fish;
In Shark, the code would be return true;
Another option would be to have a field of Creature that describes it. Maybe an enum, or a String for the latin classification names. Then, you could use something like genus.equals("Carcharodon") for Shark or latinName.contains("Spheniscidae") for Penguin.
Maybe creature should be an enum...
public enum Creature {
FISH(false), SHARK(true), PENGUIN(true);
private boolean isPredator;
private Point gridLocation;
Creature(boolean isPredator) {
this.isPredator = isPredator;
}
// ...getters/setters
}
with a separate world class for grid locations...
public class World {
List<Creature> creatures = new LinkedList<>();
public boolean isNearPredator(Creature c) {
for (Creature i : creatures) {
if (i.getGridLocation().distance(c.getGridLocation()) < 2
&& i.isPredator()) {
System.out.println("About to get eaten!");
}
}
}
}
Related
I did the following, i got a stackoverflow error after some time, and I understand why it was.
public class Cat {
String name="default name";
Cat insideCat;
public Cat(){
System.out.println("Cat constructor");
insideCat = new Cat();
}
}
But what if I don't create a new Cat object within the constructor, but take a parameter of Cat type and assign it to the insideCat field.
public class Cat {
String name="default name";
Cat insideCat;
public Cat(Cat insideCat){
System.out.println("Cat constructor");
this.insideCat = insideCat;
}
}
I am just playing around with the code, just trying to find out what Java can do and cannot. In the second code, everything looked normal, until I started to test this class. I need a Cat object to create a Cat object (and to create this Cat object I need another Cat object...and it goes on). So technically I cannot test this class.
So my question is WHY does java allow to create an instance variable of its own type? I guess the whole purpose of a constructor is to initialize it's instance variables. So either I have to create a new object to initialize the insideCat or else I have to take Cat object from outside. Both doesn't seem to work.
What am I missing here. Is there any occurrence where instance variables of its own types can become useful, and can be used without any problem? Is it bad OOP practice to come up with classes like this?
Classes like this exist all the time.
Consider linked lists or trees, e.g.,
class ListNode {
ListNode next;
// Etc.
}
class TreeNode {
TreeNode left;
TreeNode right;
// Etc.
}
You wouldn't initialize the "child" objects in the constructor, you'd add them later.
In your example you'd need to have a method that created the insideCat at a later time. In general you wouldn't create child objects that had the exact same state, there'd be something to differentiate them either at construction time, in which case you could have a "oh god stop creating these now" condition, or while they were being added, e.g., you'd add them via a method and not in a constructor.
There is nothing wrong in having an instance member of same class.
an Employee has a manager and the manager is also an Employee
public class Employee{
private Employee manager;
//getters setters and constructor
}
There are many examples of self referencing data structures that are valid. Think of a LinkedList. Each LinkNode has a data field, and a pointer to the next LinkNode.
class LinkNode {
int data;
LinkNode nextLink;
public LinkNode(int d1) {
data = d1;
nextLink = null;
}
...
}
class LinkedList {
private LinkNode first;
...
}
Your StackOverflow problem stems from the fact that creating an instead of X requires the creation of another X, ad-infinitum.
Just think of your Cat example. Why would instantiating a Cat require of all things...another Cat!
There can be multiple constructors. Thus, you can have another constructor
public Cat(){...}
That would allow you to create an inside Cat. Afterwards you could create another Cat that contains the inside Cat. Obviously, the design might not be great here, depending on your needs. Dave Newton's answer about linked list is a great real world example of this usage.
I know that you can only have an array of a certain type (e.g. String, int, Student, etc.). I was wondering if this held true in the case of inheritance - i.e. whether or not a Bicycle object that extends Vehicle could be placed in a Vehicle array along with something else, like a Bus object.
Here's my code:
public class Test{
public static void main(String[] args) {
Bus bus1 = new Bus();
Bicycle bike1 = new Bicycle();
bike1.changeGear(true);
Bus bus2 = new Bus();
Vehicle[] myFleet = {bus1, bike1, bus2}; // Note that Vehicle is an abstract class
for (Bus v: myFleet){ // Trying to access every bus in the Vehicle array. I already
v.issueTicket(1.50); // tried to get the computer to treat myFleet as a Bus array - doesn't
System.out.println(v); // work, sadly.
}
}
}
Note that this is in the Java language
You have an array of a super type.
for iterates through ALL items in an iterable object (here array).
Since there can be Bicycle or Bus instances (or even other types, which are currently unknown) in the array, you cannot treat it as a Bus Array.
What you probably want is this :
for (Vehicle v : myFleet) {
if (v instanceof Bus) {
Bus b = (Bus)v;
b.doSomeSpecialThingsForABus();
}
}
There is no good other way around this except for the visitor pattern maybe.
If ClassTwo extends ClassOne and you make an array of ClassOnes, then you can add objects of ClassTwo to the array, however, you may only access members of ClassOne unless you cast.
Took me some time to get your point.
If you want to do something like this, you'll have to cast the Vehicle into a Bus.
However usually you should have an interface common to all vehicles.
As issueTicket() does not apply to bicycles you could probably think about not using the same interface for busses and bicycles at all.
Another idea would be to implement the issueTicket() method for bicecles just signalling an error as soon as it's called:
Vehicle[] myFleet = {bus1, bike1, bus2}; // Note that Vehicle is an abstract class
for (Vehicle v: myFleet){
v.issueTicket(1.50);
System.out.println(v);
}
However in my opinion this still feels like a design which could be better.
For me to provide some more suggestions it would be good to know the reason why those objects shall be stored within the same container.
Hope that helps.
Best regards,
Joerg
You can use
java.lang.Object[] myFleet;
But that could be too generic.
If your objects have a common interface (say Foo) then you could use
Foo[] myFleet;
Also have a look at some Java containers like ArrayList.
Yes...but
Yes, you can have an array of Vehicles, eg Bus1, Bus2 and Bike1.
...But that doesn't stop your Bike being a Bike, or turn it into a Bus. An array is a list of references to objects, it doesn't take a new copy of the object and turn it into the type of the array: the objects will still be instances of their original class
The Array can hold vehicles regardless of their sub-class, it doesn't change them into Buses, Bikes or Vehicles: the type stays the same.
You can try to cast a bike as a bus, however: if you accept that you'll lose any non-bus attributes. You can also use instanceof to decide if the Vehicle is a Bus already, or a Bike, and do conversion stuff if required
ie
for (Vehicle v: myFleet){ // For each vehicle in the fleet
Bus b = (Bus) v; // Turn the vehicle into a bus
b.issueTicket(1.50);
System.out.println(b);
}
Provided that bus and bicycle both either extend the same superclass or implement the same interface they can be placed into an array of the type of either the interface or the superclass.
To access those you can check if they are instances of any of the subclasses
for (Vehicle v: myFleet){
if(v instanceof Bus){
((Bus) v).issueTicket(1.50);
}
}
However using instanceof is not advised and in most cases it is better to find either an interface or superclass that describes the generic functionality required for all objects in the array.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am trying to turn a board game into a multiplayer game using java, but I have a few questions as to how I can achieve what I want.
In the game, there is a bag that holds Creatures, Buildings and Magic. Each player draws from this bag to get their game pieces. They then proceed to either put the pieces on tiles in the game board that they own right away, or they hold onto the pieces and play them at a later date. The tiles can hold creatures, magic, buildings, forts.
Right now I have an ArrayList that is holding all of the creatures, and each tile has an ArrayList that can hold creatures.
It looks like an ArrayList is not what I want to be using, as I would have to have the ArrayList be of type Object (which is bad). Any ideas on how I can design my program so I don't have to cast to Object? I'm not sure if I need a wrapper class, or just multiple array lists, but The confusing things is when a player is drawing from the bag that contains a bunch of different things. I should be able to differentiate what is moving around the board easily enough.
Any suggestions?
Can Creatures, Buildings, and Magic all implement the same interface or extend the same class? Then you could have an ArrayList that contains that interface or class. Alternatively, just have a data structure that contains three ArrayLists and write code that picks fairly between them.
I would suggest an interface that each object implements:
interface Bagable {
public String getType();
}
Then each object can be done in this fashion:
class Creature implements Bagable {
public String getType() {
return "Creature";
}
// Normal Creature Class methods...
}
class Building implements Bagable {
public String getType() {
return "Buidling";
}
// Normal Building Class methods...
}
class Magic implements Bagable {
public String getType() {
return "Magic";
}
// Normal Magic Class methods...
}
public static void main(String args[]) {
ArrayList<Bagable> bag = new ArrayList<Bagable>();
bag.add(new Creature());
bag.add(new Building());
bag.add(new Magic());
for (int i = 0; i < bag.size(); i++ ) {
System.out.println(bag.get(i).getType());
}
}
Or you could have the types as built in values
int ITEM_TYPE_MAGIC = 0;
int ITEM_TYPE_CREATURE = 1;
int ITEM_TYPE_BUILDING = 2;
and check them against these built in values
One solution would be to create an interface, for example BagItem (which could define any common behaviours that the items in the bag would be expected to do), and have each of Creature, Building, Magic, etc, implement this interface. This would mean you could have an ArrayList<BagItem> (or other collection).
In my opinion, the real benefit to this is that common behaviour can be defined at the interface level, rather than just being able to stuff random stuff into the bag. If there isn't any common functionality between the items being put into a given bag/collection, then maybe consider having more than one bag (or maybe 'pockets' in the bag?) if that's an option.
I'm building a basic game from a brief, and have been given some code to look at. All characters in the game are game objects, some are moveable ones, and some aren't. The moveable ones have a position and direction.
I have been given a MoveableObject class (below). Moveable GameObjects instantiate this class in their own constructor. I have not been guaranteed this code is right, so I'm trying to grasp the theory behind it.
public class MoveableObject {
int speed;
String direction;
public MoveableObject(){
speed = 0;
direction = "unknown";
}
public MoveableObject(int iSpeed, String sDirection){
speed = iSpeed;
direction = sDirection;
}
and all the moveable characters create an instance of this class in a constructor. For example, from a vampire class.
public class Vampire
public Vampire(){
MoveableObject thisObject = new MoveableObject(30, "South-East");
}
}
To my knowledge, this is known as aggregation. I thought this was to be used in a HAS-A relationship, and not an IS-A. Since a character IS-A moveable object, should I not use inheritance or an interface? I also don't understand why you need to create an instance of a MoveableObject, if each character either is or isn't moveable, surely, you should give them the ability to be moveable or not (through inheritance or interface) and then instantiate the character?
Thanks in advance.
That depends if the MoveableObject class also takes care of the actual movement of the object (i.e. update its position according to the speed and direction members) or just holds the speed and direction members so that the engine module of the game will use it to calculate the object's position.
In the latter case I would change the name of the MoveableObject class to something more appropriate and stick with the aggregation. Otherwise an inheritance will be more appropriate for movable objects. That way the moving logic will be implemented once and the sub classes can take care only for their own specific need.
To explain further if the MoveableObject is just a data container you can create an interface :
public Interface Moveable {
public MoveableObject getMovementData();
}
and each moveable class will look like :
public class Vampire implements Moveable {
.
.
private MoveableObject movementData; //
.
.
public MoveableObject getMovementData() {
return movementData;
}
}
and in your game engine hold an array of all moving objects (Type moveable) and in the update method get the movement data and process it:
public Class GameEngine {
.
.
private ArrayList<Moveable> movableObjects = .....
.
.
public void gameUpdate() {
for (Moveable moveableObj : movableObjects) {
MoveableObject movementData = moveableObj.getMovementData();
// Process and update as required using the given data
}
}
this is a 2 part question.
I have two classes: Animal and Vehicle which I'll be instantiating as objects. Animal contains two instance variables: numLegs and animalName, and Vehicle contains one instance variable: numTires, both classes contain getters and setters.
I have a generic class Box that holds either an Animal or a Vehicle.
Suppose I want to create an Arraylist of boxes. Every Box in said Arraylist will hold exclusively type Animal or exclusively type Vehicle.
e.g: In the case of exclusively animals, this will look something to the effect of:
List<Box<Animal>> list = new ArrayList<Box<Animal>>();
list.add( new Box<Animal>( new Animal( "fluffy", 4 ) ) );
(1). What should the box class look like?
also, suppose I want to perform a getter on an animal from the list.
Such as: System.out.println(list.get(0).getName());
(2). how would I go about this properly?
I'm not exactly sure what you're after, but if you're wanting a generically typed Box class, it probably needs to look something like this:
public class Box<T extends SuperclassOfAnimalAndVehicle> {
T myModeOfTransport;
Box(T myModeOfTransport) {
this.myModeOfTransport = myModeOfTransport;
}
public T getModeOfTransport() {
return myModeOfTransport;
}
}
This line: list.get(0).getName() won't do however. You'll have to get the object that Box contains. So using my example, it would be list.get(0).getModeOfTransport().getName(), assuming Vehicle and Animal both have getName() methods.
All that being said, I'm really confused about why exactly this is necessary. Perhaps if you explained the bigger picture I could give you a more complete answer.
If you want to have a list containing two or more entities with nothing in common then you will always need to specialize your code to address each of them. This Box class is completlly useless.
Object o = list.get(0);
if(o instanceof Animal) {
System.out.println(((Animal)o).getName());
}