The primary drive behind the open/close principle was to avoid having to update programs that used a library when changes were made to that library. Or, in other words, to enforce backward compatibility for old programs that used a library.
By not modifying the object (the close half) any code that uses the object according to the documented API, will always work.
By allowing extension of the object (the open half) new features, data, methods, etc., can be added to the functionality of the object to handle new uses for the object, or its subclasses.
Combining both means that the existing object, that almost fits the needs, can be enhanced to be useful in a new program, and still be used by the old programs, without needing to recode the old programs.
A common API that most high school students are familiar with is the telephone. It is going to be a very rare high school student who has never used a push-button telephone, including the "buttons" on the screen of a smart phone. So it is something that's well within the prior experience for those students.
The twelve standard buttons on the push-button telephone haven't been changed since the Western Electric model 2500 was introduced in 1968. The latest model smart phone still uses the same layout, and it still works the same (from the user's perspective), even if it's now a touch-sensitive screen rather than twelve physical buttons. They way on made a phone call in 1968 using a push-button phone, and they way one makes a phone call now with a smart phone is the same. It has not been modified. What you can do with those same twelve buttons, or simulated buttons on the smart phone, has been greatly extended. Sending text messages is only one change of many. There's no guessing what else those buttons might be extended to do, using new methods or new data. No matter what new extensions are added, the original will not be modified.