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
...
}
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 understand what interfaces and abstract classes are, but I don't know how to get the following functionality; if it's possible, that is. I have a bunch of classes which are each going to have a validate() method. Each method may take different parameters. For example, we could have classes with the following methods:
boolean validate();
boolean validate(Block[]);
boolean validate(BlockSet[]);
...
So, basically I want to know if I can use an interface or abstract class, or something else, to define a contract to have a method with a given name and return type implemented, but no restrictions on the set of parameters. Thanks in advance.
You can do this with validate(Object... args), but it's worth questioning whether you really want to. Interfaces and Abstract Classes are useful so that you can group a bunch of similar objects together, and have implementations do different things with the same operation. It seems to me that you wouldn't be able to call this method without knowing what the underlying implementation is, and therefore there is no reason to abstract them.
Try using varargs in an interface:
boolean validate(Object... args) or
'boolean validate(Block... blocks)`
if the Blocks are always a collection, use their supertype:
boolean validate(Collection<Block> blocks)
But then you may need to use some casts. Not best option.
If you want method to take any number pf parameters then you can use Varargs but if you want it to change Type also then its not feasible.
Also what you want to achieve is find a separate way of method overloading, but for that you will have to explicitly specify the methods.
In this post I suggested a solution that uses interface and anonymous class. However, there is one thing to be implemented: the hashCode and equals method.
However I found it is hard to implement equals for anonymous class that implements an interface. In that example the interface is Pair<L,R>, and a factory method Pairs.makePair will return an anonymous implementation for it. Suppose I added an equals implementation. The user may implement their own Pair<L,R> classes with a different equals code, therefore the call userobj.equals(makepairobj) will enter their code, and makepairobj.equals(userobj) will enter my code. Because I have no control of their code, it is hard to make sure equals to be symmetric, which is required for a good implementation.
I believe this problem is common for other cases, so I would like to know how this issue being address generally?
EDIT:
In typical class, the implementation of equals will check the parameter type to make sure it is the same as its own. This guarantee only the implementing code will be called to compare the objects. However, the anonymous class do not have a name and cannot check the type with instanceof. What I can do is make sure it is an instance of the implementing interface/class. Which is not enough to prevent the above scenario.
You can use this.getClass() (with either == or isAssignableFrom()) to compare the types.
Edit
As in:
public boolean equals(Object obj) {
if (getClass() == obj.getClass()) {
// do whatever
}
return false;
}
Usually, when you make an interface like this, it requires the implementing classes to implement equals and hashCode to follow some convention. For example, if you look at the java.util.List interface, it requires lists to be equal iff they have the same length and equal elements in the same order, and it specifies a formula for calculating the hashCode based on the hash codes of the elements.
So then "it is hard to make sure equals to be symmetric" should not be a problem.
The problem you've encountered is a sign that an anonymous class is the wrong way to implement this.
Anonymous classes are a simply a shorthand way of implementing an interface or extending a class. It's purely syntactic sugar, with no extra functionality or other advantage. They were (perhaps mistakenly) intended to make your code simpler and more readable. If an anonymous class complicates your code instead, don't use it.
Many cases that used to be a good fit for anonymous classes are now better served by lambdas. If a class has two or three methods, trying to put it in an anonymous class makes your code hard to read; it should be an inner class anyway.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: Rationale of the Object class not being declared abstract
Why is the Object class, which is base class of 'em all in Java, not abstract?
I've had this question for a really really long time and it is asked here purely out of curiosity, that's all. Nothing in my code or anybody's code is breaking because it is not abstract, but I was wondering why they made it concrete?
Why would anyone want an "instance" (and not its presence a.k.a. Reference) of this Object class? One case is a poor synchronization code which uses the instance of an Object for locking (at least I used it this way once.. my bad).
Is there any practical use of an "instance" of an Object class? And how does its instantiation fit in OOP? What would have happened if they had marked it abstract (of course after providing implementations to its methods)?
Without the designers of java.lang.Object telling us, we have to base our answers on opinion. There's a few questions which can be asked which may help clear it up.
Would any of the methods of Object benefit from being abstract?
It could be argued that some of the methods would benefit from this. Take hashCode() and equals() for instance, there would probably have been a lot less frustration around the complexities of these two if they had both been made abstract. This would require developers to figure out how they should be implementing them, making it more obvious that they should be consistent (see Effective Java). However, I'm more of the opinion that hashCode(), equals() and clone() belong on separate, opt-in abstractions (i.e. interfaces). The other methods, wait(), notify(), finalize(), etc. are sufficiently complicated and/or are native, so it's best they're already implemented, and would not benefit from being abstracted.
So I'd guess the answer would be no, none of the methods of Object would benefit from being abstract.
Would it be a benefit to mark the Object class as abstract?
Assuming all the methods are implemented, the only effect of marking Object abstract is that it cannot be constructed (i.e. new Object() is a compile error). Would this have a benefit? I'm of the opinion that the term "object" is itself abstract (can you find anything around you which can be totally described as "an object"?), so it would fit with the object-oriented paradigm. It is however, on the purist side. It could be argued that forcing developers to pick a name for any concrete subclass, even empty ones, will result in code which better expresses their intent. I think, to be totally correct in terms of the paradigm, Object should be marked abstract, but when it comes down to it, there's no real benefit, it's a matter of design preference (pragmatism vs. purity).
Is the practice of using a plain Object for synchronisation a good enough reason for it to be concrete?
Many of the other answers talk about constructing a plain object to use in the synchronized() operation. While this may have been a common and accepted practice, I don't believe it would be a good enough reason to prevent Object being abstract if the designers wanted it to be. Other answers have mentioned how we would have to declare a single, empty subclass of Object any time we wanted to synchronise on a certain object, but this doesn't stand up - an empty subclass could have been provided in the SDK (java.lang.Lock or whatever), which could be constructed any time we wanted to synchronise. Doing this would have the added benefit of creating a stronger statement of intent.
Are there any other factors which could have been adversely affected by making Object abstract?
There are several areas, separate from a pure design standpoint, which may have influenced the choice. Unfortunately, I do not know enough about them to expand on them. However, it would not suprise me if any of these had an impact on the decision:
Performance
Security
Simplicity of implementation of the JVM
Could there be other reasons?
It's been mentioned that it may be in relation to reflection. However, reflection was introduced after Object was designed. So whether it affects reflection or not is moot - it's not the reason. The same for generics.
There's also the unforgettable point that java.lang.Object was designed by humans: they may have made a mistake, they may not have considered the question. There is no language without flaws, and this may be one of them, but if it is, it's hardly a big one. And I think I can safely say, without lack of ambition, that I'm very unlikely to be involved in designing a key part of such a widely used technology, especially one that's lasted 15(?) years and still going strong, so this shouldn't be considered a criticism.
Having said that, I would have made it abstract ;-p
Summary
Basically, as far as I see it, the answer to both questions "Why is java.lang.Object concrete?" or (if it were so) "Why is java.lang.Object abstract?" is... "Why not?".
Plain instances of java.lang.Object are typically used in locking/syncronization scenarios and that's accepted practice.
Also - what would be the reason for it to be abstract? Because it's not fully functional in its own right as an instance? Could it really do with some abstract members? Don't think so. So the argument for making it abstract in the first place is non-existent. So it isn't.
Take the classic hierarchy of animals, where you have an abstract class Animal, the reasoning to make the Animal class abstract is because an instance of Animal is effectively an 'invalid' -by lack of a better word- animal (even if all its methods provide a base implementation). With Object, that is simply not the case. There is no overwhelming case to make it abstract in the first place.
From everything I've read, it seems that Object does not need to be concrete, and in fact should have been abstract.
Not only is there no need for it to be concrete, but after some more reading I am convinced that Object not being abstract is in conflict with the basic inheritance model - we should not be allowing abstract subclasses of a concrete class, since subclasses should only add functionality.
Clearly this is not the case in Java, where we have abstract subclasses of Object.
I can think of several cases where instances of Object are useful:
Locking and synchronization, like you and other commenters mention. It is probably a code smell, but I have seen Object instances used this way all the time.
As Null Objects, because equals will always return false, except on the instance itself.
In test code, especially when testing collection classes. Sometimes it's easiest to fill a collection or array with dummy objects rather than nulls.
As the base instance for anonymous classes. For example:
Object o = new Object() {...code here...}
I think it probably should have been declared abstract, but once it is done and released it is very hard to undo without causing a lot of pain - see Java Language Spec 13.4.1:
"If a class that was not abstract is changed to be declared abstract, then preexisting binaries that attempt to create new instances of that class will throw either an InstantiationError at link time, or (if a reflective method is used) an InstantiationException at run time; such a change is therefore not recommended for widely distributed classes."
From time to time you need a plain Object that has no state of its own. Although such objects seem useless at first sight, they still have utility since each one has different identity. Tnis is useful in several scenarios, most important of which is locking: You want to coordinate two threads. In Java you do that by using an object that will be used as a lock. The object need not have any state its mere existence is enough for it to become a lock:
class MyThread extends Thread {
private Object lock;
public MyThread(Object l) { lock = l; }
public void run() {
doSomething();
synchronized(lock) {
doSomethingElse();
}
}
}
Object lock = new Object();
new MyThread(lock).start();
new MyThread(lock).start();
In this example we used a lock to prevent the two threads from concurrently executing doSomethingElse()
If Object were abstract and we needed a lock we'd have to subclass it without adding any method nor fields just so that we can instantiate lock.
Coming to think about it, here's a dual question to yours: Suppose Object were abstract, will it define any abstract methods? I guess the answer is No. In such circumstances there is not much value to defining the class as abstract.
I don't understand why most seem to believe that making a fully functional class, which implements all of its methods in a use full way abstract would be a good idea.
I would rather ask why make it abstract? Does it do something it shouldn't? is it missing some functionality it should have? Both those questions can be answered with no, it is a fully working class on its own, making it abstract just leads to people implementing empty classes.
public class UseableObject extends AbstractObject{}
UseableObject inherits from abstract Object and surprise it can be implemented, it does not add any functionality and its only reason to exist is to allow access to the methods exposed by Object.
Also I have to disagree with the use in "poor" synchronisation. Using private Objects to synchronize access is safer than using synchronize(this) and safer as well as easier to use than the Lock classes from java util concurrent.
Seems to me there's a simple question of practicality here. Making a class abstract takes away the programmer's ability to do something, namely, to instantiate it. There is nothing you can do with an abstract class that you cannot do with a concrete class. (Well, you can declare abstract functions in it, but in this case we have no need to have abstract functions.) So by making it concrete, you make it more flexible.
Of course if there was some active harm that was done by making it concrete, that "flexibility" would be a drawback. But I can't think of any active harm done by making Object instantiable. (Is "instantiable" a word? Whatever.) We could debate whether any given use that someone has made of a raw Object instance is a good idea. But even if you could convince me that every use that I have ever seen of a raw Object instance was a bad idea, that still wouldn't prove that there might not be good uses out there. So if it doesn't hurt anything, and it might help, even if we can't think of a way that it would actually help at the moment, why prohibit it?
I think all of the answers so far forget what it was like with Java 1.0. In Java 1.0, you could not make an anonymous class, so if you just wanted an object for some purpose (synchronization or a null placeholder) you would have to go declare a class for that purpose, and then a whole bunch of code would have these extra classes for this purpose. Much more straight forward to just allow direct instantiation of Object.
Sure, if you were designing Java today you might say that everyone should do:
Object NULL_OBJECT = new Object(){};
But that was not an option in 1.0.
I suspect the designers did not know in which way people may use an Object may be used in the future, and therefore didn't want to limit programmers by enforcing them to create an additional class where not necessary, eg for things like mutexes, keys etc.
It also means that it can be instantiated in an array. In the pre-1.5 days, this would allow you to have generic data structures. This could still be true on some platforms (I'm thinking J2ME, but I'm not sure)
Reasons why Object needs to be concrete.
reflection
see Object.getClass()
generic use (pre Java 5)
comparison/output
see Object.toString(), Object.equals(), Object.hashCode(), etc.
syncronization
see Object.wait(), Object.notify(), etc.
Even though a couple of areas have been replaced/deprecated, there was still a need for a concrete parent class to provide these features to every Java class.
The Object class is used in reflection so code can call methods on instances of indeterminate type, i.e. 'Object.class.getDeclaredMethods()'. If Object were to be Abstract then code that wanted to participate would have to implement all abstract methods before client code could use reflection on them.
According to Sun, An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed. This also means you can't call methods or access public fields of an abstract class.
Example of an abstract root class:
abstract public class AbstractBaseClass
{
public Class clazz;
public AbstractBaseClass(Class clazz)
{
super();
this.clazz = clazz;
}
}
A child of our AbstractBaseClass:
public class ReflectedClass extends AbstractBaseClass
{
public ReflectedClass()
{
super(this);
}
public static void main(String[] args)
{
ReflectedClass me = new ReflectedClass();
}
}
This will not compile because it's invalid to reference 'this' in a constructor unless its to call another constructor in the same class. I can get it to compile if I change it to:
public ReflectedClass()
{
super(ReflectedClass.class);
}
but that only works because ReflectedClass has a parent ("Object") which is 1) concrete and 2) has a field to store the type for its children.
A example more typical of reflection would be in a non-static member function:
public void foo()
{
Class localClass = AbstractBaseClass.clazz;
}
This fails unless you change the field 'clazz' to be static. For the class field of Object this wouldn't work because it is supposed to be instance specific. It would make no sense for Object to have a static class field.
Now, I did try the following change and it works but is a bit misleading. It still requires the base class to be extended to work.
public void genericPrint(AbstractBaseClass c)
{
Class localClass = c.clazz;
System.out.println("Class is: " + localClass);
}
public static void main(String[] args)
{
ReflectedClass me = new ReflectedClass();
ReflectedClass meTwo = new ReflectedClass();
me.genericPrint(meTwo);
}
Pre-Java5 generics (like with arrays) would have been impossible
Object[] array = new Object[100];
array[0] = me;
array[1] = meTwo;
Instances need to be constructed to serve as placeholders until the actual objects are received.
I suspect the short answer is that the collection classes lost type information in the days before Java generics. If a collection is not generic, then it must return a concrete Object (and be downcast at runtime to whatever type it was previously).
Since making a concrete class into an abstract class would break binary compatibility (as noted upthread), the concrete Object class was kept. I would like to point out that in no case was it created for the sole purpose of sychronization; dummy classes work just as well.
The design flaw is not including generics from the beginning. A lot of design criticism is aimed at that decision and its consequences. [oh, and the array subtyping rule.]
Its not abstract because whenever we create a new class it extends Object class then if it was abstract you need to implement all the methods of Object class which is overhead... There are already methods implemented in that class...