Im writing a small java game in which there are various types of monsters, a couple computer controlled players and a human controlled player. The game world is a fairly basic 2D grid. The grid is declared so that it expects Humanoid objects. That is, Humanoid [][] grid. However, various parts of the humanoid code need to be overridden for each type of character.
What im having some trouble with is how I can call the humans specific move method if the code expects Humanoids and also how to check bounds on the movement.
If anything is unclear, let me know.
Thanks
Note: My humanoid class doesn't have a move method and due to the fact that im doing this for class, it isn't allowed to either
You don't have to do anything. If you have a Humanoid class, with a move method, and a Human class that extends from Humanoid, with its own move method, when you call move Human's version will be used (if you call it on a Human instance).
So if you do
Humanoid human = new Human();
human.move(); // Human's move is invoked
Humanoid orc = new Orc();
orc.move(); // Orc's move is invoked
the runtime automagically invokes the appropriate move method.
If you override the methods in subclasses, you don't have to do anything special to call them. Just call the method on your Humanoid variable, and whatever actual class the instance is, that's the version of the method that will run.
You'll probably want to make Humanoid an abstract class with abstract methods that must be defined in subclasses, or maybe even an interface. But it'll work even if you define a method, with code, in Humanoid and then override that same method with different code in a subclass. The subclass's version of the method will run when the object you call it on is an instance of the subclass, even if your variable is of type Humanoid, not the subclass.
The point of inheriting is that you should not have to know which sub-class you are operating on. For instance, say that both humans and monsters shared a base class called "Mobile", and Mobile had an abstract method "move". Humans might override move to walk across the map, birds might override it to fly, and landsharks might swim under ground.
Thing is, your map just calls Mobile.move(), and the action will be delegated to the actual subclass to do the moving.
If you have to know which class you using, you're doing it wrong--however sometimes you need to know something ABOUT the class, for instance, if the terrain is impassable, then you might call Mobile.canFly() to see if the given critter supports flying.
Later, if you decide humans can fly via spells you simply modify the human class and everything else just works, but if you had tested the class and only permitted "Vulture", "Eagle" and "Dragon" to fly over an obstacle, then your code is a lot messier to fix up if you change it or add to it.
Related
This may be a bit general and I apologize if it is too much so. It pertains to an assignment for a college class and as such would like to focus on my understanding of the topic as opposed to what the answer should be.
As I understand the situation:
I have one parent class called pet, and two subclasses called Dog and Cat. The UML class Diagrams specify that Pet contains the methods createPet(), updatePet(), and petCheckIn().
petCheckIn() requires the ability to create an object if it isn't already, and update one if it is.
The two subclasses contain default constructors, as well as setters and getters for their attributes, but nothing else specific to them.
I don't believe there would be an instance when a Pet object would be needed as the pets being checked in would always be dogs or cats. If constructors are not inherited by the subclasses but methods are, and createPet() is not strictly speaking a constructor, can an inherited method perform the constructor function if designed properly? I feel the implementation should be something like (not concerned about exact syntax as much as I am my understanding of what can and cant be done here):
My pseudocode :
Execute Dog/Cat inherited petCheckIn()
IF new pet THEN
Execute Dog/Cat inherited createPet()
ELSE
Execute Dog/Cat inherited updatePet()
This is an entry level programming class, and so I cant imagine that the implementation would be terribly complex.
Likely I am misunderstanding something/overcomplicating.
Regardless, Thanks for your time.
EDIT:
Truly sorry I never got back to you #Karam and #Chung. Life hits like a freight train sometimes lol. Specifying another class was out of scope for the assignment (though most of what I wanted to know seems to have been as well), nothing was specified about the signature (thats methodName + its arguments correct?). Ultimately I believe a lot depends on how the classes would be implemented by the overall program which was not covered in detail. I can pretty confidently say I was just asking questions that were beyond what was intended at that stage of the lesson plan. I wound up using a parametered constructor in the super class, and another in the subclass which passed arguments for superclass fields to the superclass constructor, then initialized the subclass specific fields. Karam, I never wound up actually defining the methods by which the constructors were called, and wasnt able to educate myself on design patterns, but a relative of mine also mentioned an abstract factory. Id say that is likely the best way to handle it. Unfortunately I do not have more time to dig into this right now so Im calling it good.
Cant tell yall how much I appreciate your willingness to help.
Dog.java constructor:
//Overloaded Constructor that passes parameters to Superclass
constructor.
//TODO: Reconsider which fields need a parameter and which can be set to
default at this point in the program.
//TODO: Verify that not passing an argument for catSpace will default to
-1.
//FIXME: Is dogSpaceNBR known at this point in program?
public Dog(int dogSpaceNBRInput, double dogWeightInput, boolean
groomingInput, String petTypeInput, String petNameInput, int petAgeInput,
int dogSpaceInput, int catSpaceInput, int daysStayInput, double
amountDueInput) {
// Passes arguments common to all pet subclasses to superclass
constructor.
super(petTypeInput, petNameInput, petAgeInput, dogSpaceInput,
catSpaceInput, daysStayInput, amountDueInput);
//Dog specific variables
dogSpaceNbr = dogSpaceNBRInput;
dogWeight = dogWeightInput;
grooming = groomingInput;
}
If i understand well your question , you want to be able to create different instances of your pet depending on the subclass using only methods
There is a Design Pattern called Abstract Factory , it is used to ignore the creation of different methods in a concret way
Example :
You have the class Pet ( it should be abstract ) that contains the method createPet() {}
In your sublcass , you'll have to simply redefine the method createPet() { return new Dog() ; /* or */ return new Cat() ;}
This helps you whenever you create a new sublcass , to redefine the methods without changing in the original class , and this will goes not only for the method createPet() but for all your methods
I've been developing a small text-based RPG game in Java. I've written a story-line and did inventory/armor equipment. I've ran into a problem when it comes to accessing some code though. At the beginning of the game, the user can choose to be an archer/mage/warrior (i'll refer to these as "Jobs" not "class"). Each of these have their own class. But when incorporating them into the game, I find that i'm doing a lot of if-statements to always check if the user is a archer/mage/warrior.
How would I better integrate this without using if-statements everywhere? I'm a beginner/intermediate level and doing Objects for about a month now.
It would be easiest to use polymorphism for this, but this isn't possible if the methods have different names...
If you wanted to do this polymorphically:
First off, read up on polymorphism. Here's a good website to do that.
To start off, have all of your classes extend a superclass, say Player (you will have to write the Player class before you can extend it). To extend the Player class, you can write something like this in the header of your "job" classes:
public class Mage extends Player {
Of course, you substitute Mage for the different classes depending on what "job" you're defining.
Inside the Player class, which you will have to write, you should define all of the methods you want your subclasses to be able to execute. You should make these methods abstract, but keep in mind, if you have an abstract method, you will have to define it in ALL of your subclasses. So, if you had a abstract method called "Cast" you would need to define this in EVERY "job" class.
But once you have created a superclass, with methods, (I suggest having general abstract methods such as Attack or Defend), just define these methods in the subclasses, and you're good to go.
If you want to do this non-polymorphically:
An if-statement, while not necessarily pleasant, appears to be the most effective way to do this, if you don't want to try to make the behaviors polymorphic.
Could you say what the structure of your if-statement is? There might be an easier way to write it, and cut down on the amount of code (to make it more legible).
For example, if you are saying:
if (a.getClass() == X.class)
You could consider using instanceOf instead:
if (a instanceof X)
Besides this, I don't have any better ideas on how to do this.
I have a class, lets say CargoShip, which is a derived class of 'Starcraft', which implements the interface IStarcraft.
This is the function that should return the count (number of instances) of every ship:
public static void printInstanceNumberPerClass (ArrayList<ISpacecraft> fleet){}
There's a solution which I thought of and I'm sure it will work, declaring 'getCount()' in ISpacecraft, then overriding it in each SpaceCraft ship (I have 4 ships), and just iterating through everyone of them, polymorphism.
Fine, I got that. but because the function is static (yes, I know we dont need to create an object to use it) I thought it might tell me something different. What do I mean by that? Is it possible to create 'static count = 0' instead, in every ship, and somehow access it?
The question is then, how can I access that static field when I get an arraylist of ISpacecraft objects?
Polymorphism doesn't work with static methods, method resolution is very different. For virtual methods on an instance the code may be referring to the object with a variable typed as a superclass or interface, and calling a method is resolved at runtime without your application code needing to know the exact concrete type. For static methods you call it on a specific class and if the method isn't found then it's called on a superclass. Your code has to start with some subclass and resolution works up the hierarchy from there. For static methods you can't not know a low-level class to call the method on, the way you can with instance methods on objects. You can't have the level of abstraction you take for granted with objects.
The comment by markspace provides a much better alternative. Use static methods for stateless functions like java.lang.Math.
When writing a program in Java, if I have a special case of an object that needs to be treated differently by the main class but that does not require any additional methods, is it better to add a boolean parameter to the constructor of the object such as isSpecial and to check whether the object is special in the main class or to create a new object that extends the original?
Example:
I have a Cat class. If a cat has whiskers, I want to print "This cat has whiskers!" in the Main class.
Would it be better to have a WhiskerCat class or to simply add a boolean parameter to the Cat constructor such as hasWhiskers?
Simply add the boolean parameter. You don't want to end up with an excess of classes that do roughly the same thing. For example, in the Cat class, the default value for hasWhiskers should be false, and remain false if they don't call the constructor that explicitly requires them to specify it. Then you can have a hasWhiskers() method that returns this boolean attribute.
In general, only extend a class if the new class has additional functionality (additional methods etc) that cannot simply be tacked on to the original.
It's a problem of responsibilities: which class is doing what?
Your "main" class should not probably be aware of the internals of the "Cat" class.
In your case that means the implementation of the Cat class would probably need to be adjusted to either have a new interface that the main class could use to print that message.
Then the Cat class itself could either have that boolean, a (list of) component that make up the cat or you could go the inheritance way. This will most likely depend on the real problem: is there many more variations? is that really the only difference? are you taking a class/exam? (in the last case it might be more useful to just apply the way you've been taught).
I think the problems are about design patterns instead of coding style.
In general,if you want to add some new features in a class.
First,you should ask yourself is it a interface or a property?If it is a property,then there are two ways to tackle it.
Way 1:subclass as you metioned
Way 2:you should use delegate (i.e. add a hairclass to consider whether it is a long hair cat
or it is short hair cat.)
Just wondering, is adding a boolean the only way to recognize if the object is special? For sure there must be other characteristics that make it special?
Anyway, it's not the responsibility of the main class to know if it is. Leave what should be printed to the Cat class, not on the Main class.
In my opinion it depends on how special that attribute is.
If we consider another example:
cars...
The attribute 'sunroof' or 'navi' is quite common and has no special requirement to the car and may be part of the base class.
But a siren and flash light are quite uncommon and would be better fit if they are attributes of another extended class.
I have a bunch of classes extending an abstract Base class.
Each subclass takes an array as in the constructor, (different length depending on class).
These classes could be written by other people.
What is the best way to figure out the length of the array the class needs?
I could:
(A) Require that each derived class have a static method, returning the length.
However, the base class cannot enforce this, since abstract static methods does not work in java.
(B) Each derived class have a constructor with no arguments, and I construct
such classes just to be able to call the countParameters() method, that
I can enforce from the Base class. This feels "cludgy", since I am not interested in creating such object, but only need some info about it.
The reason is that I am creating a GUI, that gives the user the ability to create
instances of Derived classes, but each Derived class takes different number of parameters.
That is, I need to know how to draw the GUI before I can create the classes.
EDIT:
I could just require that each Derived class have a private
constructor, with no arguments, and using reflection I can call the countParameters() method.
EDIT2: Actually, what I am interested in, is what the names of the parameters are.
That is, if the class Derived have the constructor
public Derived(double name1,double name2,...)
I need a way to generate the String[] array
{name1,name2,...}
I guess this would be impossible to do without creating an instance of the class,
but for the user to be able to create such class, he/she needs the parameter names!
Moment 22.
It sounds like you need the Factory Pattern.
In general, it's a bad idea for a base class to know the set of it's descendant's. So you define another class whose job it is to know that.
If you have something like a Shape, with ThisShape and ThatShape as derived classes, then a ShapeCreator will handle the job of creating the specific set of shapes your program supports, giving each one the arguments it needs.
It's not quite clear what you're trying to achieve, but I wonder: Do the subclasses really have to take a single parameter with an array, as opposed to a list of parameters?
Constructor<?> ctor = Test.class.getConstructors()[0];
int parameterCount = ctor.getParameterTypes().length;
ctor.newInstance(new Object[parameterCount]);
how about this code:
public absract Base {
public abstract int size();
public Base(Object[] objs) {
if (objs.length != size()) {
throw new IllegalArgumentException();
}
//rest of your code.
}
each child class needs to implement size method.
hope its help.
I'd go with method A. You can't get the compiler to enforce the existence of such a method, but you can certainly enforce it in your program - no method, no work!
Seriously, this whole scheme is a bit brittle and I can't think of a way to make it significantly better. An incorrect implementation of those subclasses will bomb out, that's life.
A possible remedy would be for you to provide a set of interfaces for those subclasses, such as
SubClassTaking2Args
SubClassTaking3Args
...
and requiring your sub's to implement one of those as a marker interface. But that's just more bureaucracy with little more effect.