Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java inheritance vs initialization

I'm reading J. Bloch's Effective Java and now I'm at inheritance vs composition section. As far as I understood he said that inheritance is not always good.

A related cause of fragility in subclasses is that their superclass can acquire new methods in subsequent releases. Suppose a program depends for its security on the fact that all elements inserted into some collection satisfy some predicate. This can be guaranteed by subclassing the collection and overriding each method capable of adding an element to ensure that the predicate is satisfied before adding the element. This works fine until a new method capable of inserting an element is added to the superclass in a subsequent release.

But why doesn't it work? The superclass is just the Collection interface and if we add a new method we just a compile-time error. That's not harmful ever...

like image 634
St.Antario Avatar asked Jun 26 '15 14:06

St.Antario


People also ask

Can we inherit initializer in Java?

Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass. In the same way,you cannot inherit static block . Static initialzier blocks are not inherited .

What is Java initialization?

Initialization: Initialization is when we put a value in a variable, this happens while we declare a variable. Example: int x = 7; , String myName = "Emi"; , Boolean myCondition = false; Assignment: Assignment is when we already declared or initialized a variable, and we are changing the value.

What are the two types of initialization in Java?

Java offers two types of initializers, static and instance initializers.

Can we use constructor in inheritance?

No, constructors cannot be inherited in Java. In inheritance sub class inherits the members of a super class except constructors. In other words, constructors cannot be inherited in Java therefore, there is no need to write final before constructors.


2 Answers

Suppose you have a Collection superclass in some library v1.0:

public class MyCollection {
    public void add(String s) {
        // add to inner array
    }
}

You subclass it in order to only accept Strings that have length 5:

public class LimitedLengthCollection extends MyCollection {
    @Override
    public void add(String s) {
        if (s.length() == 5) {
            super.add(s);
        }
    }
}

The contract, the invariant of this class is that it will never contain a String that doesn't have length 5.

Now version 2.0 of the library is released, and you start using it. The base class is modified to:

public class MyCollection {
    public void add(String s) {
        // add to inner array
    }

    public void addMany(String[] s) {
        // iterate on each element and add it to inner array
    }
}

and your subclass is left unmodified. Now users of your subclass can do

LimitedLengthCollection c = new LimitedLengthCollection();
c.addMany(new String[] {"a", "b", "c"});

and the contract of your subclass is thus broken. It was supposed to only accept Strings of length 5, and it doesn't anymore, because an additional method has been added in the superclass.

like image 194
JB Nizet Avatar answered Nov 09 '22 05:11

JB Nizet


The problem is not that inheritance could not work.

The problem is that with inheritance the developer can not enforce some behaviour (like the example of the collection that satisfy some predicate) .

When we create a new class rarely it really is a specialized type of another. More often it is something new that use other classes.

So rarely we need inheritance and more often we need to create a class that use other classes to so something.

The IS A vs HAS A

You have to ask yourself:

Class B IS A new sub type of Class A that do the same things of A in different ways ?

or

Class B HAS A class inside to do something different from what A is intented to do ?

And know that more often the right answer the latter.

like image 24
frhack Avatar answered Nov 09 '22 05:11

frhack