-1

"Introduction to Java programming", says:

To enable generic programming, it is a good practice to define a variable with a supertype, which can accept a value of any subtype.

Code example:

 Object myObject = new Circle();

... // Some lines of code

System.out.println("The circle diameter is " +
((Circle)myObject) .getDiameter());

... // Some lines of code

Why not define myObject as a Circle type in the first place?

Wololo
  • 841
  • 8
  • 20
  • 3
    Example you provided may be a good practice in a very few cases. For me, it is awful. – Alex Salauyou Aug 19 '15 at 09:08
  • Introduction to Java programming sounds like a horribly bad book, or the OP understood something wrong. – Kayaman Aug 19 '15 at 09:09
  • 2
    In most cases, the simplest and clearest code is best. It is likely that the example they provide is not a good one. – Peter Lawrey Aug 19 '15 at 09:10
  • 1
    if I recall that book is over 10 years old... – nafas Aug 19 '15 at 09:11
  • Please provide an example that makes some sense. In this example, I can't see what difference does defining myObject as Object type, rather than as Cirlce, make? – Wololo Aug 19 '15 at 09:13
  • @Saud The only difference is you need an extra casting to `Circle`. So it provides no advantage at all. (In this example) – Manu Aug 19 '15 at 09:15
  • @Manu . Another example of this practice (making no sense to me): `Set set = new HashSet();` Then he uses this set to store some strings and display them using an iterator. Declaring set as Set rather than HashSet, I think he is simply making the code prone to more errors. – Wololo Aug 19 '15 at 09:21
  • 1
    @Saud That's a different case. `Set` is a well defined interface, and it usually doesn't matter what the actual runtime class being used is. I don't see how it would be prone to errors, unless someone makes assumptions about the concrete class being used (which would be an error on that developer's part). – Kayaman Aug 19 '15 at 09:38
  • @Kayaman agreed. But you do have to be more cautious; like you said, one might erroneously assume Set as a concrete class. – Wololo Aug 19 '15 at 09:47
  • 1
    @Saud No, that's not what I meant at all. Any half-decent Java programmer knows that `Set` is an interface, if not, he shouldn't be touching code at all. My example was about a developer thinking that `Set` is a `HashSet`, when there's no guarantees about it. – Kayaman Aug 19 '15 at 10:01

3 Answers3

2

Lets make a simple Example with a class Fruit

public class Fruit {
   public void eat() {
       //some code
   }
}

And two other classes

public class Banana extends Fruit{

}
//
public class Apple extends Fruit{

}

Now let´s create a Person

public class Person {
    public void eat(Fruit f) {
        f.eat();
    } 
}

Let´s use this now

public static void main(String[] args) {
    Person p = new Person();
    // We are creating a random Fruit, and pass it to the person to eat.
    // We can´t be more specific here and don´t need to be more specific
    Fruit f = getRandomFruit();
    p.eat(f);
}

public static Fruit getRandomFruit() {
    if(new Random().nextInt(2) == 0) {
        return new Banana();
    } else {
        return new Apple();
    }
}
SomeJavaGuy
  • 7,307
  • 2
  • 21
  • 33
1

I think that in this case, this example does more harm than good. To do any Circle or Shape related operations you will need to cast your current object. Other than adding potential overhead, this could lead to issues such as incompatible types.

Doing generic programming is usually recommended since it allows your code to be flexible. Unlike the example you have posted however, it is recommended only when done right. Creating everything as an object will almost always do more harm than good.

Taking the List as an example, if you where to have a method which returns an ArrayList<String> as a result: public ArrayList<String> foo(), then, you are bound to that particular type. If you want a linked list, you will probably need to write some sort of converter which creates a LinkedList<String> from an ArrayList<String>.

On the other hand, if you use the generic interface instead, your method would become something like so: public List<String> foo(). This will allow who ever consumes foo to be able to create any one of the data structures which implement the List interface without the need of going through hoops.

EDIT: As per your comment, most of the time it does not help. As I mentioned in my answer it does more harm than good. One of the instances where working with objects makes sense is the readObject() method provided by the ObjectInputStream. This method is used when you are reading a custom object, which the ObjectInputStream does not know about. Since in Java everything extends the Object class, this method yields an object. Even then, every illustration I have seen of this method they eventually cast it to something else.

npinti
  • 51,780
  • 5
  • 72
  • 96
  • **How does defining myObject as Object type help in generic programming?** Can you please cite a case where doing this actualy makes sense.. – Wololo Aug 19 '15 at 09:23
  • @Saud: As I and others have mentioned, declared something as `Object` does more harm than good. The `List` example provided should yield something which is more practical. I've updated my answer with a situation in which the Java API yields an `Object`, but even then, the object will be eventually cast to something more specific. – npinti Aug 19 '15 at 09:42
1

If you modify the example a little bit, by deriving Circle, Square , RectAngle from Shape instead of Object, it will make good sense. Shape can have methods like getArea() and attributes like height and width, which can be overridden by derived classes.

Shape circle = new Circle();
Shape rectangle = new Rectagle();

In real life examples, it is better to use Base generic types for derived classes so that an implementation can change at run time.

If you are looking for object creation, use simple Factory.

If you are looking to change the behaviour of the object at run time, use Strategy_pattern.

If you are working on multiple strategies for feature, strategy can replaced dynamically by changing base to new derived strategy.

Have a look at below examples:

Design Patterns: Factory vs Factory method vs Abstract Factory

Real World Example of the Strategy Pattern

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211