2

I have a method which adds Objects to an static list like this:

@PostConstruct
protected void registerToTransactionList() {
    TransactionValidator.registerTransactionList(this);
}

registerTransactionList method just adds "this" to the static list, this method is in BalanceTransactionValidator class which extends TransactionValidator (owner of static list),the problem is all subclasses of BalanceTransactionValidator class are added to static list either,and if I override registerToTransactionList method in them like this:

@Override
@PostConstruct
protected void registerToTransactionList() {
}

It doesn't add subclasses but doesn't add BalanceTransactionValidator either. Can anybody help me on this? Please notice sublasses are overriding this method by default.

Nazila
  • 1,353
  • 4
  • 15
  • 28
  • And for the record: the code you are showing is not adding **classes**. It is adding "this" objects. If it would be really about classes, the code would be like "this.getClass()" or something alike! – GhostCat Oct 10 '16 at 08:10
  • you are right my mistake I edited – Nazila Oct 10 '16 at 08:18

2 Answers2

1

make the method private to block the visibility

private void registerToTransactionList() {
}

or make the method final to block it from been override

protected final void registerToTransactionList() {
}
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
1

There are two ways of achieving that:

  1. Keep your method as it is; but then you have to actively check for the type of your objects before externally calling that method
  2. Change your whole logic and make that method private

It won't help to make the method final as suggested in one of the comments - your problem is not that subclasses are overwriting that method; in essence, you have a design problem: you wish that subclasses should not invoke that method at all.

So, the only real option that makes sense here is "2.". You see, by having public method on a class that you want to be extended you are implicitly saying: it is perfectly fine to call that method; on any object that is instance of the base class (or child class!).

And in your case, that is not true: you actually do not want that the code behind this method runs for child classes. Then you shouldn't put that method in the list of public/protected methods of your base class!

Finally: you might want to step back and do some reading about good OO design. Class hierarchies do not fall from the sky: you willfully design them for a certain purpose. In other words: there is more to inheritance than just putting some "A extends B" on your class declaration. You have to understand each and every method on your B class; and how your child classes should deal with them!

EDIT: after some more thinking, I guess you are doing things "the wrong way", like:

class BaseClass {

  public final void doRegistration() {
    BaseClass toRegister = getObjectForRegistration();
    if (toRegister != null) { ... register  toRegister ...
  }

  protected BaseClass getObjectForRegistration() {
     return null;
  }

With that code, you could then put

 protected BaseClass getObjectForRegistration() {
    if (this instanceof ClassThatShouldBeRegistered) {
      return this;
    } 
    return null;
 }

into that one class that wants to be registered. Probably there could be even nicer ways of doing so; but after some thinking I don't see how we could avoid the instanceof. But the above code should work; and it only requires specific code only in your base class and in that one class that wants to register something.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • I forgot to add that even making method private doesn't help still all subclasses are added to list – Nazila Oct 10 '16 at 08:12
  • I updated my answer to give some hints there. Hope that helps. – GhostCat Oct 10 '16 at 08:23
  • I have tried this and yet not working for me I don't know why,It is logically true but not working – Nazila Oct 10 '16 at 08:32
  • Then you probably did something wrong. We cant help with code that we dont see. In that sense: rework your question; put in a **minimal** viable example that shows your problem. You have a lot of **descriptions** in your question; you should replace them with *code*, because descriptions always imply *interpretation*, and I guess: your code is wrong, you interpret that the wrong way, and thus you come to wrong conclusions. – GhostCat Oct 10 '16 at 08:36