Start course

This course takes code from the Data Types and Variables course and refines it using object-oriented (OO) principles. We explore some of the main concepts of OO programming during this process, such as encapsulation, code reuse, and inheritance.

Along the way, we learn more about essential code structures such as conditional evaluation with if-then-else statements, functions for grouping code that performs a specific task, and for-loops for dynamically repeating an action. We will also look at how .NET and C# have object-oriented baked-in as a fundamental design principle underpinning the framework and language.

Learning Objectives

  • Understand the benefits of object orientation and what came before it
  • Learn about essential code structures and turn code into a class
  • Refine the class code and learn more object-oriented concepts
  • Learn about inheritance, a fundamental object-oriented concept
  • Understand how object-orientation is a foundation principle of C# and .NET

Intended Audience

This course is intended for those who already have an understanding of data types and variables in C# and now want to learn about object-oriented principles.


To get the most out of this course, you should have an understanding of C# as well as basic data types: strings, numbers, and Booleans. In order to follow along with the demos, you should also have a working development environment, whether in Windows, Linux, or macOS.


The GitHub repository for this course can be found here.



We've covered a lot of new ground, so let's go over the important takeaways. We started with one file of code that produced a 4x4 checkerboard pattern. All the code is jumbled together; tasks to perform specific actions are mixed with other tasks, so not encapsulated. Every variable is accessible to all parts of the program, with lots of code repetition, which is never a good sign, and we are stuck with a 4x4 checkerboard. 

On the road to object orientation, we segregated code into functions that performed specific tasks. PopulateCheckerRow is responsible for setting up a row, and PrintCheckers is responsible for displaying the whole board. Functions take input parameters that can be passed by value or reference, and all functions have a return type, even if it is nothing,  denoted by the keyword void. We did away with repetition in each case by using for loops to dynamically repeat actions, utilizing the loop counter variable to walk through the checkers rows and the whole array.

However, our checkerboard code is still part of the program class. Next, we created a fully self-contained board class that can exist independently of the program class. In fact, we created a new namespace to separate it from the application's namespace. A class has both data and functionality. Data can be any data type from simple numbers and text through to other classes. In the context of a class, variables are called members when they are visible to the whole class, as opposed to variables that exist only within a function – again, within the context of a class, functions are called methods. Class members have visibility denoted by the keywords private: only visible to the class they're declared in. Protected, where visibility is limited to their class and all of the class's children and public members, also known as properties that are globally accessible. Public properties can be interfaces for private members, where the value can be set or retrieved using the getter and setter syntax. Getter can be as simple as return the value, and setter can be an assignment, or both getters and setters can be replaced by functions. You can have multiple versions of a function or method with the same name, as long as they have different parameter signatures. We saw this with the multiple Board class constructors - one with no parameters and one with two integer parameters.

We used the if-then-else statement to implement column validation and ascertain the checkers array existed by testing to see if it was null. We made the board size dynamic by using variables to set the checkers array size and the upper limit of the for loops.  

Inheritance is an intrinsic part of object orientation, enabling easy and logical code reuse. We derived a chessboard class from board having the dimensions fixed at eight by overriding the public Rows and Columns properties. Then we created a chessboard object assigning it to a board data type variable demonstrating the OO parent-child relationship.


Finally, we saw how object-orientation is baked into C# and .NET with even the most fundamental data types like char and string implemented as classes. This just a tiny sample of what is in the System namespace, but it gives you a sense of available functionality and allowed us to explore more fully the concept of static classes that we touched on earlier.

About the Author
Learning Paths

Hallam is a software architect with over 20 years experience across a wide range of industries. He began his software career as a  Delphi/Interbase disciple but changed his allegiance to Microsoft with its deep and broad ecosystem. While Hallam has designed and crafted custom software utilizing web, mobile and desktop technologies, good quality reliable data is the key to a successful solution. The challenge of quickly turning data into useful information for digestion by humans and machines has led Hallam to specialize in database design and process automation. Showing customers how leverage new technology to change and improve their business processes is one of the key drivers keeping Hallam coming back to the keyboard. 

Covered Topics