Can I create a object array to hold different objects in Java? - java

Is it possible to do something like this in Java?
Object[] objArray = { new Car(), new Human() }
I read that the array elements all have to be the same type but aren't these all of type Object ?

Yes, it's possible but not useful often and always dangerous.
If you want to put some objects into a collection (list or array), the type of the collection must allow for a common ancestor. Since Object is the common ancestor to all OO types in Java, you can put anything into it (and, with Java 6's autoboxing, even primitives).
The problems start when you work with the elements in the list. As long as you only need to call methods which the common ancestor type provides, everything is fine.
But eventually, you will want to call methods of the Car type and that means you'll have to identify the instances in the collection (which is somewhat slow and pretty clumsy in the code) and use casts (always a good sign for bad code).

You're correct, that works perfectly okay even though it's not considered to be good OO practice.

Inheritance is used to define a is-a relationship. Since every class in Java extends java.lang.Object (either directly or indirectly), a Car instance is-a Object instance, and a Human instance is-a Object instance.
So, of course, an array of objects can hold humans, cars, and every other kind of object.

Yes, it's possible to do something like that but its not very OO-like.
Make sure you do an explicit cast when accessing your objects, e.g.
Human h = (Human) objArray[1337];
Have Fun!

Yes, it is possible! Since Object is the upper class of all classes

Related

Usage of Generics in Java [duplicate]

Getting into a little bit of confusion here when to use generics. I've looked at Java Generics? but still have a few questions.
Say I have:
public class Honda implements ICar(){
}
public class Opel implements ICar(){
}
Should I use:
public class Person{
ICar car;
.
.
public Person (ICar c){
car = c;
}
}
or
public class Person<T extends ICar>{
T car;
.
.
public Person(T c){
car = c;
}
}
or does it depend on the tasks performed?
Are generics only for aggregation relationships (containers etc); that is, are they just used for collections?
A person is generally not parameterized with a type of car. Only very annoying persons are defined by their car. Persons change cars too (in time). So I would not parameterize the class, if only for the semantics.
Think about what you try to mimic from the real world, before going into such programming details.
The distinction isn't always clearcut but here are a few clues:
Try to think of them as "type parameters" (Which they are.) They are associated with the class but they're not necessarily related to it. (Look at the collections framework for example.)
Type parameters can only be used if they don't change throughout an object's lifetime. This sounds quite obvious, but it's a very handy rule to decide when NOT to use generics. (Example is a person who can change cars.)
On the other hand, if not many instances will use the type parameter, if it's too optional, that's not a good idea either. (A lot of people might not have cars at all.)
And finally, a general thought that I found really useful: if you're unsure, don't be afraid to prototype it. Write the code both ways and check which one looks simpler and easier to comprehend. Show it to someone else without any explanations or maybe wait a day or two and then re-read the code yourself. Then throw the other one away. Throwing away code is good.
You need the generics version if you have any methods that take or return anything involving a T, or if it's possible for other people to access your car field. (Since you didn't show any methods, we can't really tell.)
For example, with the generics version you can have a method like T someMethod();, then when someone has a Person<Honda>, they know they can get a Honda back when they call someMethod, rather than some unknown type of car if you didn't have generics.
Similarly, with the generics version you can have a method like void anotherMethod(T anotherCar);, then when someone has a Person<Honda>, this forces them to pass a Honda to this method, instead of any car.
So basically, having a generic class allows you to place constraints on uses of the object later on (method calls etc.). If the constructor is the only place that you use T, and you don't need to use T in any methods or fields, then yes, there is no point for it.
This has to do with using Inheritance versus Composition.
Without knowing any other semantics, Composition seems more relevant. A person may change cars, without becoming a different person.
http://www.artima.com/objectsandjava/webuscript/CompoInherit1.html
http://en.wikipedia.org/wiki/Composition_over_inheritance
I'd tend to favor composition (what you're calling dynamic binding), especially in the case you use. A person is not a type of ICar, so using the generics here is kind of weird (to me anyway). I'd use generics as a way of saying "A container for ICar", as in Garage although in that case I might just use a collection type as a variable, or extend the collection type if really needed.
I'd suggest to focus on semantics first:
Providing that you may have a Bmw and a Toyota classes implementing the ICar interface, then make this question: can a Person change his car or would it be a different person if he does so?
The generics approach will force you to create a new Person instance if for some reason you need to change the value of the car attribute from Toyota to Bmw in an existent person instance and thus, this new person will be different from the previous one. Of course, you could create the first Person instance as Person<ICar> instead of hooking it to a specific car class but, why use generics then?

Java - Collection of abstract class, children contain disparate objects - Any "good" way to handle these wrapped objects?

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.

Prefered way to reference super classes (typed languages)

This problem comes up quite a bit actually. Take this instance model view. I have 2 objects. Simulation object and render object.
The class ObjectRSim (Object, designated as Render Sim) is something like:
class ObjectRSsim {
var simObject:ObjectSim;
}
ObjectRSim, uses properties/invalidation of ObjectSim.
There are objects that inherit ObjectRSim and ObjectSim:
PosObjectRSim and PosObjectSim (positional objects..)
class PosObjectRSim extends ObjectRSim {
var posSimObject:PosObjectSim;
}
or...
class ObjectRSim {
var simObject:Dynamic; //Dynamic is untyped Type from haxe, the compiler does not check calls to a Dynamic object.
}
Should I have a reference to each type in the inheritance hierarchy of ObjectSim in the ObjectRSim hierarchy classes, or should I just use simObject:Dynamic?
It will be totally wrong to use Dynamic for that case. It's frequently slow(for every haxe target except javascript I guess), not inlined, and is normally used only for interacting with underlying platform or working with serialization(YAML, JSON etc.).
Talking about solving the problem...
If there aren't thousands of this objects planned, I'd probably just another field for lower-level class object. It's not the clearest way from OOP perspective, but it frequently results in simpler and clearer code for me.
Casting is another option(I personally don't like).
Parameterization would probably be the best way to handle that, but I'm not sure if we already have type restricted parameterization in haxe.
Parameterize the dependent class and the dependency member.

What is the difference in these two declarations?

List<String> someName = new ArrayList<String>();
ArrayList<String> someName = new ArrayList<String>();
Does it impact anything on performance?
The first one is a List of Objects and the latter one is ArrayList of Objects. Correct me if i am wrong. I got confused because ArrayList implements List Interface.
Why do people declare like this? Does it help in any situtions.
When i am receiving some email address from DB, what is the best way to collect it? List of eMail address Objects????
Finally one unrelated question.... can an interface have two method names with same name and signature and same name with different signature.
The difference between the declarations is more one of style. It is preferable to declare variables using the abstract, rather than the concrete implementation, because you can change the implementation choice later without changing the variable type. For example, you might change the List to use a LinkedList instead.
If you always use the abstract type (interface or abstract class) wherever you can, especially in method signatures, the client code is free to use whatever implementation they prefer. This makes the code more flexible and easier to maintain.
This is true even of variable declarations. Consider this:
public abstract class MyListUsingClass {
private List<String> list;
protected MyListUsingClass(List<String> list) {
this.list = list;
}
...
}
If the variable list was declared as ArrayList, then only ArrayLists would be accepted in the constructor. This would be a poor choice: Always try to let the client code chose the implementations they want to use.
Regarding you last question: Interfaces have the same restrictions for methods as classes do, so yes you can overload methods.
There is no performance impact, because in runtime you are dealing with the same class (ArrayList) in both cases.
They are both lists of Strings. The difference is that the first one is declared as a List but initialized as an ArrayList, which is a more specific type of List.
One instance where it helps is when you use an IDE with context-sensitive suggestions (Eclipse, NetBeans, etc). In the first case, whenever you use the suggestion feature, you will only see the members of the List interface. In the second, you will see all (public) members of ArrayList. In any given programming situation, as long as the more abstract type provides the functionality you need, you want to use that because it makes your code more robust: the more abstract a type is, the less likely it is to change in some future release of the API.
The best way to represent anything always depends on what you intend to use the data for and how much of it there is. Probably a List or a Set of javax.mail.internet.InternetAddress will fit the bill.
An interface can have two methods with the same name only if they have different parameter type signatures. Two methods which both take a single string cannot have the same name even if the parameters have different names, nor can you have two methods with the same name which differ only in return type.
In the first cause you're declaring a var of type list and using an ArrayList as its implementation.
In the second case you're declaring and defining an array list.
The difference is that, using the interface type (as in the first case), you will access only those methods defined in the List interface, and if ArrayList has some specific implementation methods, in order to access them you will need to cast your list to its sub-type (ArrayList).
In the second case, you're using a more specific type, so no cast is needed at all.
Performance - probably not.
Actually they are lists of Strings, not objects. Interfaces is not the point of what is held in Collection
Defining variable of superclass type could be usefull if you would like to make your code independent of concrete list implementation. If someday you would like to change list to LinkedList implementation - this won't be so harmful to all your code
Create new type EMail and store them into some kind of list (e.g. mentioned LinkedList or ArrayList) or just array (EMail[]). If you provide more information - this could be helpful.
edit
2. In both cases they are ArrayList of Strings. The difference is, that in first case you're doing casting to the superclass (losing access to some methods specific to ArrayList)
Does it impact anything on performance? No measurable impact. Your code will be the source of your performance issues, not nano-optimizations like this.
The first one ie s a List of Objects and the latter one is ArrayList of Objects. Correct me if i am wrong. I got confused because ArrayList implements List Interface. Exactly. You can assign a class reference to any of the types that it implements.
Why do people declare like this? Does it help in any situations.The reason you might want to is in case you want to change your implementation to use another concrete class that implements List e.g. LinkedList.
When i am receiving some email address from DB, what is the best way to collect it? List of eMail address Objects? Define "best". Depends on how you'll use them. Strings might be sufficient; perhaps a better abstraction would work for you.
Finally one un related question.... can an interface have two method names with same name and signature and same name with different signature. Interfaces define signatures, not implementation. You can have two interfaces with methods that define the same signature, but there can only be one implementation when you execute. If you have a Cowboy and Artist interfaces, both with void draw() methods, the class that implements both will have to decide what the single implementation will be. There can't be one for Cowboy and another for Artist, because interfaces don't have any notion of implementation.

What's the difference between these two java variable declarations?

public class SomeClass {
private HashSet<SomeObject> contents = new HashSet<SomeObject>();
private Set<SomeObject> contents2 = new HashSet<SomeObject>();
}
What's the difference? In the end they are both a HashSet isn't it? The second one looks just wrong to me, but I have seen it frequently used, accepted and working.
Set is an interface, and HashSet is a class that implements the Set interface.
Declaring the variable as type HashSet means that no other implementation of Set may be used. You may want this if you need specific functionality of HashSet.
If you do not need any specific functionality from HashSet, it is better to declare the variable as type Set. This leaves the exact implementation open to change later. You may find that for the data you are using, a different implementation works better. By using the interface, you can make this change later if needed.
You can see more details here: When should I use an interface in java?
Set is a collection interface that HashSet implements.
The second option is usually the ideal choice as it's more generic.
Since the HashSet class implements the Set interface, its legal to assign a HashSet to a Set variable. You could not go the other way however (assign a Set to a more specific HashSet variable).
Set is an interface that HashSet implements, so if you do this:
Set<E> mySet = new HashSet<E>();
You will still have access to the functionality of HashSet, but you also have the flexibility to replace the concrete instance with an instance of another Set class in the future, such as LinkedHashSet or TreeSet, or another implementation.
The first method uses a concrete class, allowing you to replace the class with an instance of itself or a subclass, but with less flexibility. For example, TreeSet could not be used if your variable type was HashSet.
This is Item 52 from Joshua Bloch's Effective Java, 2nd Edition.
Refer to Objects by their interfaces
... You should favor the use of interfaces rather than classes to refer to objects. If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types. The only time you really need to refer to an object's class is when you're creating it with a constructor...
// Usually Good - uses interface as type
List<T> tlist = new Vector<T>();
// Typically Bad - uses concrete class as type!
Vector<T> vec = new Vector<T>();
This practice does carry some caveats - if the implementation you want has special behavior not guaranteed by the generic interface, then you have to document your requirements accordingly.
For example, Vector<T> is synchronized, whereas ArrayList<T> (also an implementer of List<T>) does not, so if you required synchronized containers in your design (or not), you would need to document that.
One thing worth to mention, is that interface vs. concrete class rule is most important for types exposed in API, eg. method parameter or return type. For private fields and variables it only ensures you aren't using any methods from concrete implementation (i.e. HashSet), but then it's private, so doesn't really matter.
Another thing is that adding another type reference will slightly increase size of your compiled class. Most people won't care, but these things adds up.

Categories