Pergunta

public class SuperClass {
    public void doFoo() {
        //...
    }
}

public class SubClass extends SuperClass implements AnInterface {}

public interface AnInterface {
    public abstract void doFoo();
}

Why doesn't SubClass have to implement the doFoo() method? I guess it's because it's already in its superclass. But I can't add an @Override for the doFoo() method in SuperClass. So it is shadowed? Or what's that called? And is this a good/normal practice?

Foi útil?

Solução

Why does SubClass don't have to implement the doFoo() method?

Because it's already implemented in SuperClass.

But I can't add a @Override for the doFoo() method in SuperClass.

No you cannot, because SuperClass does not implement AnInterface. It does not override nobody's method.

So it is shadowed?

No. Shadowing is something else. It's concerns variables. So, if SuperClass has a varaible foo, and in SubClass you try define a variable with the same name, that would be shadowing. This does not have a name.

And is this a good/normal practice?

This is normal practice. I've seen it multiple times in many big projects.



TLDR Example follows:

Let's say we have an interface that is needed for implementing a ModelBasedWizard (wizard is a common thing in many desktop apps).

public interface IModelBasedWizard {

    public void addWizardPage(IWizardPage page);

    public IStatus getWizardStatus();

    public void bindModel(IModel model);
}

Let's say that there is already an implementation of a Wizard

public class Wizard {

    public void addWizardPage(IWizardPage page) {
        pages.add(page);
        page.createContent(this);
    }

    public IStatus getWizardStatus() {
        List<IStatus> stati= new ArrayList<Status>();
        for (IWizardPage page : pages) {
            stati.add(page.getStatus());
        }
        return stati;
    }
}

Now, this is just a visual part of the Wizard, but it does not know anything about the model. Okay, no problem:

public class ModelBasedWizard extends Wizard implements IModelBasedWizard {
    //UI, pages, stati and all other functionalities are already implemented.
    //I just need to bind this wizard to a model

    //create some content here

    @Override
    public void bindModel(IModel model) {
        this.model = model;
        this.fieldOne.bindToModel(model);
        model.addPropertyChangeListener(new PropertyChangeListener() {
            //bla bla
        });
    }
}

Outras dicas

Generally speaking, there is nothing wrong with what you've done. The subclass inherits the doFoo method from the parent class, thus satisfying the requirements imposed by the interface.

If you wanted your code to be overly clear (perhaps to assist in future maintenance) one option would be:

public class SubClass extends SuperClass implements AnInterface {

  @Override
  public void doFoo() {
    super.doFoo();
  }
}

I'm not sure there is a specific term for your original question. Perhaps "mildly confusing inheritance"?

This is how interfaces are used. When you implement an interface all that changes about the class is that you are required to have methods in your class that are defined by that interface.

All you have to do to make your code work is put an empty method called doFoo() in your subclass.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top