Abstract Class versus an Interface, when no Members in Common

Discussion in 'Java' started by KevinSimonson, Nov 3, 2011.

  1. I have a method that needs to be able to return either of two very
    different types of data, in one case a class consisting of a two-
    dimensional array of <int>s accompanied by a single <byte> value, and
    in the other case just a one-dimensional array of <int>s and that's
    all. So I created an abstract class called <SearchResult> that has no
    members, not even any constructors, and made two classes extend
    <SearchResult>, the one class having the two-dimensional array and the
    <byte> value, and the other having the one-dimensional array. Then I
    have my method return a value of <SearchResult>.

    My question is, in a situation like this where there are absolutely no
    variables or methods the two classes have in common, is it better to
    have an abstract class that both classes extend, or is it better to
    have an interface that both classes implement? Or is there any
    difference between the two approaches?

    Kevin Simonson
    KevinSimonson, Nov 3, 2011
    #1
    1. Advertising

  2. KevinSimonson

    Arne Vajhøj Guest

    On 11/3/2011 7:09 PM, KevinSimonson wrote:
    > I have a method that needs to be able to return either of two very
    > different types of data, in one case a class consisting of a two-
    > dimensional array of<int>s accompanied by a single<byte> value, and
    > in the other case just a one-dimensional array of<int>s and that's
    > all. So I created an abstract class called<SearchResult> that has no
    > members, not even any constructors, and made two classes extend
    > <SearchResult>, the one class having the two-dimensional array and the
    > <byte> value, and the other having the one-dimensional array. Then I
    > have my method return a value of<SearchResult>.
    >
    > My question is, in a situation like this where there are absolutely no
    > variables or methods the two classes have in common, is it better to
    > have an abstract class that both classes extend, or is it better to
    > have an interface that both classes implement? Or is there any
    > difference between the two approaches?


    I don't like either approach. The calling code would need
    to detect what type is actually returned and that would
    most likely result in some very ugly code.

    Two methods in the public API:

    public Typ1 returnFoobarAsTyp1();
    public Typ2 returnFoobarAsTyp2();

    Arne
    Arne Vajhøj, Nov 3, 2011
    #2
    1. Advertising

  3. KevinSimonson

    markspace Guest

    On 11/3/2011 4:09 PM, KevinSimonson wrote:
    > So I created an abstract class called<SearchResult> that has no


    In the real world, when there's a class like this, there's usually some
    meta data that can decode which type is being returned. As Arne points
    out, there's usually also a "getAsType" method. For example, the JDBC
    object has various "getBoolean()" and "getBlob()" methods for accessing
    database columns, as well as metadata describing the object.

    While not the best over all (JPA is better, generally, than JDBC), it's
    more structured that just an abstract class with no methods.

    I might say that no methods = interface (called a mixin), but I think
    the potential to add common methods here is high. So, use a base class
    so that you don't get tripped up by Java's single inheritance. It's the
    most conservative approach in this case.
    markspace, Nov 4, 2011
    #3
  4. KevinSimonson

    Lew Guest

    markspace wrote:
    > KevinSimonson wrote:
    > > So I created an abstract class called<SearchResult> that has no

    >
    > In the real world, when there's a class like this, there's usually some
    > meta data that can decode which type is being returned. As Arne points
    > out, there's usually also a "getAsType" method. For example, the JDBC
    > object has various "getBoolean()" and "getBlob()" methods for accessing
    > database columns, as well as metadata describing the object.
    >
    > While not the best over all (JPA is better, generally, than JDBC), it's
    > more structured that just an abstract class with no methods.
    >
    > I might say that no methods = interface (called a mixin), but I think
    > the potential to add common methods here is high. So, use a base class
    > so that you don't get tripped up by Java's single inheritance. It's the
    > most conservative approach in this case.


    The OP's approach seems somewhat hackish, based on the paucity of information provided so maybe it isn't. Would it work to make the varying type a generic parameter?

    --
    Lew
    Lew, Nov 4, 2011
    #4
  5. KevinSimonson

    markspace Guest

    On 11/3/2011 6:10 PM, Lew wrote:

    > The OP's approach seems somewhat hackish, based on the paucity of
    > information provided so maybe it isn't. Would it work to make the
    > varying type a generic parameter?



    He'd have to add some sort of method(s) to support the generic
    parameter. Some kind of generic mix-in:

    public interface MixMe<T> {}

    Seems silly to me, without something specified to be done with T. Like
    wise a base class with a single generic getter:

    public BaseGetter<U> {
    public U get();
    }

    doesn't seem any different than just making a regular non-generic
    sub-class. Arne's point of just declaring the methods and return types
    you need in one class seems the most straight forward.

    I think he just has to be prepared to refactor a lot of code when the
    right way to do it becomes apparent. What he's got right now could go
    any way at all.
    markspace, Nov 4, 2011
    #5
  6. KevinSimonson

    Roedy Green Guest

    On Thu, 3 Nov 2011 16:09:08 -0700 (PDT), KevinSimonson
    <> wrote, quoted or indirectly quoted someone who
    said :

    >I have a method that needs to be able to return either of two very
    >different types of data, i


    Another way to handle it is like this:

    final Calculator calc = new Calculator( a, b,c );
    if ( calc.isStrange() )
    {
    final Strange strangeAnswer = calc.getStrangeAnswer();
    ...
    }
    else
    {
    final Ordinary ordinary = calc.getOrdinaryAnswer();
    ...
    }


    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Capitalism has spurred the competition that makes CPUs faster and
    faster each year, but the focus on money makes software manufacturers
    do some peculiar things like deliberately leaving bugs and deficiencies
    in the software so they can soak the customers for upgrades later.
    Whether software is easy to use, or never loses data, when the company
    has a near monopoly, is almost irrelevant to profits, and therefore
    ignored. The manufacturer focuses on cheap gimicks like dancing paper
    clips to dazzle naive first-time buyers. The needs of existing
    experienced users are almost irrelevant. I see software rental as the
    best remedy.
    Roedy Green, Nov 4, 2011
    #6
  7. KevinSimonson

    Ian Pilcher Guest

    On 11/03/2011 06:09 PM, KevinSimonson wrote:
    > I have a method that needs to be able to return either of two very
    > different types of data, in one case a class consisting of a two-
    > dimensional array of <int>s accompanied by a single <byte> value, and
    > in the other case just a one-dimensional array of <int>s and that's
    > all. So I created an abstract class called <SearchResult> that has no
    > members, not even any constructors, and made two classes extend
    > <SearchResult>, the one class having the two-dimensional array and the
    > <byte> value, and the other having the one-dimensional array. Then I
    > have my method return a value of <SearchResult>.


    If you *really* need to overload the return value of your method like
    this (and I'm skeptical), you can put the 1-dimensional array into a 2-
    dimensional array:

    int[] array1D = { 1, 2, 3 };
    int[][] array2D = new int[1][]; // This seems backwards to me
    array2D[0] = array1D;

    --
    ========================================================================
    Ian Pilcher
    "If you're going to shift my paradigm ... at least buy me dinner first."
    ========================================================================
    Ian Pilcher, Nov 4, 2011
    #7
  8. On 11/04/2011 12:09 AM, KevinSimonson wrote:
    > I have a method that needs to be able to return either of two very
    > different types of data,


    Based on what criteria?

    > in one case a class consisting of a two-
    > dimensional array of<int>s accompanied by a single<byte> value, and
    > in the other case just a one-dimensional array of<int>s and that's
    > all. So I created an abstract class called<SearchResult> that has no
    > members, not even any constructors, and made two classes extend
    > <SearchResult>, the one class having the two-dimensional array and the
    > <byte> value, and the other having the one-dimensional array. Then I
    > have my method return a value of<SearchResult>.
    >
    > My question is, in a situation like this where there are absolutely no
    > variables or methods the two classes have in common, is it better to
    > have an abstract class that both classes extend, or is it better to
    > have an interface that both classes implement? Or is there any
    > difference between the two approaches?


    Since your result classes do not have anything in common you could as
    well use Object as return type. From your description the caller needs
    to downcast SearchResult anyway. If SearchResult does not have any
    properties (methods) then the type may be superfluous altogether. There
    are really only few cases where an interface without methods does make
    sense (e.g. Serializable and Cloneable as tagging interfaces). In your
    case the only property that could be associated with the empty interface
    (or abstract class) SearchResult is that it is returned by your method
    X. But that is not a property of a type; rather it is an indication of
    usage.

    If it's clear at call site which return type you'll get you could have a
    method with a generic type parameter, e.g.

    public <T> T search(...) {...}

    Maybe you even have two search methods with different argument lists
    each returning a specific type.

    Kind regards

    robert
    Robert Klemme, Nov 4, 2011
    #8
  9. KevinSimonson

    Daniel Pitts Guest

    On 11/3/11 4:09 PM, KevinSimonson wrote:
    > I have a method that needs to be able to return either of two very
    > different types of data, in one case a class consisting of a two-
    > dimensional array of<int>s accompanied by a single<byte> value, and
    > in the other case just a one-dimensional array of<int>s and that's
    > all. So I created an abstract class called<SearchResult> that has no
    > members, not even any constructors, and made two classes extend
    > <SearchResult>, the one class having the two-dimensional array and the
    > <byte> value, and the other having the one-dimensional array. Then I
    > have my method return a value of<SearchResult>.
    >
    > My question is, in a situation like this where there are absolutely no
    > variables or methods the two classes have in common, is it better to
    > have an abstract class that both classes extend, or is it better to
    > have an interface that both classes implement? Or is there any
    > difference between the two approaches?
    >
    > Kevin Simonson


    Sounds almost like you want a visitor pattern instead, or an
    intermediate object:

    public class SearchResult {
    public boolean isSingleArray() { ... }
    public boolean isMultipleArray() { ... }

    // Throws IllegalStateException if !isSingleArray
    public SingleArray getSingleArray() { ... }
    // Throws IllegalStateException if !isMutipleArray
    public MultipleArray getMultipleArray() { ... }

    }

    Alternatively, or conjointly, you can use the visitor pattern.
    Daniel Pitts, Nov 4, 2011
    #9
  10. KevinSimonson

    Roedy Green Guest

    One my essays that gets more than its share of hits discuses when to
    use an abstract class and when an interface and when both.

    see http://mindprod.com/jgloss/interfacevsabstract.html

    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Capitalism has spurred the competition that makes CPUs faster and
    faster each year, but the focus on money makes software manufacturers
    do some peculiar things like deliberately leaving bugs and deficiencies
    in the software so they can soak the customers for upgrades later.
    Whether software is easy to use, or never loses data, when the company
    has a near monopoly, is almost irrelevant to profits, and therefore
    ignored. The manufacturer focuses on cheap gimicks like dancing paper
    clips to dazzle naive first-time buyers. The needs of existing
    experienced users are almost irrelevant. I see software rental as the
    best remedy.
    Roedy Green, Nov 4, 2011
    #10
  11. KevinSimonson

    Daniel Pitts Guest

    On 11/8/11 2:15 PM, Wanja Gayk wrote:
    > In article<3iYsq.9363$>,
    > says...
    >
    >> Sounds almost like you want a visitor pattern instead, or an
    >> intermediate object:
    >>
    >> public class SearchResult {
    >> public boolean isSingleArray() { ... }
    >> public boolean isMultipleArray() { ... }
    >>
    >> // Throws IllegalStateException if !isSingleArray
    >> public SingleArray getSingleArray() { ... }
    >> // Throws IllegalStateException if !isMutipleArray
    >> public MultipleArray getMultipleArray() { ... }
    >>
    >> }

    >
    > That doesn't seem to be any better than the infamous instaceof-cascade -
    > I'd rather say it's even uglier.

    Being converted to a visitor pattern would be better, granted, but the
    OP was extremely vague on the requirements.
    Daniel Pitts, Nov 9, 2011
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rajarshi Guha

    abstract class versus interface

    Rajarshi Guha, Feb 6, 2004, in forum: Java
    Replies:
    20
    Views:
    3,325
    Tony Morris
    Feb 12, 2004
  2. Matthias Kaeppler
    Replies:
    1
    Views:
    418
    R.F. Pels
    May 22, 2005
  3. Replies:
    4
    Views:
    800
    Rolf Magnus
    May 17, 2006
  4. Paul Butcher
    Replies:
    12
    Views:
    691
    Gary Wright
    Nov 28, 2007
  5. John Reye
    Replies:
    28
    Views:
    1,336
    Tim Rentsch
    May 8, 2012
Loading...

Share This Page