1

If I have an AddressBook to store Items:

public class AddressBook {

    public void add(Item item) {
       ...
    }

}

And an immutable IPAddress

public final class IPAddress {}

And an immutable PhysicalAddress

public final class PhysicalAddress {}

And the potential parent class Item

public final class Item {}

Since immutable objects wouldn't be able to extend the immutable class Item, how could I reuse the add method in AddressBook class for either an IPAddress or a PhysicalAddress?

Hooli
  • 1,135
  • 3
  • 19
  • 46
  • Why do you want your `Item` class to be final (meaning it cannot be inherited from) when you clearly want it to be the parent of `IPAddress` and `PhysicalAddress`? – Milan Milanov Sep 03 '15 at 17:00
  • @MilanMilanov: To make `IPAddress` and `PhysicalAddress` immutable – Hooli Sep 04 '15 at 09:24
  • You can make `IPAddress` and `PhysicalAddress` final (part of being immutable, although not enough on its own) while `Item` can be either an abstract class or an interface. Both methods will work and which one you choose depends on your situation. – Milan Milanov Sep 04 '15 at 14:26

3 Answers3

2

First of all you need to be aware that a "final class" in Java does not mean immutable, it means "un-inheritable". Immutability using "final" keyword only works for variables (and only after you set their initial value).

If you want Item to be un-inheritable (final class) and you also want IPAddress and PhysicalAdress to be final as well, you can use interfaces. (Edit: it's not a requirement for those two classes to be final, just wanted to note that you can keep them final if you actually need to, although as others have commented you should really be sure that you need it to be final).

You could change Item to be an interface and make IPAddress and PhysicalAddress implement that interface.

This way AdressBook actually adds objects of type "ItemInterface" (bad mnemonic but you get the idea) and as long as you manage to abstract common operations for all Items, you can use the interfaces instead of inheritance.

e.g.

public interface ItemInterface{
    public Object getItemValue();
    public void setItemValue(Object value);
}

public final class IPAddress implements ItemInterface{
    @Override
    public Object getItemValue(){
       ...
    }
    @Override
    public void setItemValue(Object value){
       ...
    }
}

and then you can do:

public class AddressBook {

    public void add(ItemInterface item) {
        itemsList.add(item);
        // or whatever other structure you use to store items
    }
}

In general as you develop more and more complex code it becomes more useful to program to an interface than try to keep using inheritance.

This way, whenever you need to add another type of entry to your AddressBook, you can make it implement ItemInterface and ideally you won't have to change a line inside AddressBook because everything is an ItemInterface.

Acapulco
  • 3,373
  • 8
  • 38
  • 51
  • 1
    I like your answer but in your `add` method you're not actually adding `ItemInterface` items to the `List`, you're adding `Objects` – Hooli Sep 04 '15 at 09:27
  • Yeah, you are right. My mistake. I'll change that. But you get the idea. Instead of finding out what to inherit, you can just implement a common interface and use that instead. – Acapulco Sep 04 '15 at 13:34
0

I think, that you probably mixed up immutable and final class

Immutable object means, that it cannot be changed, after it's creation. see https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

True is, that final class cannot be inherted. If you really want inherit class it cannot be final.

But the point is, that immutable class does NOT have to be final.

bugs_
  • 3,544
  • 4
  • 34
  • 39
0

Marking a class as final means that it cannot be extended. That basically means that you think the class is perfect and no one will ever need (or be able) to extend it or override any of its behaviour in a more specific subclass.

Generally speaking, you should avoid using final classes unless you have a very good reason to use them.

Because you cannot extend a final class, it can never be used in anywhere in an inheritance hierarchy except at the very bottom.

Are you sure you actually wanted to make your classes final?

Nameless Voice
  • 461
  • 2
  • 9
  • But the question is, how can I implement the `add` method? – Hooli Sep 04 '15 at 09:18
  • By fixing your hierarchy, so that Item is not final and then making IPAddress and PhysicalAddress extend that class. You might also want to make Item an interface if it has no code for the other two classes to inherit / reuse. – Nameless Voice Sep 04 '15 at 15:52