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?

3
  • 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? Commented Sep 3, 2015 at 17:00
  • @MilanMilanov: To make IPAddress and PhysicalAddress immutable Commented Sep 4, 2015 at 9: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. Commented Sep 4, 2015 at 14:26

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I like your answer but in your add method you're not actually adding ItemInterface items to the List, you're adding Objects
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.
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?

2 Comments

But the question is, how can I implement the add method?
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.
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.

1 Comment

But the question is, how can I implement the add method?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.