As a programming instructor I am often asked: "Why do we need all these abstractions?"
A good while ago I was reading the book Code: The Hidden Language of Computer Hardware and Software (a great book I recommend and am in no way affiliated with) Which walked the reader through building a computer from the ground up. I used to think I knew how to do that because I could assemble all of the pieces of a computer such as attaching a power supply, cpu, video card, etc. to a motherboard. However this book was more about creating a computer from raw materials such as building an electromagnet using wire, iron and electricity. Then using that electromagnet to create a relay, then using several relays to build a switch, then using several switches to build a logic gate, and using several logic gates to build a circuit board.
At each step after explaining and visually showing all the pieces of a new concept. The author would abstract away that concept with a symbol such as: and use these abstractions to describe the next concept.
Without these abstractions the diagram to show a circuit board for a simple binary calculator would have been so huge it would not have been able to be printed on the page without losing details. It also would have been virtually impossible to comprehend.
However when I looked at such diagrams I tried to make all the abstractions become concrete as I mentally parsed the details. That is to say, I was trying to keep the entire machine in my head. This was getting harder and harder as more levels of abstraction were added until it finally surpassed my brain capacity.
At first I got frustrated. Then I realized what I was trying to do was unnecessary and defeated the entire purpose of the abstractions the author was making. I came to the realization that as long as I understood each level, while at that level, I did not need to concern myself with the details once they were abstracted way. For once abstracted into concepts, it is then only those concepts that matter. At that level the contents are merely implementation details.
When teaching to new programmers it is a bit ironic that these abstractions which are meant to make code easier to reason about are some of the concepts my students often find the hardest to wrap their heads around.
Just as I would look at the high level circuit board diagrams and try to internalize the lower level's inter-workings and find myself confused; I found my students were doing the same thing while they gazed into my code examples.
The uninitiated often wonder what the point is of creating classes or prototypes. There are several reasons these high level programming concepts exist but I believe the most important one is abstraction.
Without the ability to write a complex piece of code and abstract it into an easy to understand concept that can be used as a building block without considering the details, then software would quickly become too complex that no one would be able to understand it.