sfabriece
sfabriece

Reputation: 121

Why should I use general classes instead of specific classes

I recently read that I should use general classes instead of specific classes when proramming. I can't figure out why it is suggested.

example: Let's say that we have a class MyPanel that inherits from JPanel. MyPanel a non-inherited method called getLastChild.

instead of:

MyPanel panel = new MyPanel():
Component last = panel.getLastChild();

it is suggested to do this:

JPanel panel = new MyPanel();
Component last = ((MyPanel)panel).getLastChild();

I don't see why I should choose the second one.

Upvotes: 1

Views: 173

Answers (4)

Adam Stelmaszczyk
Adam Stelmaszczyk

Reputation: 19847

A good example would be:

List<Integer> list = new ArrayList<Integer>;

instead of

ArrayList<Integer> list = new ArrayList<Integer>;

Why?

tl;dr It gives you more flexibility and generalizes your code for free.

Explanation

Whenever you want to pass a list you will use List instead of ArrayList. For example you have a method:

public void doSomething(List<Integer> list)

Later you can change your implementation easily if you realize that for example LinkedList is a better choice.

Upvotes: 0

AlexR
AlexR

Reputation: 115388

You can now develop utility method that operates with JPanels. Let's call it foo(JPanel p).

Now you can use it with any JPanel including MyPanel. But why? You can define the method as following: foo(MyPanel p) and use it with MyPanel until you develop second panel that it called OtherPanel. You cannot send this OtherPanel to foo() that operates with MyPanel only.

However the first (general) version of foo() can be used for both and for any other class that extends JPanel and developed by you, by me or by any other programmer.

I hope that this simple example is enough to understand the need of generalization.

Upvotes: -1

Mureinik
Mureinik

Reputation: 312086

You are correct, this example indeed makes no sense.

The general rule of thumb is that you should use the most general class that still has the appropriate functionality. This way, you allow yourself the freedom to change the concrete class you're using and have the rest of the program continue working. For example, consider the JDK's Collections.sort(List). The same method call can be used with an ArrayList, a LinkedList, or any other List - it does not care about the specifics of how that list is implemented, just about the fact that it's a list.

Your example, however, is different. If you need to call MyPanel.getLastChild(), you most certainly care about having a MyPanel - you can't just use any other JPanel. Since you already have this dependency, it makes no sense declaring your variable as a JPanel and downcasting it just to call getLastChild().

Upvotes: 4

Joshua Zollinger
Joshua Zollinger

Reputation: 757

That second one brings greater flexibility. If you declare panel to be of type MyPanel, then it can ONLY be MyPanel (or classes that inherit from MyPanel), whereas if you declare panel as type JPanel, it can be a generic JPanel OR any subclass of JPanel (including MyPanel). This makes your code more portable and easier to edit down the road. Your component might only be a MyPanel now, but what if that changes later?

Upvotes: -1

Related Questions