So in a simple game engine of mine I use an interface "UpdatedGameElement" to signal that an object having that interface has to be updated every frame through an implementation of an update() method.
Now in my "main"(not THE main) class I iterate through a list of GameElement 's and check if these are an instanceof UpdatedGameElement. If this is the case I cast them, and then call .update().
Now the thing is, I just read that using instanceof is usually a sign of bad coding; and in cases where classes are used as markers when they could be easily replaced with a variable, I agree. But I'm not so sure about my case.
I guess I could let the GameElement class implement UpdatedGameElement, and define a standard empty update() method that needs to be overridden to actually do something, but I'm not sure if and why that would be better than what I have now.
What would you say?
Edit: some code from my main class:
public void process()
{
if (active)
{
for (GameElement GE: elements)
{
if (!GE.isToBeRemoved())
{
//Relevant part
if (GE instanceof UpdatedGameElement)
{
((UpdatedGameElement) GE).update();
}
}
else
{
prepareRemoval(GE);
}
}
processRemovals();
}
}
Following the invitation if the OP:
If use of the interface has no other reason than to add a marker plus the update method to GEs, and if the type UGE isn't used except after this single instanceof, then it is a weak reason for having these extra types. ESpecially when the capability of being updated can be extended to all other GEs, where it is just a NOOP.
An abstract method in the base class forces the programmer to decide whether update needs to be coded for a particular subclass. This approach is rather "safe" from a "defensive design" point of view. But, of course, you write more code.
In contrast to the previous technique: If you forget the interface there's no alarm.
Also, if you code a NOOP update method in the base class and rely on programmers' alacrity to override where necessary: convenient, but risky when you forget to do it.
Summarizing: There are a few subtle pro's and con's - not just the instanceof "smell".
Based on your comments you mentioned that GameElement implements UpdatedGameElement, for now GameElement is the only class which is implementing UpdatedGameElement but it could be more in future. Also I hope you are aware that an interface cannot be instantiated thus you cannot create an instance of UpdatedGameElement thus in real the instances are created of the implementing classes of an interface. Thus during runtime when you create an instance of GameElement and assign it to UpdatedGameElement variable, that doesn't mean the instance is of type UpdatedGameElement now, its actually of type GameElement, now suppose that you have one more class implementing XYZElement implements UpdatedGameElement and create instance as below:
UpdatedGameElement ge = new GameElement();
UpdatedGameElement xyze = new XYZElement();
Do you think it good to use instance of check as below, as in either case it will be true and you never know which kind of instance ge and xyze are of.
if(ge instance of UpdatedGameElement)
instead one should always check for if(ge instance of GameElement)
Similarly for if(xyze instance of UpdatedGameElement)
instead one should always check for if(ge instance of XYZElement)
Hope this helps.
I guess I could let the GameElement class implement
UpdatedGameElement, and define a standard empty update() method that
needs to be overridden to actually do something
Yes, you should definitely do it!
Reason: suppose in the future you'll need to implement another "updateable" class that extends UpdatedGameElement - consider the code changes you'll have to do in every place you've used instanceof...
Related
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.
So in java the way to initialise an interface, such as a collection or list, is to create an instance of a class that implements it, eg:
Collection<Object> moo = new ArrayList();
If I wanted to specify an implementation at a later time in my code, I was thinking of doing this by creating another class like:
class ListList extends ArrayList{
}
and then initialise the variable with
Collection<Object> moo = new ListList();
And then all that's required if I want to change the implementation later on is to change what ListList extends.
So, here's the question.. is there a better way of doing this (I still feel as though I'm inexperienced with this type of thing).
is there a better way of doing this
Yes: use a factory method:
public static Collection<Object> createCollection() {
return new ArrayList<Object>(); // change this later, if need be
}
Then, invoke the factory rather than instantiating:
Collection<Object> moo = createCollection();
Your suggestion of using a "dummy" subclass might appear attractive, but such abuses of inheritance invariably lead to pain and suffering later on. You really don't want to do that.
You could also do it that way
Collection<Object> coll=new ArrayList(){
//bla
};
The basic idea is a good one. Make your variable/field/... an instance of the interface and not of the concrete class you are using. This will force all your code to work against the interface (on the condition that you not start casting somewhere down your code path), and allows to replace the implementation later on with a different class if you feel the need for it.
One can start discussion about how you create that concrete class, like for example using a factory method as #skaffman suggested in his response. However, this might depend on the situation. If it is just for a one-time use like initializing a field you can just create the instance without bothering about factory methods.
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.
In my quest to correctly grasp Interface best practices, I have noticed declarations such as:
List<String> myList = new ArrayList<String>();
instead of
ArrayList<String> myList = new ArrayList<String>();
-To my understanding the reason is because it allows flexibility in case one day you do not want to implement an ArrayList but maybe another type of list.
With this logic, I set up an example:
public class InterfaceTest {
public static void main(String[] args) {
PetInterface p = new Cat();
p.talk();
}
}
interface PetInterface {
public void talk();
}
class Dog implements PetInterface {
#Override
public void talk() {
System.out.println("Bark!");
}
}
class Cat implements PetInterface {
#Override
public void talk() {
System.out.println("Meow!");
}
public void batheSelf() {
System.out.println("Cat bathing");
}
}
My question is, I cannot access the batheSelf() method because it only exists for Cat. That leads me to believe that I should only declare from an Interface if I am only going to use methods declared in the Interface (and not extra methods from the subclass), otherwise I should declare from the Class directly (in this case Cat). Am I correct in this assumption?
When there is a choice between referring to an object by their interface or a class, the former should be preferred, but only if an appropriate type exists.
Consider StringimplementsCharSequence as an example. You should not just blindly use CharSequence in preferrence to String for all cases, because that would deny you simple operations like trim(), toUpperCase(), etc.
However, a method that takes a String only to care about its sequence of char values should use CharSequence instead, because that is the appropriate type in this case. This is in fact the case with replace(CharSequence target, CharSequence replacement) in the String class.
Another example is java.util.regex.Pattern and its Matcher matcher(CharSequence) method. This lets a Matcher be created from Pattern for not just String, but also for all other CharSequence there are out there.
A great example in the library of where an interface should've been used, but unfortunately wasn't, can also be found in Matcher: its appendReplacement and appendTail methods accept only StringBuffer. This class has largely been replaced by its faster cousin StringBuilder since 1.5.
A StringBuilder is not a StringBuffer, so we can not use the former with the append… methods in Matcher. However, both of them implementsAppendable (also introduced in 1.5). Ideally Matcher's append… method should accept any Appendable, and we would then be able to use StringBuilder, as well as all other Appendable available!
So we can see how when an appropriate type exists referring to objects by their interfaces can be a powerful abstraction, but only if those types exist. If the type does not exist, then you may consider defining one of your own if it makes sense. In this Cat example, you may define interface SelfBathable, for example. Then instead of referring to a Cat, you can accept any SelfBathable object (e.g. a Parakeet)
If it does not make sense to create a new type, then by all means you can refer to it by its class.
See also
Effective Java 2nd Edition, Item 52: Refer to objects by their interfaces
If appropriate interface types exist, then parameters, return values, and fields should all be declared using interface types. If you get into the habit of using interface types, your program will be much more flexible. It is entirely appropriate to refer to an object by a class if no appropriate interface exists.
Related links
Bug ID: 5066679 - java.util.regex.Matcher should make more use of Appendable
Yes, you are correct. You should declare as the most general type providing the methods you use.
This is the concept of polymorphism.
Your are correct, but you can cast from the interface to the desired pet if you need. For example:
PetInterface p = new Cat();
((Cat)p).batheSelf();
Of course if you try to cast your pet to a dog you cannot call the batheSelf() method. It would not even compile. So, to avoid problems, you could have a method like this:
public void bathe(PetInterface p){
if (p instanceof Cat) {
Cat c = (Cat) p;
c.batheSelf();
}
}
When using instanceof, you make sure you will not try to make a dog bathe himself during runtime. Which would throw an error.
Yes, you are correct. By having Cat implent "PetInterface" you can use it in the example above and easily add more kinds of pets. If you really need to be Cat-specific you need to access the Cat class.
You can call method batheSelf from talk in Cat.
Generally, you should prefer interfaces to concrete classes. Along those lines, if you can avoid using the new operator (which always requires a concrete type as in your new ArrayList example), even better.
This all has to do with managing dependencies in your code. It's best to depend only on highly abstract things (like interfaces) because they also tend to be very stable (see http://objectmentor.com/resources/articles/stability.pdf). Because they have no code, they only must be changed when the API changes...in other words, when you want that interface to present a different behavior to the world, i.e., a design change.
Classes, on the other hand, change all the time. Code that depends upon a class doesn't care how it does what it does, as long as the inputs and the outputs of the API don't change, callers shouldn't care.
You should strive to nail down the behavior of your classes according to the Open-Closed Principle (see http://objectmentor.com/resources/articles/ocp.pdf), that way existing interfaces need not change even when you add functionality, you can just specify a new subinterface.
The old way of avoiding the new operator was by using the Abstract Factory pattern, but that comes with its own set of problems. Better is to use a tool like Guice that does dependency injection, and prefer constructor injection. Make sure you understand the Dependency Inversion Principle (see http://objectmentor.com/resources/articles/dip.pdf) before you start using dependency injection. I've seen a lot of people inject inappropriate dependencies and then later complain that the tool isn't helping them...it won't make you a great programmer, you still have to use it appropriately.
Example: you are writing a program that helps students learn physics. In this program, students can put a ball in various physical scenarios and watch how it behaves: shoot it out of a cannon off a cliff, put it underwater, in deep space, etc. Question: you want to include something about the heaviness of the ball in the Ball API...should you include a getMass() method or a getWeight() method?
Weight depends upon the environment the ball happens to be in. It might be convenient for callers to be able to call one method and get the weight of the ball wherever it happens to be, but how do you write this method? Each ball instance must constantly keep track of where it is and what the current gravitational constant is. So you should prefer getMass(), because mass is an intrinsic property of the ball and doesn't depend on its environment.
Wait, what if you just use getWeight(Environment) instead? This way, the ball instance can just get its current g out of the environment and proceed...better yet, you can use Guice to inject the Environment in the Ball's constructor! This is the type of misuse I often see, and people end up blaming Guice for not being able to handle dependency injection as seamlessly as they would've hoped.
The problem is not Guice here, it's the Ball API design. Weight is not an intrinsic property of the ball, so it's not a property that should be accessible from the ball. Instead, Ball should implement the MassiveObject interface with a getMass() method, and Environment should have a method called getWeightOf(MassiveObject). Intrinsic to the Environment is its own gravitational constant, so this is much better. And Environment only depends upon a simple interface now, MassiveObject...but it's job is to contain objects, so this is as it should be.
Why not simply do this!
Cat c = new Cat();
PetInterface p = (PetInterface)c;
p.talk();
c.batheSelf();
Now we have a single object, which can be manipulated using 2 references.
The reference p can be used to call functions defined in interface and c can be used to call functions defined in class(or superclass) only.