comparison of protected members vs abstract classes

Discussion in 'Java' started by Sideswipe, Sep 12, 2007.

  1. Sideswipe

    Sideswipe Guest

    I often debate to myself the best approach to an inheritance
    implementation problem.

    Say I have a abstract base class that does all the heavy lifting for a
    task. The only thing subclasses need do is fill in some blanks -- data
    blanks not functional.

    3 ways I know of doing it are:

    1) create a constructor in the parent and pass it up the stack

    public MySubclass(Int x,String y) {
    super(x,y);
    }

    pro -- less subclass code. super.x and super.y are unmodifiable by the
    subclass
    con -- creates a rigid constructor dependency between parent and
    child. Multiple constructors become difficult to maintain

    2) use protected member objects set during construction.

    public MySubClass(int x,String y) {
    super.x = x;
    super.y = y;
    }

    pro: no dependency on parent constructor. Child constructor also gains
    added flexibility
    con: super.x and super.y are always modifiable to the child class.
    This can create bad situations with misbehaving children.

    3) Use abstract method to force child classes to give info.

    public abstract class SomeClass {
    public abstract int getX();
    public abstract String getY();
    }

    public class MySubClass extends SomeClass {

    public int getX() {return this.x;}
    public String getY() {return this.y;}
    }

    pro: no constructor dependencies, no access to raw member variable in
    parent, child may also change values anytime between calls to said
    abstract methods (data on as-needed basis)

    con: can create very repetitive code across several child classes.
    Especially when simple return values are needed.

    Experience has taught me to stay away from 1. 2 doesn't generally
    represent a problem if you are writing the super and subclasses, but
    because it leaves the door open for abuse later I generally lean
    toward the 3rd.

    I was looking for more discussion on this subject. Any thoughts?

    Christian Bongiorno
    http://christian.bongirono.org
     
    Sideswipe, Sep 12, 2007
    #1
    1. Advertising

  2. Sideswipe

    Roedy Green Guest

    On Wed, 12 Sep 2007 18:57:23 -0000, Sideswipe
    <> wrote, quoted or indirectly quoted
    someone who said :

    >I was looking for more discussion on this subject. Any thoughts?


    In the example you gave I don't see enough difference to fret over it.
    Perhaps with messier examples the difference would become obvious.

    With constructors, the specification is positional, terse, but
    confusing with a large number of parms.

    In both schemes you ensure all data is provided.

    I tend to like the abstract method approach. It gives flexibility to
    the implementor to use either constructors, constants or complex
    calculations.
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Sep 13, 2007
    #2
    1. Advertising

  3. Sideswipe

    Ed Kirwan Guest

    Sideswipe wrote:

    > I often debate to myself the best approach to an inheritance
    > implementation problem.
    >
    > Say I have a abstract base class that does all the heavy lifting for a
    > task. The only thing subclasses need do is fill in some blanks -- data
    > blanks not functional.
    >

    Snip.
    > Christian Bongiorno
    > http://christian.bongirono.org


    I know one author - H.S. Lahman - who would strongly, strongly suggest that
    if you have subclasses that only fill in the data-blanks in the base class
    then you should not have subclasses at all. Instead, you should only have
    the base class and supply the required data in its constructor.

    He claims that behaviour resides in the class invariant: which in this case
    is everything-but-the-data, and so having subclasses pretending that
    they're doing anything useful is just clutter.

    I find his writing dense but rewarding; if you're willing to give it a go:

    http://pathfinderpeople.blogs.com/hslahman/invariants_and_parametric_polymorphism/index.html

    --
    ..ed

    www.EdmundKirwan.com - Home of The Fractal Class Composition
     
    Ed Kirwan, Sep 13, 2007
    #3
  4. Sideswipe

    Sideswipe Guest

    Well, I fully admit it does give more clutter, but it also makes it
    much more clear and, OO is about Data encapsulation -- which is what
    subclasses filling in the blanks definitely is.

    Why is it clearer? Because when I am debugging I don't have to figure
    out which, of 100 different instantiations, was used to create an
    instance of the object that is behaving wrong and knowing which
    parameters were passed at runtime. The "parameters" are declared
    static inside the subclass. Because it's a method, I also have the
    ability in the subclass to intercept anytime that data is used. I
    tend to agree with the prior poster about the extra flexibility being
    worth the cluster. The potential is that these classes COULD be
    useful. Anyone with some time in the field will tell you that
    flexibility counts for a lot.

    This author says.... but, what do you think? Do you agree? Djikstra
    claimed, until his death, that OO was unnecessary and that CS student
    should be taught to formally prove their code -- there by nullifying
    the need for a highly organized language like Java. Of course, his
    fanaticism ignored that fact that provability of code requires a
    closed system where non-determinism can't be introduced through
    Network, disk io and multi-threading and, of course, silly users. To
    say nothing of the time and cost to formally prove anything.


    Christian Bongiorno
    http://christian.bongiorno.org
    > I know one author - H.S. Lahman - who would strongly, strongly suggest that
    > if you have subclasses that only fill in the data-blanks in the base class
    > then you should not have subclasses at all. Instead, you should only have
    > the base class and supply the required data in its constructor.
    >
    > He claims that behaviour resides in the class invariant: which in this case
    > is everything-but-the-data, and so having subclasses pretending that
    > they're doing anything useful is just clutter.
    >
     
    Sideswipe, Sep 13, 2007
    #4
  5. Sideswipe

    Ed Kirwan Guest

    Sideswipe wrote:

    > Well, I fully admit it does give more clutter, but it also makes it
    > much more clear and, OO is about Data encapsulation -- which is what
    > subclasses filling in the blanks definitely is.


    I tend to agree that having the extra classes is clearer than not having
    them. This clarity, however, does have its price (the extra classes
    themselves) so I suppose it depends on the problem being solved (what
    doesn't?).

    And as a slight aside, OO for me is more about encapsulating variation (be
    that behavioural or data) than pure data encapsulation. Of course, to each
    his own.

    >

    snip
    >
    > This author says.... but, what do you think? Do you agree?


    Well, as you ask, I've been trying to think of encounters I've had that are
    relevant to your question, and I think I've spotted one - but in this case,
    the classes are very simple, perhaps so much so that they bare no true
    relation to your own classes: you must be the judge. Again, I find myself
    thinking that the nature of the problem itself decides.

    Anyway, I've a little poker game that offers three different levels of
    computer opponent, called a Type 1 AI, a Type 2 AI and a Type 5 AI. The
    game's configurable via a BinaryOption class, and I've three subclasses
    called Type1AIOption, Type2AIOption and Type5AIOption that say whether a
    particular AI is allowed to play in a particular game:

    http://www.edmundkirwan.com/servlet/fractal/cs1/code/package123.html

    http://www.edmundkirwan.com/servlet/fractal/cs1/code/package124.html

    http://www.edmundkirwan.com/servlet/fractal/cs1/code/package125.html

    All these subclasses just assign variables in the base BinaryOption class
    and contain no behaviour of their own.

    I think, however, that Mister Lahman's advice has rubbed off onto me,
    because in my current project I also use BinaryOption, and I presently have
    six binary options, but I don't create six subclasses; instead, I pass the
    parameters into the constructor of a, "Raw," BinaryOption:

    /**
    * Create the system options.
    */
    private void addAllOptions() {
    options.add(new AlgorithmOption());
    createBinaryOption(Configuration.DELETE_ORIGINAL_OPTION_NAME,
    false, Configuration.MISCELLANEOUS_GROUP);
    createBinaryOption(Configuration.AUTO_CLOSE_PROGRESS_OPTION_NAME,
    false, Configuration.MISCELLANEOUS_GROUP);
    createBinaryOption(Configuration.ALLOW_REENCRYPTION_OPTION_NAME,
    false, Configuration.MISCELLANEOUS_GROUP);
    createBinaryOption(Configuration.WATERMARK_OPTION_NAME,
    true, Configuration.MISCELLANEOUS_GROUP);
    createBinaryOption(Configuration.CHECKSUM_OPTION_NAME,
    true, Configuration.MISCELLANEOUS_GROUP);
    createBinaryOption(Configuration.CBC_OPTION_NAME,
    true, Configuration.MISCELLANEOUS_GROUP);
    Option viewOption = new ViewOption();
    options.add(viewOption);
    }

    /**
    * Creates a binary option with the given name, default value, and group
    * header identity.
    *
    * @param name binary option name
    * @param value default value
    * @param groupHeaderIdentity group header identity
    */
    public void createBinaryOption(String name, boolean value,
    String groupHeaderIdentity) {
    options.add(new BinaryOption(name, value, groupHeaderIdentity));
    }

    So I'd have to say, on the whole, that I tend not to have subclasses which
    differ from base classes only by data.

    > Djikstra
    > claimed, until his death, that OO was unnecessary and that CS student
    > should be taught to formally prove their code -- there by nullifying
    > the need for a highly organized language like Java. Of course, his
    > fanaticism ignored that fact that provability of code requires a
    > closed system where non-determinism can't be introduced through
    > Network, disk io and multi-threading and, of course, silly users. To
    > say nothing of the time and cost to formally prove anything.


    I wouldn't dream of contradicting a master such as Dijkstra, but I always
    phased-out when it came to, "Predicate transformers." Some day I must look
    into modal and predicate calculus to see what on earth it's all about.

    I have often wondered, however, about the practicalities of program proofs.
    Surely there's a circular argument in there somewhere, for how to we show
    that the proof is correct?

    If a proof is a page long, then I'd be happy to have an expert tell me it's
    correct.

    If it's fifty pages long, then I'd rather have a few experts confirm it.

    If my program is one million lines long, however, how long will the proof
    be? Ten thousand lines? How many experts are needed to guarantee that this
    proof contains no errors?

    Also, looking at a Dijkstran proof, I always find it looks like a program
    itself, somehow condensed from the original. Could that proof itself be fed
    into a computer and executed? If so, has the proof just, "Compressed," the
    original program by some impressive factor (say 10, as above)? Can we ditch
    the original and just use the executable proof?

    And if we can do this, then how do we prove that the executable proof is
    proven?

    And can we make an executable proof of the executable proof that's an
    impressively compressed factor of the (first) executable proof?

    --
    ..ed

    www.EdmundKirwan.com - Home of The Fractal Class Composition
     
    Ed Kirwan, Sep 14, 2007
    #5
  6. Sideswipe

    Sideswipe Guest

    I slumped in my chair when the discussion was Lambda calculus.
    Assuming all programs could be proved, you rightly cite the costs of
    doing so. Plus, considering the kind of "engineers" I have met in my
    time, if their code didn't pass "proofing" what do you do? I mean, it
    isn't like a math test where you get a question wrong, get a 'B' and
    move on with life. I have found that, in software the 'good enough'
    model is all people want to pay for. and then they apply the 'binary'
    quality metric: Works/ doesn't work -- applying the two you get :
    (Works good enough | Doesn't work good enough)
     
    Sideswipe, Sep 20, 2007
    #6
  7. Sideswipe

    Daniel Pitts Guest

    On Sep 12, 5:28 pm, Roedy Green <>
    wrote:
    > On Wed, 12 Sep 2007 18:57:23 -0000, Sideswipe
    > <> wrote, quoted or indirectly quoted
    > someone who said :
    >
    > >I was looking for more discussion on this subject. Any thoughts?

    >
    > In the example you gave I don't see enough difference to fret over it.
    > Perhaps with messier examples the difference would become obvious.
    >
    > With constructors, the specification is positional, terse, but
    > confusing with a large number of parms.
    >
    > In both schemes you ensure all data is provided.
    >
    > I tend to like the abstract method approach. It gives flexibility to
    > the implementor to use either constructors, constants or complex
    > calculations.
    > --
    > Roedy Green Canadian Mind Products
    > The Java Glossaryhttp://mindprod.com


    If all you want is to encapsulate data, then you might consider using
    an Argument object. approach.

    final class MyNoLongerBaseClass {
    public static final class Argument {
    // necessary parameters as fields, with getters and setters
    probably.
    }

    public MyNoLongerBaseClass(Argument argument) {
    // use argument data, throw IllegalArgumentException if its not
    configured properly.
    }
    }

    >From that, you might say, Oh, why don't I just make Argument a Factory

    object, that can create my no longer base class objects. Well, the
    answer is, you should! You can still have the constructor that
    accepts the "Argument" object, but it would only be called from within
    the Argument (now called Factory) class.


    In this case, using the Builder pattern tends to be useful as well,
    allowing chaining of method calls (think StringBuilder/ProcessBuilder)

    public class MNLBBuilder {
    public MNLBBuilder someProperty(String value) {
    someProperty = value;
    return this;
    }
    // ... etc...
    }


    MNLB mnlb = new MNLBBuilder().someProperty("Foo!").createMNLB();
     
    Daniel Pitts, Sep 20, 2007
    #7
    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. Praveen
    Replies:
    1
    Views:
    387
    Woebegone
    Nov 21, 2003
  2. DaKoadMunky
    Replies:
    4
    Views:
    571
    Lee Weiner
    Apr 20, 2004
  3. Mr Dyl
    Replies:
    2
    Views:
    507
    Mr Dyl
    Dec 1, 2005
  4. aidy
    Replies:
    11
    Views:
    232
    Robert Dober
    Jul 22, 2008
  5. Kevin Prichard
    Replies:
    11
    Views:
    424
    Richard Cornford
    Nov 29, 2005
Loading...

Share This Page