Question

In Java, is it possible to override member data in a subclass and have that overridden version be the data used in a super class's implementation?

In other words, here's what I am trying to get to happen, and it's not happening:

abstract public class BasicStuff {
        protected String[] stuff = { "Pizza", "Shoes" };

        public void readStuff() {
                for(String p : stuff) { 
                        system.out.println(p); 
                }
        }
}

..

public class HardStuff extends BasicStuff {
        protected String[] stuff = { "Harmonica", "Saxophone", "Particle Accelerator" };
}

This invocation:

HardStuff sf = new HardStuff();
sf.readStuff();

... prints Pizza and Shoes. I want it to print the latter instead.

I recognise that this is rather poor hierarchical OO practice; I needed it for a very specific case as I am doing something with XML configuration and reflection.

Is there a modifier that can make this happen?

And yes, I do recognise that there are wrappers one can use to get around this problem in my subclass, i.e. by indicating that the contents of stuff[] are now stored in an array with a different name, for instance. I'm just trying to keep this simple, and am curious in principle.

Thanks a lot in advance!

Was it helpful?

Solution

I believe you must interpose an accessor method, i.e., use:

    for(String p : getStuff()) { 

in the superclass, and add:

    protected String[] getStuff() { return stuff; }

wherever you have a protected String[] stuff redefinition.

Overriding really applies to methods, not data (at least, that is so in the Java model; some other languages do things differently), and so to get the override effect you must interpose a method (typically a dirt-simple accessor, like here). It doesn't really complicate things at all, it's just a very simple way to instruct the Java compiler to use, intrinsically, the "extra level of indirection" that your desired behavior requires.

OTHER TIPS

This way you are hiding the parent variable stuff with the defined stuff.

Try giving value to stuff in the initialization block (or in the constructor):

abstract public class BasicStuff {
  protected String[] stuff;

  {
    stuff = new String[] { "Pizza", "Shoes" };
  }

  public void readStuff() {
    for(String p : stuff) { 
      System.out.println(p); 
    }
  }
}

..

public class HardStuff extends BasicStuff {
  {
    stuff = new String[] { "Harmonica", "Saxophone", "Particle Accelerator" };
  }
}

If you want to print the array of the String Stuff defined in derived class then you need to override the method readStuff in the class HardStuff by redefining the method in the class HardStuff. As the method readStuff was defined in the abstract class BasicStuff, hence it would only print the members of the class BasicStuff. Hence, add the same method in the derieved class too. Below you can find the complete code..

class BasicStuff {
    protected String[] stuff = { "Pizza", "Shoes" };

    public void readStuff() {
            for(String p : stuff) { 
                    System.out.println(p); 
            }
    }
}


public class HardStuff extends BasicStuff {
    protected String[] stuff = 
              { "Harmonica", 
                "Saxophone", 
                "Particle Accelerator" 
              };

    public void readStuff() {
            for(String p : stuff) { 
                    System.out.println(p); 
            }
    }
    public static void main(String []arg)
    {
     HardStuff sf = new HardStuff();
        sf.readStuff();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top