abstract classes and generic types

Discussion in 'Java' started by horos11@gmail.com, May 17, 2009.

  1. Guest

    All,

    I'm trying to overcome the following problem. I'd like to have an
    abstract class contain common functionality for subclasses, but I
    don't want to be limited by the representations of them. For example:

    abstract class a
    {
    String calculate() { return this.put(this.my_func()); }
    }

    class b extends a
    {
    Set<Integer> myset;

    Integer my_func() { return (1); }
    void put(Integer myint) { myset.put(myint); }
    }

    class c extends a
    {
    Set<Float> myset;
    Float my_func() { return(1.0); }
    void put(Float myfloat) { myset.put(myfloat); }
    }

    As it stands, if I put the return types, etc. in the abstract class it
    gets exceedingly ugly because implementation details are seeping into
    the abstract class and it would need to be updated with new function
    signatures each time a new subclass is created. I need to find a way
    to say that any given method is *purely* abstract, ie: that it will be
    defined solely in the subclass.

    Is there a way to do this, or am I pretty much stuck reimplementing
    lots of functionality in each subclass?

    thanks much..
     
    , May 17, 2009
    #1
    1. Advertising

  2. wrote in news:3d5780fe-671e-4f46-94f9-
    :

    > All,
    >
    > I'm trying to overcome the following problem. I'd like to have an
    > abstract class contain common functionality for subclasses, but I
    > don't want to be limited by the representations of them. For example:
    >
    > abstract class a
    > {
    > String calculate() { return this.put(this.my_func()); }
    > }
    >
    > class b extends a
    > {
    > Set<Integer> myset;
    >
    > Integer my_func() { return (1); }
    > void put(Integer myint) { myset.put(myint); }
    > }
    >
    > class c extends a
    > {
    > Set<Float> myset;
    > Float my_func() { return(1.0); }
    > void put(Float myfloat) { myset.put(myfloat); }
    > }
    >
    > As it stands, if I put the return types, etc. in the abstract class it
    > gets exceedingly ugly because implementation details are seeping into
    > the abstract class and it would need to be updated with new function
    > signatures each time a new subclass is created. I need to find a way
    > to say that any given method is *purely* abstract, ie: that it will be
    > defined solely in the subclass.
    >
    > Is there a way to do this, or am I pretty much stuck reimplementing
    > lots of functionality in each subclass?
    >
    > thanks much..
    >
    >


    abstract class a
    {
    protected Set<Object> myset = new java.util.HashSet<Object>();

    // how put returns a String is beyond me ???
    String calculate() { this.put(this.myfunc()); return "barf"; }

    abstract Object my_func() ;
    }

    class b extends a
    {
    @Override
    Object my_func() { return new Integer(1); }

    void put(Integer myint) { myset.put(myint); }
    }

    class b extends a
    {
    @Override
    Object my_func() { return new Float(1); }

    void put(Float myfloat) { myset.put(myfloat); }
    }
     
    Donkey Hottie, May 17, 2009
    #2
    1. Advertising

  3. Donkey Hottie <> wrote in
    news:Xns9C0EE14908F5ASH15SGybs1ysmajw54s5@62.237.120.180:

    > wrote in news:3d5780fe-671e-4f46-94f9-
    > :
    >
    >> All,
    >>
    >> I'm trying to overcome the following problem. I'd like to have an
    >> abstract class contain common functionality for subclasses, but I
    >> don't want to be limited by the representations of them. For example:
    >>
    >> abstract class a
    >> {
    >> String calculate() { return this.put(this.my_func()); }
    >> }
    >>
    >> class b extends a
    >> {
    >> Set<Integer> myset;
    >>
    >> Integer my_func() { return (1); }
    >> void put(Integer myint) { myset.put(myint); }
    >> }
    >>
    >> class c extends a
    >> {
    >> Set<Float> myset;
    >> Float my_func() { return(1.0); }
    >> void put(Float myfloat) { myset.put(myfloat); }
    >> }
    >>
    >> As it stands, if I put the return types, etc. in the abstract class it
    >> gets exceedingly ugly because implementation details are seeping into
    >> the abstract class and it would need to be updated with new function
    >> signatures each time a new subclass is created. I need to find a way
    >> to say that any given method is *purely* abstract, ie: that it will be
    >> defined solely in the subclass.
    >>
    >> Is there a way to do this, or am I pretty much stuck reimplementing
    >> lots of functionality in each subclass?
    >>
    >> thanks much..
    >>
    >>

    >
    > abstract class a
    > {
    > protected Set<Object> myset = new java.util.HashSet<Object>();
    >
    > // how put returns a String is beyond me ???
    > String calculate() { this.put(this.myfunc()); return "barf"; }
    >
    > abstract Object my_func() ;
    > }
    >
    > class b extends a
    > {
    > @Override
    > Object my_func() { return new Integer(1); }
    >
    > void put(Integer myint) { myset.put(myint); }
    > }
    >
    > class b extends a
    > {
    > @Override
    > Object my_func() { return new Float(1); }
    >
    > void put(Float myfloat) { myset.put(myfloat); }
    > }
    >
    >


    I cancelled this. It has no point, the original sample is beyond any clue
    and no point in refining it.

    Sorry.
     
    Donkey Hottie, May 17, 2009
    #3
  4. How about:

    public abstract class A<N extends Number> {
    void calculate() { put(my_func()); }
    abstract N my_func();
    void put(N myN) { set.add(myN); }
    private final Set<N> set = new HashSet<N>();
    }

    public class B extends A<Long> {
    @Override
    Long my_func() { return Long.valueOf(1); }
    }

    AFAIK you can't do A generic without ressorting to reflection to get hold of
    the right constructor for the Number subclass.

    HTH,
    regards,
    Giovanni
     
    Giovanni Azua, May 17, 2009
    #4
  5. "Donkey Hottie" <> wrote
    > I cancelled this. It has no point, the original sample is beyond any clue
    > and no point in refining it.
    >

    :) yes but some alternatives for the OP to get an idea would be helpful I
    think.

    I tried to address his question:
    "I need to find a way to say that any given method is *purely* abstract"

    Best regards,
    Giovanni
     
    Giovanni Azua, May 17, 2009
    #5
  6. Lew Guest

    wrote:
    >> I'm trying to overcome the following problem. I'd like to have an
    >> abstract class contain common functionality for subclasses, but I
    >> don't want to be limited by the representations of them. For example:
    >>
    >> abstract class a


    Class names should begin with an upper-case letter, and comprise compound word
    parts, each subsequent part also beginning with an upper-case letter. This
    mixed-case convention is called "camel case". Thus, the class name should be "A".

    >> {
    >> String calculate() { return this.put(this.my_func()); }


    Method and variable names other than of constants should begin with a
    lower-case letter and thereafter be in camel case. Underscores should not be
    in such names. Thus, "myFunc()" (although "Func" in a function name is
    redundant and useless).

    >> }
    >>
    >> class b extends a


    'class B extends A'

    >> {
    >> Set<Integer> myset;


    'mySet' (although "Set" in the name of a set is actually silly and somewhat
    harmful to refactoring).

    >> Integer my_func() { return (1); }
    >> void put(Integer myint) { myset.put(myint); }
    >> }
    >>
    >> class c extends a
    >> {
    >> Set<Float> myset;
    >> Float my_func() { return(1.0); }
    >> void put(Float myfloat) { myset.put(myfloat); }
    >> }
    >>
    >> As it stands, if I put the return types, etc. [sic] in the abstract class it
    >> gets exceedingly ugly because implementation details are seeping into
    >> the abstract class and it would need to be updated with new function
    >> signatures each time a new subclass is created. I need to find a way
    >> to say that any given method is *purely* abstract, ie: that it will be
    >> defined solely in the subclass.
    >>
    >> Is there a way to do this, or am I pretty much stuck reimplementing
    >> lots of functionality in each subclass?


    Generics, along the lines Giovanni Azua showed you.

    Giovanni Azua wrote:
    > How about:
    >
    > public abstract class A<N extends Number> {
    > void calculate() { put(my_func()); }
    > abstract N my_func();
    > void put(N myN) { set.add(myN); }
    > private final Set<N> set = new HashSet<N>();
    > }
    >
    > public class B extends A<Long> {
    > @Override
    > Long my_func() { return Long.valueOf(1); }
    > }
    >
    > AFAIK you can't do A generic without ressorting to reflection to get hold of
    > the right constructor for the Number subclass.


    I don't understand what you mean exactly. 'A' is generic as you show it here.

    'my_func()' should be named in accordance with the naming conventions, and
    meaningfully, say 'getValue()'. The methods should probably be 'public'.
    (And, of course, the classes should belong to packages.)

    --
    Lew
     
    Lew, May 17, 2009
    #6
  7. Hi Lew,

    "Lew" <> wrote
    >> AFAIK you can't do A generic without ressorting to reflection to get hold
    >> of the right constructor for the Number subclass.

    >
    > I don't understand what you mean exactly. 'A' is generic as you show it
    > here.
    >

    Indeed you are right, I meant the generic not in the proper sense of
    genericity but generic in the sense of A being concrete and reusable for all
    cases without need to implement concrete subclasses "a generic solution" I
    can't recall where I learned this second definition from ... :)

    > 'my_func()' should be named in accordance with the naming conventions, and
    > meaningfully, say 'getValue()'. The methods should probably be 'public'.
    > (And, of course, the classes should belong to packages.)
    >

    I agree but you won't help and address the OP by completely changing her
    example, I guess you will confuse her.

    Best regards,
    Giovanni
     
    Giovanni Azua, May 17, 2009
    #7
  8. Lew Guest

    Giovanni Azua wrote:
    >>> AFAIK you can't do A generic without ressorting to reflection to get hold
    >>> of the right constructor for the Number subclass.


    Lew wrote
    >> I don't understand what you mean exactly. 'A' is generic as you show it
    >> here.


    Giovanni Azua wrote:
    > Indeed you are right, I meant the generic not in the proper sense of
    > genericity but generic in the sense of A being concrete and reusable for all
    > cases without need to implement concrete subclasses "a generic solution" I
    > can't recall where I learned this second definition from ... :)


    Lew wrote
    >> 'my_func()' should be named in accordance with the naming conventions, and
    >> meaningfully, say 'getValue()'. The methods should probably be 'public'.
    >> (And, of course, the classes should belong to packages.)


    Giovanni Azua wrote:
    > I agree but you won't help and address the OP by completely changing her
    > example, I guess you will confuse her.


    I hope not. horos11, if you are confused please feel free to ask more
    questions and we'll work to clear it up.

    Bad habits not caught early and corrected early are all the harder to correct.
    Begin by doing things correctly. It's less to unlearn later.

    The coding conventions are documented in
    <http://java.sun.com/docs/codeconv/index.html>
    (I admit, proudly, that I use the other convention for opening brace "{"
    placement.)

    More of your questions can be answered starting at the Java tutorials:
    <http://java.sun.com/docs/books/tutorial/index.html>
    and the links from there.

    --
    Lew
     
    Lew, May 17, 2009
    #8
  9. "Lew" <> wrote
    > The coding conventions are documented in
    > <http://java.sun.com/docs/codeconv/index.html>
    > (I admit, proudly, that I use the other convention for opening brace "{"
    > placement.)
    >

    I also don't like some of the Sun recommended ways of doing a few things
    e.g. to have your implementation details (attributes) listed on top. It is
    an implicit bottom-up way of design and thinking counter to the good OO
    top-bottom design and good encapsulation. I don't want to see implementation
    details, I'd rather like to see the public interface/methods of a class:
    http://java.sun.com/docs/codeconv/html/CodeConventions.doc10.html

    Regards,
    Giovanni
     
    Giovanni Azua, May 17, 2009
    #9
  10. Lew Guest

    Giovanni Azua wrote:
    > "Lew" <> wrote
    >> The coding conventions are documented in
    >> <http://java.sun.com/docs/codeconv/index.html>
    >> (I admit, proudly, that I use the other convention for opening brace "{"
    >> placement.)
    >>

    > I also don't like some of the Sun recommended ways of doing a few things
    > e.g. to have your implementation details (attributes) listed on top. It is
    > an implicit bottom-up way of design and thinking counter to the good OO
    > top-bottom design and good encapsulation. I don't want to see implementation
    > details, I'd rather like to see the public interface/methods of a class:
    > http://java.sun.com/docs/codeconv/html/CodeConventions.doc10.html


    Used as I am to the conventional way of listing attributes prior to methods, I
    found your listing jarring. I like to see things declared prior to their use,
    a necessity within the body of methods and initializers, and a comforting
    tradition for members. There's something that offends my sensibilities about
    not knowing what a thing is until after its use.

    Enums are a major exception to the tradition. Because their syntax requires
    declaration of the constants before anything else, some of the conventions are
    turned upside-down.

    I recommend to newbies that they adhere to the convention of declaring member
    variables prior to member methods, at least until they've gained enough
    experience in Java to decide whether the other way is so superior in every
    respect that it's worth violating the convention.

    As for seeing the public interface first, that's what interfaces themselves
    are for, and part of the motivation for "programming to the interface" as a
    recommended practice.

    --
    Lew
     
    Lew, May 17, 2009
    #10
  11. Mark Space Guest

    I think I came up with the same thing Giovanni did, except "put" needs
    to return a String to match your example.

    wrote:

    abstract class a<U>
    > {
    > String calculate() { return this.put(this.my_func()); }

    abstract String put( U u );
    abstract U my_func();
    > }
    >


    Otherwise use this the same way as his example.

    Note: you can' parameterize with primitives. If you want to use float
    or int, gotta write those by hand yourself. Sorry.
     
    Mark Space, May 17, 2009
    #11
  12. Lew Guest

    Mark Space wrote:
    > Note: you can' parameterize with primitives. If you want to use float
    > or int, gotta write those by hand yourself. Sorry.


    Or use Float and Integer.

    --
    Lew
     
    Lew, May 18, 2009
    #12
  13. Guest

    On May 17, 3:29 pm, Mark Space <> wrote:
    > I think I came up with the same thing Giovanni did, except "put" needs
    > to return a String to match your example.
    >
    > wrote:
    >
    > abstract class a<U>> {
    > >     String calculate() { return this.put(this.my_func()); }

    >
    >        abstract String put( U u );
    >        abstract U my_func();
    >
    > > }

    >
    > Otherwise use this the same way as his example.
    >
    > Note:  you can' parameterize with primitives.  If you want to use float
    > or int, gotta write those by hand yourself.  Sorry.


    Ok, I guess I'll morph this issue a bit. I came to the conclusion that
    generics were the way to go, but why should I need to define a
    parameter with a class to do what I want to do?

    I think of the types of variables in an object as implementation
    details.. But the following doesn't work:

    import java.util.*;
    class AA
    {

    Set<?> example;

    aa()
    {
    example = new HashSet<Integer>();
    _setHelper(example, new Integer(1));
    System.out.println(example);
    }

    private<K> void _setHelper(Set<K> parm, K key)
    {
    parm.add(key);
    }
    }

    where I'm attempting to give the compiler a little push in the right
    direction, showing that Set<K> should be linked with the ?. I would
    have thought this would have worked, but no.

    Of course, if I explicitly cast it - (Set<Integer>)example, it works,
    but that gets rid of the point of generics, doesn't it?

    So any ideas around this?

    (ps - wrt language lawyering, with all respect I detest camelcase, and
    will only use it if required by convention. And no - I don't go around
    naming my variables mySet, etc.. I do it for example.. so thanks for
    the concern, but no thanks..
     
    , May 18, 2009
    #13
  14. Guest

    BTW - with the below I did find a workaround. If I say:

    private<K> void _setHelper(Set<K> parm, Integer key)
    {
    parm.add((K) key);
    }

    ie, ie explicitly cast it, this works. But it also tells me that I'm
    using unsafe operations.
    This should not be unsafe - there's got to be a better solution than
    this out there. Else are generics inherently unsafe?


    > import java.util.*;
    > class AA
    > {
    >
    >     Set<?> example;
    >
    >     aa()
    >     {
    >          example = new HashSet<Integer>();
    >         _setHelper(example, new Integer(1));
    >          System.out.println(example);
    >     }
    >
    >     private<K> void _setHelper(Set<K> parm, K key)
    >     {
    >         parm.add(key);
    >     }
    >
    > }
    >
    > where I'm attempting to give the compiler a little push in the right
    > direction, showing that Set<K> should be linked with the ?. I would
    > have thought this would have worked, but no.
    >
    > Of course, if I explicitly cast it - (Set<Integer>)example, it works,
    > but that gets rid of the point of generics, doesn't it?
    >
    > So any ideas around this?
    >
    > (ps - wrt language lawyering, with all respect I detest camelcase, and
    > will only use it if required by convention. And no - I don't go around
    > naming my variables mySet, etc.. I do it for example.. so thanks for
    > the concern, but no thanks..
     
    , May 18, 2009
    #14
  15. Lew Guest

    wrote:
    > Ok, I guess I'll morph this issue a bit. I came to the conclusion that
    > generics were the way to go, but why should I need to define a
    > parameter with a class to do what I want to do?


    Because that's how Java does it.

    > I think of the types of variables in an object as implementation
    > details.. But the following doesn't work:
    >
    > import java.util.*;
    > class AA
    > {
    >
    > Set<?> example;
    >
    > aa()


    The constructor name must match the class name. This line as shown will not
    compile, as it is legal for neither constructor nor method.

    Both class and constructor must be public if you wish to use them outside the
    package in which they're defined.

    > {
    > example = new HashSet<Integer>();
    > _setHelper(example, new Integer(1));
    > System.out.println(example);
    > }
    >
    > private<K> void _setHelper(Set<K> parm, K key)


    Convention has it that one not use underscores in method names.

    To your actual point, 'Set<?>' and 'Set<K>' have different meanings. Just
    telling the method that the 'Set<?>' is actually a 'Set<Integer>' isn't quite
    enough. Generally, with "extends" wildcards (? is shorthand for "? extends
    Object"), you cannot safely "put()" (i.e., "add()" in this context).

    See these articles:
    <http://java.sun.com/docs/books/tutorial/extra/generics/index.html>
    particularly,
    <http://java.sun.com/docs/books/tutorial/extra/generics/wildcards.html>

    <http://www.ibm.com/developerworks/java/library/j-jtp04298.html>
    <http://www.ibm.com/developerworks/java/library/j-jtp07018.html>

    The compiler errors will indicate what you did wrong, but in more general
    terms, you aren't locking down your type analysis with this kind of thing. If
    'example' is meant to be a 'Set<Integer>', it should be declared as such. If
    the whole class is meant to be a general handler for different types of sets,
    where the instance will deal throughout with the same type, then the class
    itself should have the type parameter. Also, there's little point in passing
    a member variable as an argument to a member method of the same class. It
    already has access to the member variable.

    > {
    > parm.add(key);
    > }
    > }
    >
    > where I'm attempting to give the compiler a little push in the right
    > direction, showing that Set<K> should be linked with the ?. I would
    > have thought this would have worked, but no.


    That's because you are misusing the generics syntax. The right way to do this
    is to have the <K> in the 'Set' declaration itself. You were trying to tell
    the compiler that 'Set' can have literally any type of object in it with the
    <?>, and also simultaneously that it can only have 'K' (in this case,
    'Integer') in it. You can't get both promises at the same time because they
    contradict each other.

    Furthermore, <?> means that whatever type 'Set' contains, all its elements are
    of that type. If your method were legal, it could be called at different
    times with different 'K' types, all trying to 'add()' to the same set. That
    wouldn't be legal either.

    > Of course, if I explicitly cast it - (Set<Integer>)example, it works,
    > but that gets rid of the point of generics, doesn't it?


    It does generate a warning to that effect.

    It was the failure to lock down the 'example' type parameter to that of the
    method that got rid of that point, actually.

    > So any ideas around this?


    Do it like this:

    public class AA
    {

    Set<Integer> example = new HashSet<Integer>();

    public void loadAndPrintln()
    {
    example.add( Integer.valueOf(1) );
    System.out.println( example );
    }
    }

    If you want 'AA' to be generic so that client code can use it for 'Integer',
    'String' or whatever, the generic parameter should be on the class itself.

    public class AA <K>
    {
    Set <K> example = new HashSet <K> ();

    public void loadAndPrintln( K value )
    {
    example.add( value );
    System.out.println( example );
    }
    }

    That's kind of the point of generics, isn't it?

    > (ps [sic] - wrt language lawyering, with all respect I detest camelcase, and
    > will only use it if required by convention. And no - I don't go around


    It is "required" by convention. It is not a question of "language lawyering",
    as you so disparagingly put it, but of communication. The language itself
    lets you do things differently, but that doesn't mean that you should do
    things differently. The conventions make life easier in a world where one is
    not the only resident.

    However, whatever convention you do follow, the constructor name must match
    the case of the class name. The compiler will refuse to cooperate if you don't.

    > naming my variables mySet, etc.. I do it for example.. so thanks for
    > the concern, but no thanks..


    One period suffices to indicate a declarative sentence.

    --
    Lew
     
    Lew, May 18, 2009
    #15
  16. Lew Guest

    wrote:
    > BTW - with the below I did find a workaround. If I say:
    >
    > private<K> void _setHelper(Set<K> parm, Integer key)
    > {
    > parm.add((K) key);
    > }
    >
    > ie, ie explicitly cast it, this works. But it also tells me that I'm
    > using unsafe operations.
    > This should not be unsafe - there's got to be a better solution than
    > this out there. Else are generics inherently unsafe?


    No, generics make life more safe. What you did intentionally broke the
    promises that generics tries to keep, so that was what was unsafe.

    If you read the rules for generics, you will see that they are compile-time
    constructs, and that casts to a parametric type, being a run-time phenomenon,
    are therefore not really what generics handle. Thus the warning.

    Correct use of generics, which follows hard on correct if difficult detailed
    type analysis, will eliminate both the need for the cast and the warning.

    --
    Lew
     
    Lew, May 18, 2009
    #16
  17. Mark Space Guest

    wrote:
    > BTW - with the below I did find a workaround. If I say:
    >
    > private<K> void _setHelper(Set<K> parm, Integer key)
    > {
    > parm.add((K) key);
    > }
    >
    > ie, ie explicitly cast it, this works. But it also tells me that I'm
    > using unsafe operations.
    > This should not be unsafe - there's got to be a better solution than
    > this out there. Else are generics inherently unsafe?


    No, they're safe, just the way you are using them isn't.

    First, I want to point out that if you follow Giovanni's advice, the end
    user never sees the generic declaration.

    class AA<T> {}

    class BB extends AA<Integer> {}

    The user just uses BB as a normal class:

    BB bb = new BB();

    So I don't see why you want to get rid of generics. However, if you do,
    then I think something like this will work:

    class AA {}

    class BB {} extends AA {
    Set<Integer> example;
    BB() {
    example = newHashSet<Integer>();
    example.add( new Integer() );
    System.out.println( example );
    }
    }

    No need for the helper method, but in this case you do need to declare
    the Set<> yourself (which you were basically doing anyway when you
    called "new").
     
    Mark Space, May 18, 2009
    #17
  18. Tom Anderson Guest

    On Sun, 17 May 2009, wrote:

    > On May 17, 3:29 pm, Mark Space <> wrote:
    >> I think I came up with the same thing Giovanni did, except "put" needs
    >> to return a String to match your example.
    >>
    >> wrote:
    >>
    >> abstract class a<U>> {
    >>>     String calculate() { return this.put(this.my_func()); }

    >>
    >>        abstract String put( U u );
    >>        abstract U my_func();
    >>
    >>> }

    >>
    >> Otherwise use this the same way as his example.
    >>
    >> Note:  you can' parameterize with primitives.  If you want to use float
    >> or int, gotta write those by hand yourself.  Sorry.

    >
    > Ok, I guess I'll morph this issue a bit. I came to the conclusion that
    > generics were the way to go, but why should I need to define a parameter
    > with a class to do what I want to do?


    This has been discussed here many times before. The upshot is that because
    of the way java's generics work, you can't get away from defining the
    parameter as part of the exposed interface. You require clients to write:

    HorosFunkyClass<?>

    Instead of just:

    HorosFunkyClass

    When dealing with it polymorphically. This is a wart, but a small one.

    However ...

    I have thought of a way you could do it without the wart, using
    deviousness.

    The trick is to push the variable into another, private, class, and then
    refer to it via a <?>-bound variable. You can then manipulate that object
    via a private generic method, which provides a local type-bound context to
    do the work in. I should warn you that this is third-level generics
    voodoo.

    Here we go:

    abstract class FunkyClass {
    private FunkyHelper<?> helper;

    protected FunkyClass(FunkyHelper<?> helper) {
    this.helper = helper;
    }
    public void calculate() {
    doCalculate(helper);
    }
    private <T> void doCalculate(FunkyHelper<T> helper) {
    helper.things.add(helper.myFunc());
    }
    }

    class IntegerFunky extends FunkyClass {
    public IntegerFunky() {
    super(new IntegerFunkyHelper());
    }
    }

    class FloatFunky extends FunkyClass {
    public FloatFunky() {
    super(new FloatFunkyHelper());
    }
    }

    abstract class FunkyHelper<T> {
    public Set<T> things;
    public abstract T myFunc();
    }

    class IntegerFunkyHelper extends FunkyHelper<Integer> {
    public Integer myFunc() {
    return 1;
    }
    }

    class FloatFunkyHelper extends FunkyHelper<Float> {
    public Float myFunc() {
    return 1.0f;
    }
    }

    Study and be enlightened.

    tom

    --
    I am become Life, destroyer of worlds
     
    Tom Anderson, May 18, 2009
    #18
  19. Roedy Green Guest

    On Sun, 17 May 2009 11:33:02 -0700 (PDT), wrote,
    quoted or indirectly quoted someone who said :

    >
    >Is there a way to do this, or am I pretty much stuck reimplementing
    >lots of functionality in each subclass?


    this sort of problem is sometimes solved with a set of has-a functions
    rather than is-a.

    You provide the functionality via a delegate object referred to by the
    class. Think of it as hiring specialised servants rather that doing
    all the work yourself.

    see http://mindprod.com/jgloss/callback.html
    http://mindprod.com/jgloss/delegate.html
    http://mindprod.com/jgloss/isa.html
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "It wasn’t the Exxon Valdez captain’s driving that caused the Alaskan oil spill. It was yours."
    ~ Greenpeace advertisement New York Times 1990-02-25
     
    Roedy Green, May 18, 2009
    #19
    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. DaKoadMunky
    Replies:
    4
    Views:
    552
    Lee Weiner
    Apr 20, 2004
  2. Sameer
    Replies:
    4
    Views:
    603
    Roedy Green
    Aug 31, 2005
  3. Manuel
    Replies:
    8
    Views:
    639
    Manuel
    Jan 5, 2006
  4. Replies:
    4
    Views:
    816
    Rolf Magnus
    May 17, 2006
  5. Replies:
    3
    Views:
    818
Loading...

Share This Page