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?
pvinodpAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

krakatoaCommented:
"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

0
pvinodpAuthor Commented:
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?
0
krakatoaCommented:
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.
0
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

pvinodpAuthor Commented:
can u illustrate a advantage of this design.. i am trying to understand ..
0
krakatoaCommented:
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).
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
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.
0
dpearsonCommented:
This part of the pattern is quite common:

interface A
Abstract class B implements A


if you think of B as providing a default implementation for the interface A.

Since B is abstract, it's probably only a partial implementation of A.

You can derive from B and pick up that default or just implement A yourself, if you don't want to use the default.  Java has a lot of libraries that follow this pattern.

E.g.
interface List
abstract class AbstractList  implements List
class ArrayList extends AbstractList         [implicitly implements List]

follows exactly the pattern you posted.  AbstractList provides some of the implementation that lists will often use, but they don't have to.  They can directly implement List if they wish.  ArrayList is a specific concrete class and has the full implementation of a list.  Vector is another specific concrete class that derives from AbstractList.

http://docs.oracle.com/javase/7/docs/api/java/util/AbstractList.html

In your example C and D are both picking up that default implementation (from B) rather than doing the work of implementing all of A themselves.

As has already been pointed out "class D extends B implements A" is redundant and could have just been written "class D extends B".  So don't let that throw you off.

Doug
0
krakatoaCommented:
(Doug) :
As has already been pointed out "class D extends B implements A" is redundant and could have just been written "class D extends B".  So don't let that throw you off.

yes, but of course only if you do not require D to implement the interface in a different way to B.

-----

The interface is Java's way of circumnavigating multiple inheritance issues. Therefore it is sometimes useful to be able to declare objects of the interface type, like for example:

A (interface) iFace = new C() (Class);

formally then :

A iFace = new C();
iFace.someMethod();

Open in new window


However, if you attempt to reference a method in C class via the iFace type instance, which is not an implementational method, you will not be even able to compile.

This explains it more.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dpearsonCommented:
yes, but of course only if you do not require D to implement the interface in a different way to B.

Not sure I quite get the point you're making here Krakatoa.  I'm pretty sure it's entirely redundant to add "implements A" to the class definition when B already implements A.

As you say, when you use an instance of the class it makes a difference whether you use the interface or the class itself, but that's not what's happening here.

In this case, D can implement A in any way it likes (via inheritance from B or by directly overriding the methods itself), whether the class says "implements A" or not.

Just wanted to make sure we didn't muddle up the meaning of the interface in a class definition, compared to when an instance is declared (where I definitely agree with what Krakatoa is saying).

Doug
0
krakatoaCommented:
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.
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
krakatoa,

No, that isn't correct. Hopefully, this little piece of code can clear things up...
public class TestInheritance {

    public static void main(String[] args) {
        A ac = new C();
        A ad = new D();
        
        ac.print();
        ad.print();
    }
    
    public static interface A {
        void print();
    }
    
    public static abstract class B implements A {
        public void print() {
            System.out.println("in Class B");
        }
    }
    
    public static class C extends B {
        public void print() {
            System.out.println("in Class C");
        }
    }
    
    public static class D extends B implements A {
        public void print() {
            System.out.println("in Class D");
        }
    }
}

Open in new window

The output from the above is...
in Class C
in Class D

Open in new window

This shows that it doesn't matter if you explicitly "implements A" or not, you can still define your own implementation of method defined in A.

I realise that there are many different variations on the above, ie. whether the method was implemented in the abstract class or not, but none of that will matter. The fact is that class C and D behave identically regardless of the "implements A" or not.
0
krakatoaCommented:
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.
0
pvinodpAuthor Commented:
(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?
0
dpearsonCommented:
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
0
dpearsonCommented:
It occurred to me after writing this that we may be talking about two meaning of whether a class "implements A" or not.

1) Adding "implements A" to the class declaration of D.
    This is the one that I think does nothing.

2) Adding extra methods to D that implement the A interface explicitly.
    This certainly changes what D does and makes a difference.
    This could be done whether the class declaration includes "implements A" or not.
    (e.g. C could also do this with methods that implement A directly).

I think the original question is about #1, but it maybe that Krakatoa, you are talking about #2?  If so this may explain the confusion.

Doug
0
krakatoaCommented:
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.
0
pvinodpAuthor Commented:
I thank you all for a comprehensive discussion.
0
krakatoaCommented:
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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.