What is the fragile base class problem?

前端 未结 4 1548
太阳男子
太阳男子 2020-12-05 10:07

What is the fragile base class problem in java?

相关标签:
4条回答
  • 2020-12-05 10:18

    A base class is called fragile when changes made to it break a derived class.

    class Base{
        protected int x;
        protected void m(){
           x++;
        }
    
        protected void n(){
          x++;      // <- defect 
          m();
         }
     }
    
    
    class Sub extends Base{
            protected void m(){
                n();
            }
        }
    
    0 讨论(0)
  • 2020-12-05 10:19

    A fragile base class is a common problem with inheritance, which applies to Java and any other language which supports inheritance.

    In a nutshell, the base class is the class you are inheriting from, and it is often called fragile because changes to this class can have unexpected results in the classes that inherit from it.

    There are few methods of mitigating this; but no straightforward method to entirely avoid it while still using inheritance. You can prevent other classes inheriting from a class by labelling the class declaration as final in Java.

    A best practice to avoid the worst of these problems is to label all classes as final unless you are specifically intending to inherit from them. For those to intend to inherit from, design them as if you were designing an API: hide all the implementation details; be strict about what you emit and careful about what you accept, and document the expected behaviour of the class in detail.

    0 讨论(0)
  • 2020-12-05 10:34

    It is widely described in below article By Allen Holub on JavaWorld

    Why extends is evil. Improve your code by replacing concrete base classes with interfaces

    0 讨论(0)
  • 2020-12-05 10:37

    All what "Colin Pickard" has said is true , and here I want to add some of the best practices to be more protected when you are writing code that may cause this kind of issues in the Java language and especially if your are creating a framework or a library...

    1. Make all your concrete classes final by default because you may don't want them to be inherited You found this kind of behavior as feature many languages as the Kotlin langage (if you need to extend it then it's ok remove the final keyword, so it can help the reader of your code).
    2. For abstract classes, make all its implemented methods final to be not modified by its subClasses (even protected methods are a bad idea generally speaking, subClasses should'nt know so much about its subclasses)do not expose your method if they are not meant to be overriden...
    3. Try to not use a relationShip [is a] instead try to use the [uses a] relationsheap between your classes diagram use interfaces to avoid the extends problems..
    4. Remember that every extends can be replaced by implements and if you have to make a default implementation here's a code spinet:

    public interface MyBehavior {
        void doAction();
    
        static class Implementation implements MyBehavior {
            public void doAction() {
                //do some stuff
            }
        }
    }
    
    //  instead of doing extends To a class that have the doAction method
    //  we will make a [use a] relationShip between the Example class & the Implementation class
    public class Example {
        private MyBehavior.Implementation helper = new MyBehavior.Implementation();
    
        public void doAction() {
            this.helper.doAction();
        }
    }

    0 讨论(0)
提交回复
热议问题