Usage of Generics in Java [duplicate] - java

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?

Related

Why is a class called an abstraction of an object?

I understand that a class is essentially a blueprint of an object, but the idea that a class is an 'abstraction' of an object is a little hard for me to wrap my head around... If anyone could tell me the real meaning of the statement: "A class is an abstraction of an object", I'd be really grateful.
My confusion is because this statement has been interpreted differently by different people...
Does 'abstraction' mean:
Dealing with the basics of a system, and not the deep intricacies of that system?
or does it mean that:
Only an abstract class can be considered an abstraction of an object?
Thanks in advance,
Abhigyan
A class is a description of everything that will be in a certain type of object. For instance, a car will have a steering wheel, seats, dashboard, etc and functions such as accelerating, stopping etc. Each individual car is a car object, but the conceptual car is analogous to the class.
Dealing with the basics of a system, and not the deep intricacies of that system?
Somewhat, since a class does not usually describe exactly what goes into each field (for instance, the color of the steering wheel)
Only an abstract class can be considered an abstraction of an object?
No, this is more general that the abstract keyword in Java.
Basically, a class is an abstraction because it describes what is created, whereas an object is created itself.
A class can be instantiated into objects. It captures the characteristics that are common to all these objects.
A class defines fields & behavior (methods). It is instantiated into objects, which hold concrete values for those fields.
Abstraction as a term is used at many levels -- most commonly in regard of behavior. However in this regard it is being used of value.
We could state more clearly: A class is an abstraction across the possible values of its instances.
Example in pseudocode:
public class Cat {
String name;
String color;
}
object Cat ("Missy", "grey");
object Cat ("Whiskers", "orange");
object Cat ("Fluffy", "black");
As we see, class abstracts over values of its instances.

How to wrap my head around Object Oriented Design

Object oriented design is a pretty neat concept, but I'm struggling on how to wrap my head around most of its facets. I think the key to a good object oriented design is having a good grasp on how to look at it. I usually look at object-oriented this way:
Classes are Real-world entities or objects
Instance Fields are entity's attributes, ('has A')
Methods are like actions, verbs, Entity's abilities
Interfaces are like abilities that you can imbue on an object. It could also be an 'is A or can do' relationship whose implementations are not set in stone. Superman is a Krypton, being a Kryptonian comes with a set of special abilities, like flying, freeze-breath, etc. Superman fly different from Green Lantern and Goku and especially Batman, that is why Flight as interface is probably a good idea if you're creating a Fictional Universe.
public class SuperMan extends Man implements Kryptonian{}
public interface Kryptonian extends Flight, FreezeBreath{
public void fly();
public void coolBreath();
}
Problem comes along when you add Generics into the mix? Because the given type parameters somehow creates a contract between the class/interface and the type.
public interface Flight<T>{
public void fly(T t);
}
In this example, Flight is coupled with a T, T could be a superhero a bird or anything that can fly.But is that really how I should imagine it? Because that seems like the same as what plain interfaces do? Although, a parameterized interface is still an interface, the coupling with the type T is what really bothers me. Moreover, things also get complicated when you add bounded restriction on the parameter type.
public class Pidgey<T extends Bird> implements Flight<T>{}
what real-world concrete object can you identify T with? The above example is pretty wrong, although using the class parameter to also restrict the type of Flight is probably a good design, because Flight is still independent enough that other classes could still use it without any restriction. But the example itself is wrong. Pidgey is a Bird that can fly, but what what could T be? Well, T could be anything, it could be another object or abilities. The question is what are its implications, why put T there? What are real-world examples of doing so?
It's easy to understand when you talk about collections, since collections are like containers. You can create a wide variety of containers that holds different kinds of objects.
public class WaterBottle<T extends Liquid> implements UniqueCap{}
But I've seen Generics being used not just on a container-like objects? How could one design such objects, what did they consider?
Your analogies to the various features in OOP are definitely valid. Generics definitely make the most sense when talking about collections/containers/Hashmaps. They do have their uses in other places, though. For example, if a bank wants to process notes in many currencies, they can write
public class moneyProcessor
However, generics aren't required. In the context of your Flight interface, there wouldn't be much of a reason to use generics. Which brings me to another point:
Just because someone else does something one way doesn't mean you have to do it that way. OOP is very flexible for a reason. There's always more than one correct way. If a method takes an Object as a parameter, it's not the end of the world. Just make sure you can read it later. :)
Edit: and that others can read it too.
Its convention to use T when dealing with generics. it makes code readable as others reading your code will immediately know you're referring to a generic and nothing specific

Is there an easier way to call a subclass's method on an ArrayList of both the subclass and superclass in Java

I have a class (let's call it Vehicle) and a subclass (Car). Instances of both are stored in one ArrayList. Car has a method that isn't inherited from vehicle, doStuff(). I want to doStuff() to every car in the ArrayList. This is the easiest solution I came up with:
vehicleList = new ArrayList<Vehicle>();
roster.add(new Vehicle());
roster.add(new Car());
for (Vehicle v: vehicleList){
if (v instanceof Car){
((Car) v).doStuff();
}
}
But I feel like there's a much simpler way to do it. So thanks in advance if you can offer a simpler solution.
If your list is declared as List<Vehicle>, then that's the right way to do it - you can't tell without checking if an individual item is a Truck, or a Car, or something else.
If it makes sense for Vehicle to have the method, you could declare doStuff there, and have it do nothing by default, and put a real implementation in Car. This is generally a sign of bad design though.
Another option would be to get a List<Car> instead, so you don't have to check each item in the list for it's type. You could also put doStuff as part of an interface CanDoStuff, so it's not Car you're checking for - this way you can easily apply it to other classes as well.
The "easiest" solution is to implement doStuff() in Vehicle, and have it do nothing. e.g.
public void doStuff(args) { ; }
However, this is typically a hint of poor design. Might be a good idea, might be bad.
There are 2 options:
Add doStuff() to Vehicle (default impl could be "do nothing")
Something along the lines of what you have. Some way of figuring out if a particular Vehicle can "do stuff". You could have a canDoStuff() method in the Vehicle class (still requires a cast and base class is starting to "know too much". You could have Car implement a CanDoStuff interface - works a bit better than using Car directly if you might one day have a Van which can doStuff too.
Store like types together where ever possible. Then you wont have this problem. Ask yourself why you store all Vehicles in one list, if they all behave differently. The end. :)
You can do tricky things such as creating a "filtering iterator" which returns essentially a filtered sublist based on the class type. this is an advanced topic, but if your project has this list methodology quite prominent, you write that filter once and use it all over the place.

When should I use generics to define relationships between types?

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?

Is it possible to unimplement an interface in derived class in Java?

Let's have the following class hierarchy:
public class ParentClass implements SomeInterface {
}
public class ChildClass extends ParentClass {
}
Then let's have these two instances:
ParentClass parent;
ChildClass child;
Then we have the following TRUE statements
(parent instanceof SomeInterface) == true
(child instanceof SomeInterface) == true
Is it possible to unimplement the SomeInterface in the ChildClass, so when we check with the instanceof operator it returns false?
If not possible, is there a workaround?
No it is not possible, and your intent to do so is a good hint that something is flawed in your class hierarchy.
Workaround: change the class hierarchy, eg. like this:
interface SomeInterface {}
abstract class AbstractParentClass {}
class ParentClass extends AbstractParentClass implements SomeInterface {}
class ChildClass extends AbstractParentClass {}
Maybe composition instead of inheritance is what you want, i.e. have a "base class" object as a member and just implement the interfaces you need, forwarding any methods needed to the member.
I agree with other answers that it is not possible in Java.
The other answers further suggest it shows a flaw in your design.
While I agree with them, it is only fair to point out that some prominent OO experts (particularly Bertrand Meyer) disagree with us, and believe such a design should be allowed.
Other OO inheritance models (notably, Meyer's Eiffel programming language) do support the "Change of Availability or Type" (CAT) feature that you are looking for.
It's not possible and doing so would violate the implied IS-A relationship between ChildClass and ParentClass. Why do you want to do this?
I don't think you can "unimplement" it but you could check if it is an instance of the parent class. Is the interface yours? If so you could extend it to include an "IsObjectDerived" method with semantics that it returns true iff the class only derives from object. Since you are writing the class all you would need to do is implement it in the parent and have it return true if the object is of class Parent and false otherwise.
You could also do this with reflection by checking the superclass of the current class and make sure it is object. I'd probably do it this way since then implementing classes can't lie. You may want to look a tutorial on reflection in Java that I found.
[EDIT] In general I agree that this seems unnecessary in a reasonable design, but it can be done.
Since inheritance, the basis of OOP polymorphism, denotes an is-A relationship - your question seems to request a way to redefine "is" relationships to be "is not" relationships.
That won't work.
Go back to some introductory object-oriented texts or online material and study what object-oriented means: polymorphism, encapsulation, and identity.
Strip off identity, and you've got COM/ActiveX and stolen credentials.
Strip off encapsulation and nobody is safe.
Strip off polyphism's type rules and you basically have nothing is necessarily what it says it is.
If you want a situation like that, then program in "C". Don't mess around with pretending to write OOP code using OOP language features. Just use struct to hold your data. Put unions everywhere. Use typecast with abandon.
Your program likely will not work reliably but you will be able to circumvent any restrictions languages like Java and C++ have introduced to make programs more reliable, easier to read, and easier to write/modify.
In a dynamic programming language like SmalTalk or Python, you can essentially rip the wings off a butterfly at runtime. But only by changing/corrupting the type of the object.
Doing so does not buy you anything. There are coding/design techniques and design patterns that let you accomplish any "good" result that you might be after that are similar to this.
It is best if you think of what exactly you are trying to do in your application, and then try to find the safest/simplest way to accomplish that using sound techniques.
I think you should take this problem as a clear indication that your interface and class design is flawed. Even if you could do it in Java (and I don't think you can) you shouldn't.
How about re-factoring ParentClass so you have the SomeInterface implementation separate from that which you want in ChildClass. Maybe you need a common base class for ParentClass and ChildClass.
I fail to see how this would be sound practice, but you could alter a class dynamically using the excellent package Javassist created by Shigeru Chiba et al. Using this, you can add and remove features from classes and then use instances of these classes without saving as classfiles.
Dynamic, interesting and totally confusing for anyone else. Use with care is my advice, but do play around with it as it makes you a better programmer in my opinion.
(I believe ASM works in a similar fashion, but I have not tried it so far. It does seem to be very popular amongs the non-java language creators working on the JVM, so it is probably good.)
Maybe you have a specific case where a better solution could be devised, but for the generic case you need some black magic. Eventually Javassist could be used "hack" your objects but I'm not so sure.

Categories