But it does not address the issue if the base class implementation needs to change (for example a method that is implemented at the base class level). Why this principle does not address that?
Il punto di tenerlo aperto all'estensione è evitare di dover apportare tale modifica diretta.
La modifica diretta è sempre possibile ma può comportare costi significativi. L'OCP ti chiede di iniziare con un progetto che, si spera, eviti la necessità di modifiche dirette, ed è un costo, poiché i requisiti cambiano.
Un design che consente una sostituzione polimorfica del comportamento offensivo significa che non è necessario toccare il codice che si desidera modificare. Devi solo scrivere un nuovo codice.
Ciò significa che se trovi che DEVI cambiare l'implementazione della classe base, hai già fallito nel seguire l'OCP. Dovresti aver usato un design che avrebbe permesso che quell'implementazione fosse sostituita con un altro codice scritto da qualche altra parte.
Ci sono molti modi per farlo. Il polimorfismo si presenta in molte forme. Ereditarietà, composizione e delega, wrapper, si va avanti e avanti. Ognuno di questi può evitare di vedere l'implementazione del codice base chiamata.
Se scrivi codice che accede direttamente a questa implementazione in un modo che non dà a nessuno la possibilità di sostituirlo con altre implementazioni, hai violato l'OCP prima della modifica. Non farlo se non sei assolutamente sicuro che l'implementazione non avrà mai bisogno di cambiare o che sei disposto ad assumerti i costi di apportare modifiche dirette alla implementazione.
Non è che il principio non affronti la necessità di cambiare direttamente l'implementazione della classe base. Ti dice espressamente di evitare di creare una necessità per farlo.