Skip to main content
Changes in response to Deduplicator's comment
Source Link
eigensheep
  • 448
  • 4
  • 6

Inheritance BreaksWeakens Encapsulation

When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Specifically, insteadEach overrideable method could be replaced and so should be thought of justas callback provided to the constructor. The implementation provided by your public methods being publicclass is merely the default value of the callback. Thus, allsome kind of your calls to your public methodscontract should be provided indicating what the expectations on the method are public. HereThis seldom happens and is a major reason why object oriented code is called brittle.

Below is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).

Public Class HashTable{
    ...
    Public Object put(K key, V value){
        try{
            //add object to table;
        }catch(TableFullException e){
            increaseTableSize();
            put(key,value);
        }
    }
}

So what happens if we subclass this?

/** A version of Hashtable that lets you do
 * table.put("dog", "canine");, and then have
 * table.get("dogs") return "canine". **/

public class HashtableWithPlurals extends Hashtable {

    /** Make the table map both key and key + "s" to value. **/
    public Object put(Object key, Object value) {
        super.put(key + "s", value);
        return super.put(key, value);
    }
}

We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.

Note that this is not a problem with recursion, this can happen any time that a class calls one of its own public methods. In reality, there may well be several levels of inheritance involved in the problem.

This can be resolved by committing to not call the public methods of a class in that class. In practice, this commitment is frequently not honoured and is a major reason why object oriented code is considered "brittle".

Inheritance Breaks Extensibility

If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.

When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.

Inheritance Breaks Encapsulation

When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Specifically, instead of just your public methods being public, all of your calls to your public methods are public. Here is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).

Public Class HashTable{
    ...
    Public Object put(K key, V value){
        try{
            //add object to table;
        }catch(TableFullException e){
            increaseTableSize();
            put(key,value);
        }
    }
}

So what happens if we subclass this?

/** A version of Hashtable that lets you do
 * table.put("dog", "canine");, and then have
 * table.get("dogs") return "canine". **/

public class HashtableWithPlurals extends Hashtable {

    /** Make the table map both key and key + "s" to value. **/
    public Object put(Object key, Object value) {
        super.put(key + "s", value);
        return super.put(key, value);
    }
}

We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.

Note that this is not a problem with recursion, this can happen any time that a class calls one of its own public methods. In reality, there may well be several levels of inheritance involved in the problem.

This can be resolved by committing to not call the public methods of a class in that class. In practice, this commitment is frequently not honoured and is a major reason why object oriented code is considered "brittle".

Inheritance Breaks Extensibility

If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.

When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.

Inheritance Weakens Encapsulation

When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Each overrideable method could be replaced and so should be thought of as callback provided to the constructor. The implementation provided by your class is merely the default value of the callback. Thus, some kind of contract should be provided indicating what the expectations on the method are. This seldom happens and is a major reason why object oriented code is called brittle.

Below is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).

Public Class HashTable{
    ...
    Public Object put(K key, V value){
        try{
            //add object to table;
        }catch(TableFullException e){
            increaseTableSize();
            put(key,value);
        }
    }
}

So what happens if we subclass this?

/** A version of Hashtable that lets you do
 * table.put("dog", "canine");, and then have
 * table.get("dogs") return "canine". **/

public class HashtableWithPlurals extends Hashtable {

    /** Make the table map both key and key + "s" to value. **/
    public Object put(Object key, Object value) {
        super.put(key + "s", value);
        return super.put(key, value);
    }
}

We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.

Inheritance Breaks Extensibility

If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.

When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.

fixed code indentation
Source Link
eigensheep
  • 448
  • 4
  • 6

Inheritance Breaks Encapsulation

When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Specifically, instead of just your public methods being public, all of your calls to your public methods are public. Here is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).

Public Class HashTable{
    ...
    Public Object put(K key, V value){
        try{
            //add object to table;
        }catch(TableFullException e){
            increaseTableSize();
            put(key,value);
        }
    }
}

So what happens if we subclass this?

/** A version of Hashtable that lets you do
 * table.put("dog", "canine");, and then have
 * table.get("dogs") return "canine". **/

public class HashtableWithPlurals extends Hashtable {

    /** Make the table map both key and key + "s" to value. **/
    public Object put(Object key, Object value) {
        super.put(key + "s", value);
        return super.put(key, value);
    }
}

We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.

Note that this is not a problem with recursion, this can happen any time that a class calls one of its own public methods. In reality, there may well be several levels of inheritance involved in the problem.

This can be resolved by committing to not call the public methods of a class in that class. In practice, this commitment is frequently not honoured and is a major reason why object oriented code is considered "brittle".

Inheritance Breaks Extensibility

If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.

When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.

Inheritance Breaks Encapsulation

When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Specifically, instead of just your public methods being public, all of your calls to your public methods are public. Here is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).

Public Class HashTable{
    ...
    Public Object put(K key, V value){
        try{
            //add object to table;
        }catch(TableFullException e){
            increaseTableSize();
            put(key,value);
        }
    }
}

So what happens if we subclass this?

/** A version of Hashtable that lets you do
 * table.put("dog", "canine");, and then have
 * table.get("dogs") return "canine". **/

public class HashtableWithPlurals extends Hashtable {

    /** Make the table map both key and key + "s" to value. **/
    public Object put(Object key, Object value) {
        super.put(key + "s", value);
      return super.put(key, value);
    }
}

We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.

Note that this is not a problem with recursion, this can happen any time that a class calls one of its own public methods. In reality, there may well be several levels of inheritance involved in the problem.

This can be resolved by committing to not call the public methods of a class in that class. In practice, this commitment is frequently not honoured and is a major reason why object oriented code is considered "brittle".

Inheritance Breaks Extensibility

If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.

When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.

Inheritance Breaks Encapsulation

When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Specifically, instead of just your public methods being public, all of your calls to your public methods are public. Here is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).

Public Class HashTable{
    ...
    Public Object put(K key, V value){
        try{
            //add object to table;
        }catch(TableFullException e){
            increaseTableSize();
            put(key,value);
        }
    }
}

So what happens if we subclass this?

/** A version of Hashtable that lets you do
 * table.put("dog", "canine");, and then have
 * table.get("dogs") return "canine". **/

public class HashtableWithPlurals extends Hashtable {

    /** Make the table map both key and key + "s" to value. **/
    public Object put(Object key, Object value) {
        super.put(key + "s", value);
        return super.put(key, value);
    }
}

We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.

Note that this is not a problem with recursion, this can happen any time that a class calls one of its own public methods. In reality, there may well be several levels of inheritance involved in the problem.

This can be resolved by committing to not call the public methods of a class in that class. In practice, this commitment is frequently not honoured and is a major reason why object oriented code is considered "brittle".

Inheritance Breaks Extensibility

If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.

When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.

Source Link
eigensheep
  • 448
  • 4
  • 6

Inheritance Breaks Encapsulation

When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Specifically, instead of just your public methods being public, all of your calls to your public methods are public. Here is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).

Public Class HashTable{
    ...
    Public Object put(K key, V value){
        try{
            //add object to table;
        }catch(TableFullException e){
            increaseTableSize();
            put(key,value);
        }
    }
}

So what happens if we subclass this?

/** A version of Hashtable that lets you do
 * table.put("dog", "canine");, and then have
 * table.get("dogs") return "canine". **/

public class HashtableWithPlurals extends Hashtable {

    /** Make the table map both key and key + "s" to value. **/
    public Object put(Object key, Object value) {
        super.put(key + "s", value);
      return super.put(key, value);
    }
}

We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.

Note that this is not a problem with recursion, this can happen any time that a class calls one of its own public methods. In reality, there may well be several levels of inheritance involved in the problem.

This can be resolved by committing to not call the public methods of a class in that class. In practice, this commitment is frequently not honoured and is a major reason why object oriented code is considered "brittle".

Inheritance Breaks Extensibility

If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.

When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.