Link to home
Start Free TrialLog in
Avatar of pvinodp
pvinodp

asked on

A design question on java code

I am at present re-factoring a off-the-shelf code.. And I have a following scenario in a package.

interface A
Abstract class B implements A
class C extends B
class D extends B implements A

Why would someone define this kind of hierarchy?
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

"Interface Ia":

interface Ia {

public int doubler();

}

Open in new window


"abstract Class Bc" :

abstract class Bc implements Ia{


public int doubler(){

return (101);

}


  public int halver(){

         return(55);

  }

  public void myMethod(){}

   

Open in new window


"Class Cc":

class Cc extends Bc{

public static void main(String[] args){Bc b = new Cc();System.out.println(b.doubler());}


}

Open in new window


"Class Dc":

class Dc extends Bc implements Ia{

public int doubler(){

return(super.doubler());

}

public static void main(String[] args){Dc d = new Dc();System.out.println(d.doubler());System.out.println(d.halver());}

}

Open in new window

Avatar of pvinodp
pvinodp

ASKER

abstract class Bc  has non-implemented methods too.
what is the purpose here?
How does the interface user [Ia] going to use this in different ways?
What design pattern is this?
Class Dc doesn't need to implement the interface, as it already inherits.

The method in bC is just there illustratively. It doesn't have to be used.

My suite merely shows the interdependencies. It depends on the overall aim of the programme you have as to what these interrelationships mean.
Avatar of pvinodp

ASKER

can u illustrate a advantage of this design.. i am trying to understand ..
Inheritors of an abstract class do not need to implement all the methods defined in an interface that the abstract class implements.

Classes C and D in your scenario are identical, as previously mentioned.

An abstract class can provide methods which are fully implemented, so if your child class requires some complicated method, you can be given access to it already via the abstract class.

Using an interface provides looser coupling. Combining that in an abstract class adds a degree of pre-implementation that the overall architecture evidently thinks you need.

(
Classes C and D in your scenario are identical, as previously mentioned.

. . . providing you do not need D to render a different implementation of course).
I'll add my 2c to this question. This type of hierarchy is fairly common, so I am not 100% sure what part of it that you in particular have issue with but I'll give you comments on 2 parts of it.

Firstly, if you are just wondering about class D saying that it "implements A" where as class C doesn't, that is just a matter of what the coder felt like typing at that time. Technically, they BOTH "implement A" as they both extend B which subsequently implements A. However, you CAN state this "implements A" on a subclass or you can leave it, it doesn't matter to Java because they both implement it anyway. In this case, although we don't have the full details, I would hazard a guess that I would normally write the "implements A" on class C aswell, as it appears that the whole point of this hierarchy is to implement the functionality that A defines. Where I wouldn't worry about explicitly stating the "implements A" was if the hierarchy was quite long and extensive and there were a number of interfaces implemented and the functionality the A defines was NOT the primary functionality intended.

Secondly, if you are wondering why would there be an abstract class in the middle, ie. between your implementation classes and the interface that they implement, it is probably just because there is some common functionality between what class C and class D do, and so it is better to move that to an abstract super class rather than repeat it in both. Take this made scenario (although it is based in reality)...

Say you are developing the "Data Access" layer of an application (also called DAO's). Firstly, it is good to have the core functionality of the data access defined in an interface. The business service methods that need to access data only use a reference to the interface. This aids in testing where you can easily create a "mock" dao object which implements the interface and just provides test data to the service methods.

Now, lets assume that in production, the usual source of data is from a JDBC database, but that a requirement is for it to work with both Oracle and SQL Server, as an example. In both cases, there will probably be quite a lot of the code that is identical between them, but in a few small cases there code differs between the two. So you put all the common code in a base class (possibly abstract, like class B in this case) and then in the concreate subclasses (C and D) you put the code particular to each DB type.

Hopefully, that gives you one idea of a real world use for such a hierarchy.
SOLUTION
Avatar of dpearson
dpearson

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Doug -

IIANM, if you declare the class (D in this case) as implementing the interface, then despite it extending the abstract class (which of course also implements the interface), it will use its *own* implemented method rather than that defined in the abstract class. So there is a subtle difference.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry - I think you didn't see that I am saying what you are saying :

If D, extending B, implements A (interface), then when the implemented method is called it will be the local D one, whatever implementation B holds. If D doesn't implement A, then a call to the method will implement B's routine. It does matter if D explicitly implements A or not.
Avatar of pvinodp

ASKER

(krakatoa) :  In our case C does not implement A but extends B. So did you mean
                   B b = new C();
                   b.print();
 will be "in Class B"?

But we know it will print "in Class C". So it comes to point that that implements was useles D for this implementation.
 
Can you give me example [may be by using these classes] where using C and D like this makes a difference?
Can you give me example [may be by using these classes] where using C and D like this makes a difference?

I still don't believe such a case exists.  For my understanding of the language, that's redundant.

When you access an instance of the class, then it makes a difference if you do this as:

D test = new D() ;
A myA = test; // Can't see B methods
B myB = test; // Can't see D methods
D myD = test; // Can see all methods

But in the declaration of the class, I think it makes no difference in this case whether you add "implements A" or not.

Krakatoa - if you're sure there is a difference here, please post some working code that shows this and we can all learn something new :)

Doug
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Doug, mccarl -

I go with what you both have said. If I get second thoughts with a proper example, I'll get back.

As I said in a previous comment to the OP, C and D are the same. Sorry for any confusion.
Avatar of pvinodp

ASKER

I thank you all for a comprehensive discussion.
Doug, mccarl and pvinodp :

My previously badly-made point which I wanted to make was this :

If a child class (D here) has a method of the same name and params as its parent's impl., then, whether D declares itself as implementing the interface *or not*, a call to that method on a D instance will invoke the local D method.

D has 3 options regarding what it shows of the method : 1. it can include the method as defined in the interface, 2. omit it completely, or 3. providing it retains the prescribed return value and scope, it can take different values for its arguments.

If D's local method is missing completely, then a call to the implemented method from a D instance - (or indeed another class) -  (whether D explicitly declares implementation in its signature or not), will produce a call to the superclass' implementation.