Abstraction in object-oriented programming
Tutorial
·
foundational
·
+10XP
·
20 mins
·
(188)
Unity Technologies

In this tutorial, you’ll learn about the first pillar of object-oriented programming: Abstraction.
By the end of this tutorial, you will be able to:
- Explain how abstraction is used to expose only necessary script components
- Expose only the important details of an object by correctly recognizing opportunities to implement abstraction
Languages available:
1. Overview
We are ready to work through our existing code and improve it without changing its external functionality — a process called refactoring. Refactoring is an important step in the development process, in which you can clean up any messy code you wrote earlier, and also reexamine the ways your code will be used in future iterations of the project. In other words, in the development phase you wrote code that “works well for now,” and in the refactoring phase you will revise the code to “work well later.”
In the last mission, we introduced the concept of object-oriented programming, and throughout the Junior Programmer Pathway you’ve been implementing some of its best practices. Now, you’ll examine each of the principal pillars (abstraction, inheritance, polymorphism, and encapsulation) in depth, and use the paradigm as guidance to effectively refactor your code, beginning with abstraction.
As you work through this final mission, you’ll continue refining the inventory project that you built in the previous mission.
2. What is Abstraction?

The first pillar of OOP is all about keeping your code clean and simple for the programmer using it, whether that is you or someone else. Abstraction is the process of removing complex code from the scripts where other programmers will see it, and only exposing the functionality other programmers really need. When you “abstract out” the details, you reduce duplicate code and provide easy access to the most useful functions. You’re actually already quite familiar with this pillar, because you’ve benefited from it frequently throughout this pathway. Whenever you call on a method to perform a task rather than writing out all of the code by hand, you’re benefiting from abstraction!
Let’s take a look at a situation where you already used abstraction. During Create with Code. In Unit 4 - Gameplay Mechanics, you created some functionality to spawn an enemy wave.

When you initially wrote the code, you put it in the Start method:
Since Start only runs once when the game loads, if you wanted to spawn another enemy wave, you’d have to paste that line of code elsewhere in your script where you wanted it to occur. Having to constantly rewrite (or copy and paste) the same lines of code over and over is inefficient and prone to error. It also means that later refactoring becomes difficult, as you have to search throughout all of your scripts and rewrite all the references over again.
Instead, you separated out the spawning functionality into its own method, and called that on Start:
You created a higher-level, more “abstract” function called SpawnEnemyWave. You were then able to spawn enemies anywhere in your script from a single line of code. And, if you needed to refactor it later, you could do it in a single location. Additionally, you and your fellow programmers no longer need to worry about the specifics about how the enemies are being spawned. All that matters is the more abstract concept: if you call SpawnEnemyWave(), they will be spawned.
Your experience with abstraction isn’t limited to methods of your own creation. In fact, you’ve been benefiting from abstraction every time you call on a method built into Unity:
Adding force to a RigidBody involves a great deal of mathematics interacting with the physics system. However, since Unity has provided you with this simple “abstract,” high-level function (AddForce), you need only call the AddForce method, and give it the parameters that are relevant to your needs. You don’t even need to understand Unity physics to successfully add force to your object!
3. Abstraction and script refactoring
Remember that an important part of refactoring code is to improve its functionality without changing the way that other programmers interact with it. Abstraction plays a key role in this! As long as the method call and output doesn’t change, you can adjust the contents of the method without the other programmer ever knowing. This means that you can safely refactor your code without risk of breaking anything elsewhere in your project.
Let’s look at a simple example:
In the above method, the calling script passes in an integer and gets an output that’s been tripled. The approach to get the output number is a little ineffective, so you could refactor the code to look like the following
Even though the content of the method has been rewritten, the way the method is called remains exactly the same, as does what gets returned. Therefore, any call to the method throughout the project will continue to work.
4. Implementing abstraction in the project
Let’s implement the abstraction principles we just learned by refactoring UserControl in the inventory project. All of the functionality involved with selecting the Forklift and moving it to the desired resource is in the Update method. But what if, later on, we want other factors to be able to control these selections and actions? Let’s abstract that functionality out into two new methods to make that possible.
1. If needed, open the Inventory project from the previous mission.
2. Locate the UserControl script in the Scripts folder and open it in Visual Studio.
3. Above Update, define two new public methods with no returns and name them HandleSelection and HandleAction.
HandleSelection will manage everything that occurs when the user left-clicks one of the Forklifts in the application. We’ll still need to check for the left mouse button (Input.GetMouseButtonDown(0)) in Update, but everything else will be moved to our new method.
4. In the Update method, select the contents of the if(Input.GetMouseButtonDown()) statement and move it to HandleSelection.
5. In the if(Input.GetmouseButtonDown()) statement, call HandleSelection();
Now let’s repeat this process for HandleAction().
6. In Update, locate the else if (m_Selected != null && Input.GetMouseButtonDown(1)) statement, and move its contents to HandleAction().
7. In the else if (m_Selected != null && Input.GetMouseButtonDown(1)) statement, call HandleAction().
8. Save the script and return to Unity and playtest the scene.
The functionality shouldn’t have changed: you should be able to left-click on a Forklift and right-click on a resource pile, and the Forklift should transport resources exactly as before. The difference now is that if you or any other programmer needs this functionality elsewhere in the application later, it’s more freely available.
5. Summary
Abstraction simplifies your code and keeps it clean, making it easier for programmers to use. The core tenet of abstraction is to hide unnecessary complexity from the other programmers, and only expose what is needed to make the code run as it’s meant to. It means taking the complex inner workings and replacing them with abstract, more reusable pieces of code. Following this principle also simplifies the process of refactoring later. Now that you’ve learned how to apply abstraction to the inventory project, think about how you might be able to apply it to your own applications, or even try to do it!