Please help me to decide which approach is reasonable in the following case. Object:
public class FunctionCall {
private String functionName;
private List<Exp> args;
...
}
In one very particular case/check the object need to be identified somehow.
Possible approaches:
FunctionCall class becomes an attribute, but there is a doubt that this would pollute overall semantics, as the attribute should not be visible "globally".
SpecialFunctionCall inherits the FunctionCall and with instanceof can be identified in the very special case. This would be ideal, the only doubt that it would misuse purpose of inheritance?
Any other suggestions are very welcome.
Thanks in advance.
From what you wrote, it seems that the FunctionCall object is just a value object with data, not some object that evaluates itself and returns value. With multiple types of such objects, you need to have a way to disambiguate what type of object you are using.
For that part, I can advise you using enums to disambiguate rather than using instanceof operator or class reflections. You can create nice switch-case commands with it, too.
public class FunctionCall {
// ...
public MyType getType() {
return MyType.BASIC_FUNCTION_CALL;
}
}
Another nice thing about enums is, it is a class that can have its own fields. Have some final fields for the enum constants, put in values that describe some trait of it, and you can use this information in the logic that handles it, to your advantage.
As for the actual answer to your question though, it's not quite possible from knowing so little about your problem. In some cases, inheritance is better, in some other cases, composition is better. In both cases, some kind of interface is nice, and it could declare the getType method.
What you actually need is to use two of the main three principles of Java,polymorphism and 'inheritance' combined together. Polymorphism is one of the OOPs feature that allows us to perform a single action in different ways. This means that the behavior of an object could be changed depending on particular circumstances or cases.
In your case you could create two classes, a FunctionCall and a SpecialFunctionCall. Latter should extends the first one with its one spexial behavior.
Then when your special case comes up you would use the second class which would have a different behavior than the first.
By this way you guarantee that there is a per-case functionality of the parent class FunctionCall.
See below an example of use:
public class SpecialFunctionCall extends FunctionCall{
//your special logic goes here
...
}
Related
I've got a task to do polymorphism but I am not entirely sure I understand the concept as per testimony of my teacher.
According to web definitions and examples, this by all means is polymorphism, but they say it is not. Can I please get confirmation?
OversizedParcel.java
public class OversizedParcel implements ParcelType {
public void resolve(PrivateUser user) {
//do theese
//and those
}
public void resolve(LegalUser user) {
//do different thing
//and a completely different thing
}
}
IllegalParcel.java
public class IllegalParcel implements ParcelType {
public void resolve(PrivateUser user) {
//do this
//do that
}
public void resolve(LegalUser user) {
//do a thing
//do a different thing
}
}
(hypothetical class)
public class Main{
private User user; //loaded user
private List<ParcelType> parcels; //assume this contains the loaded parcels already
public static void main(String[] args){
for(ParcelType type : parcels) type.resolve(user);
}
}
Polymorphism can be defined as -
it is the ability of an object to take on many forms
. The most common example of polymorphism could be-
when a parent class reference is used to refer to a child class
object.
So as per your question, in most simplistic way polymorphism can be defined as
ParcelType oversizedparcel = new oversizedParcel();
ParcelType illegalparcel = new illegalParcel();
Here ParcelType can be a oversizedParcel or illegalparcel
So if your understanding is as per my answer, then indeed it is an example of polymorphism.
I'd like to offer a dissenting opinion from what appears to be majority here. Keep in mind that "Polymorphism" is a fairly flexible term, and that what is written here does not necessitate 100% universal truth. This is simply something to aid the balance of thought.
No, what you have written is not polymorphism. This is due to the fact that they instantiate different unrelated objects that simply implement the same interface.
Traditionally, Polymorphism occurs when you have a child object that overrides a parent object's implementation of a method. Hence, there is "multiple forms" of a method that exist at the same time at different levels of the object's vertical hierarchy.
However, interfaces are merely an agreed-upon contract of inputs and outputs that standardize interactions. They don't by themselves hold an instance of the code (we shall exclude default interface methods for the sake of this conversation). Because of this, there is no "Re-definition" of the interface within an object. the same object tree does not instantiate multiple versions of the interface (unless it is through the traditional view of polymorphism).
Even if a method required two arguments of interface ParcelType, it does not necessarily mean polymorphism, it simply means that the method is asking for two 'boxes' of a particular shape and size. These boxes are empty until they are passed into the method as two distinctly different objects that are referenced separately (And not the same method object being overridden by a child object, for example)
Different objects can take advantage of the interface contract, and in a way you can say that it is "Horizontal Polymorphism", but I think this is taking away from the intention of what polymorphism means in the context of Java.
According to the W3School definition, it is indeed polymorphism. Anyway, if your teachers said it is not, they may have been expecting you to do something else.
Polymorphism is, to go further than just an example, an entire concept meaning that you can do entirely different things by using "the same things", or more exactly "things named the same".
Have a look on the Wikipedia definition, which is more complete than any language-specific one, to have a wider view on it.
Polymorphism is having the same thing in different forms. So, Yes this is polymorphism.
I assume that resolve is defined in ParcelType interface. Then the type.resolve calls in for(ParcelType type : parcels) type.resolve(user) are dispatched polymorphically on ParcelType
I have the following interface:
public enum AggregatorType{
DATA_BASE,
GLOBAL_CACHE,
//etc
}
public interface DataAggregator<T>{
public AggregatorType getType();
public Collection<T> getData();
}
My question is about putting different types in the same enumeration. To me, it smells like not a good thing at least (because two separate type put in the same place). But I can't see what potential problems it can lead to. Couldn't you help me understand?
Typically using enum types is not a good practice to explicitly define the type of a class because in some other part of your code you want must have a control structure (if-else/switch-case) on this type to separate the way of aggregation.
If I were you I would put an aggregate method in this interface and I would let the Polymorphism mechanism do the magic for me. DataBaseAggregator and CacheAggregator can be to implementation of this interface to define different behaviors in the aggregation of those data.
Let's say we have something like this:
public abstract class MyClass {
//Stuff in here
}
public class MyClassA extends MyClass {
private String thingie; //Along with getter/setters, of course
//Other stuff
}
public class MyClassB extends MyClass {
private List<Integer> thingies; //Again, getters and setters to go with
//Other stuff
}
Let's assume we have any number of classes that extend MyClass, each with it's own instance variable of a different type, although some may have the same type. This is an unfortunate necessity. Now, let's assume we have a Collection of MyClass. We have a collection filled with any number of child classes, each with an object contained within. Let's say I need to iterate over this Collection, retrieve said object from any number of elements, and perform actions upon it, store it, manipulate it, send it elsewhere, etc. These objects have nothing in common aside from extending Object.
I might be able to simply delegate these actions into the MyClass children themselves, use a visitor, etc, but this likely isn't feasible as these actions may be dependent upon other MyClass children in the Collection. A single MyClass child likely won't dictate the action to be taken all by itself, or even any single Collection of MyClass. Some of these actions may be cumulative and dependent upon a number of other potential cumulative factors.
Is there any "good" way to handle this, or am I just going to be cursed to the hell of ugly typechecking conditionals or something similar? I considered using Generics in MyClass and using concrete types on all of the children. This could simplify the retrieval of objects, but would still necessitate a large conditional block.
You discarded in your question the "good" way of doing it. Generics will not help in this case. Yes, you are going to be cursed to a nasty place for the ugly use of type checking. You can disguise the type checking using a common instance member called, say, category and its corresponding accessor getCategory defined in MyClass. And them do a switch if you can (instead of multiple ifs) on getCategory(). However, the people who will condemn you could dislike ifs and switches no matter if they are checking for types or not. And they could also be smart and understand what you are trying to do. Anything but
for(MyClass e: collection )
e.doYourAction();
is "bad".
Now, for software that seems to have no specification at all, you could be pardoned.
The subject says it already:
I am thinking right now about following design-problem: I define an interface for a specific type of object that contains various methods.
Now i have the problem, that different implementations of this interface, need additional/different method-parameters (because the way they are implemented makes this necessary), which i cannot incorporate into the interface because they are not common to all interface-implementations.
Now i realize that interface implementations could come with their own property-files, loading their additional parameters from there, but what if these parameters need to be passed in at runtime?
Currently i can only think of passing in a Map<String, Object> parameters to overcome this problem - since JDK-Classes like DocumentBuilderFactory are doing something very similar by providing methods like setAttribute(String attName, Object attValue) this
seems like a feasible approach to solve this problem.
Nevertheless i would be interested in how others solve issues like this, alternative ideas?
I dont want to derive from the interface and add additional methods, since in my case i would then have to throw NotImplementException from the methods of the base interface.
UPDATE:
What could be eventual problems of the Map-approach? Implementing classes are free to ignore it completely if they cant make use of additional parameters.
Others might check if the Map contains the desired parameter-names, check the type of their values and use them if valid, throw an exception if not.
I have also seen this being used for the abstract class JAXBContext, so it seems to be a common approach..
UPDATE:
I decided to go for the map-approach, since i dont see any obvious disadvantages and it is being used in the JDK as well (yes, i know this does not necessarily mean much :)
Since i cannot accept an answer on this question, i will just upvote. Thanks for your input!
regards,
--qu
You should just initialize each inheritor with its own specific required parameters and let the interface method remain parameter-less, as in:
Interface Runnable:
public interface Runnable {
public abstract void run();
}
Implementation:
public class MyRunnable {
private final String myConcreteString;
public MyRunnable(String myConcreteString) {
this.myConcreteString = myConcreteString;
}
public void run() {
// do something with myConcreteString
}
}
The point of the interfaces is to have something that is common to all implementations. By trying to do this you destroy the whole reason why interfaces exists.
If you absolutely must do that there is a simple enough way that I have used before.
My answer is in C++ because I'm just not that fluent in other languages. I'm sure there are ways to implement this in java as well.
SomeMethod(void* parameterData);
void* parameterData is a pointer to a struct containing your data. In each implementation you know what you are receiving. You can even have a enum to tell you what kind of data you are receiving.
SSomeData* data = (SSomeData)parameterData
EDIT:
Another approach would be to create a new interface for the parameters: IParameterData.
Inside that interface you have 2 methods: GetParameter(name) and SetParameter(name).
For each implementation of your primary interface you create a implementation of IParameterData.
I hope it helps
couldn't you design subinterfaces that extend your (super)interface?
anyhow I see a design problem if you need a method with different parameters depending on the implementation!
edit: code to clarify
interface CommonBehaviour
{
void methodA(int aParam);
}
interface SpecificBehaviour extends CommonBehaviour
{
void methodB(int aParam, int anotherParam);
}
class SpecificBehaviourImpl implements SpecificBehaviour
{
void methodA(int aParam)
{
//do something common
}
void methodB(int aParam, int anotherParam)
{
//do something specific
}
}
CommonBehaviour myObj = new SpecificBehaviourImpl();
EDIT: You may benefit from the Command pattern:
"Using command objects makes it easier to construct general components that need to delegate, sequence or execute method calls at a time of their choosing without the need to know the owner of the method or the method parameters."
(source: wikipedia)
I don't think the Map approach to be any good, I may accept it as a fix of existing code that would allow you to have any parameter number and type, but without formal checks! You're trying to define a common behavior (interface methods) given a variable, runtime, state.
You should introduce parameter object representing a super-set of possible arguments.
In your place, I would consider finding appropriate design pattern to your problem, rather then try to bend the interface methods to suit your needs. Look into Strategy Pattern for starters.
Can you invert the problem, and implement an interface on the user of these objects which they can query for the additional parameters?
So, when you instantiate these objects implementing the common interface, you also pass in (e.g. to their constructor) an object which provides a way of accessing the additional parameters they might require.
Say your interface has a method 'doSomething' taking parameter 'a', but you have an implementation that needs to know what 'b' is inside this 'doSomething' method. It would call 'getB' on the object you provided to it's constructor to get this information.
I have a basic question in Java, but it's a general question in OOP. Why do interfaces allow fields to be set? Doesn't that run contrary to what an interface is supposed to do?
The way I made sense of it, an interface is what in English would be an adjective. So, if my class implements the interfaces Runnable and Serializable, I'm ensuring the user that my class will satisfy the conditions to be Runnable and Seriablizable. However, that would mean interfaces are "stateless", but they are allowed to have fields in Java...
Am I missing something?
All fields in interface are public static final, i.e. they are constants.
It is generally recommended to avoid such interfaces, but sometimes you can find an interface that has no methods and is used only to contain list of constant values.
First of all, there's difference between OOP paradigm and OOP implementation in Java, so same words may mean a bit different things.
In OOP the paradigm interface is what you can do with the object (or what object can do for you). Any object can have several interfaces and thus play different roles. For example, someone may work as a programmer and be able to create programs, but at the same time he may be a husband and father and thus be able to pay the bills for his family and take care of children. Here "programmer", "husband" and "father" are interfaces, and a person is an object that implements them. Note, that interfaces do not imply presence of any specific features (fields) for implementing object, just actions that this object should be able to perform.
Java more or less follows this idea, but as any paradigm implementation has its own features. Java allows describing methods, that is actions that the implementing object should be able to perform, but not any implementation details, thus, nothing about object fields or private methods.
But what about constants (public final static fields)? Are they part of implementation or interface. It could be both. E.g. interface "programmer" can have constant WORK_HOURS set to "8". Thus Java allows you to describe constants in interfaces too.
Note, that Java only helps you to make good OOP design, but it doesn't strongly require it. In particular, not all public methods of an object should exist in interface too. For example, getter and setter methods are normally public, but in fact they are the part of implementation, not interface, and thus it's worth not to bring them into interface.
(Please also note, that most things I described here are about mainstream OOP like in Java, but there are also other kinds of OOP such as prototype-based one, in particular implemented in JavaScript).
What if that interface refers to constants? Wouldn't it be natural to declare them in the interface?
interface IdFinder {
Serializable UNSAVED = new Serializable() {};
/** #returns the given entity's persistent identity,
or {#link UNSAVED} if it hasn't been saved yet,
or null if o is a value object that hasn't a
persistent identity of its own.
*/
Serializable getId(Object o);
}
Yes, you can have constant fields in interfaces, but you are right when you say that "it seems contrary to what an interface is supposed to do", as it is not a good practice. Why would you want to have all your classes that implement an interface with the same constants? You could simply have them in the class that uses them, or if you really need to export them somehow, have them in a separate class utiliy like this:
public class Constants {
private Constants() { }
public static final int ZERO = 0;
public static final int SOME_COMPLEX_NUM = 2124132L;
...
}
You also have enums, if you need to represent a set of constant fields with some meaning. I do not see any "use case" where you would actually need constants in an interface. But could be wrong :)