简体   繁体   中英

reuse methods through immutable inheritance

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 ?

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.

eg

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.

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.

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM