Lesson 36 - Introduction to Classes and Objects

Tutorial Series: Free C# Fundamentals via ASP.NET Web Apps

Previous Article  |  Next Article


Get GitHub Code

In previous lessons, the topic of "classes" and "objects" has been mentioned, but not detailed. The reason for this is because this topic has to do with Object-Oriented Programming (or “OOP”), which is a shift in thinking that takes time to really understand its significance. OOP takes the basic concepts you already understand (variables, methods, scope) and separates them into a more conceptual framework; grouping one set of variables and methods in one class and grouping others in another, for example. And from those classes you can build “instances” that are bound up in a special kind of variable called an object. Those objects then work together as communities to solve problems. Objects (and therefore, classes) have a host of special properties that we have yet to see. They can inherit from other classes in order to add functionality and create a more flexible software system, as well as reducing the amount of dependency in your system. Dependency becomes a problem when one piece of code breaks, causing another piece of code that is dependent on it to break as well. Classes are an important step towards reducing dependency and allowing you to enforce the “separation of concerns” principle we spoke of earlier.

Tip:

By keeping code as separate as possible, using various object-oriented techniques, you are de-coupling dependencies within your code. Coupling is most glaring when you are debugging and start to notice how “whacking” a bug in one part of your code causes another bug to “pop up” elsewhere. And if it only happens under certain runtime conditions, you have the makings for a real coding nightmare.

Step 1: Distinguishing OOP and Procedural Programming Styles

To distinguish OOP from non-OOP you could contrast it with the style of programming we have been mostly doing up to this point which is based on a procedural style. This is an old style of programming where you work in terms of data in/data out. This style of programming typically uses carefully named variables and methods to represent data points and processes. These data points might be loosely coupled together - perhaps by some kind of naming convention - but the main distinction is that we haven’t been thinking of the data as a representative piece of a larger architecture. And beyond the problem-solving logic, we haven’t considered maintainability or how change introduced within the system will affect the existing code, such as new requirements or functionality introduced later on. We also haven’t really worried about reusability of code we've already written for use in another project.

Step 2: Why Bother Learning OOP?

In contrast to the procedural style of programming detailed above, OOP prioritizes interaction of objects throughout their creation. In other words, when we think in terms of objects that need to talk to other objects in order to accomplish a solution as a piece within a broader problem, we are putting a priority on all of these elements that procedural programming doesn’t concern itself with. This added complexity often leaves beginners wondering if this higher layer of concern – beyond just solving the problem – is worthwhile for the average programmer, especially considering that most beginning applications are actually quite simple. What you will come to learn is that the conceptual nature of OOP eventually allows you to create more complex applications without the burden of confronting their complexity upfront. OOP ultimately allows you to concern yourself less with mundane issues, instead abstracting them away into nice little bundles that you rarely have to look at and understand in full. It will allow you to focus better on individual problems that need solving, within a broader puzzle, and in the software development world there is always a broader puzzle.

Tip:

The subject of Object-Oriented-Programming is both relatively easy to pick up on and extremely deep if you want to continue pursuing it. It can take time to fully understand, and appreciate, how much it offers. Don't feel bad if you don't really understand it all the first time through. The best way to look at learning OOP is its return on time investment: the relatively modest amount of extra time you put in now to learn its secrets pales in comparison to the time you gain back when using it to build robust and extensible applications. Just keep working through the examples over the next few lessons and you will eventually start seeing the world of code around you as made up of objects.

Step 3: You’ve Already Been Doing OOP without Realizing It

Virtually everything in C# - including the part of the .NET Framework that deals with ASP.NET functionality – is either a class, or part of a class. In all of the previous lessons, we have been using ASP.NET Web Forms with a Default.aspx file. What you may not have realized is we were just creating a class definition – a set of methods and properties for a class - in that file.


cs-asp-036---introduction-to-classes-and-objects.004


What you haven’t yet seen is that the ASP.NET Runtime will create an instance of this Default class whenever the user requests it over the internet. Once it creates an instance of that class, it will begin calling methods or setting/retrieving properties of that class. Part of that process is being determined by what you write in the code for this Default class. In case you are wondering, the ultimate responsibility for this class is to generate HTML that represents a webpage called “default.”

The purpose of this lesson and the next few lessons is simply to understand classes and their ubiquity when working with C#.

Step 4: Create a New Project

For this lesson, suppose that you wanted to create an application that works with cars in some way. You may have a car lot with an inventory of all the cars that are for sale, or you may want to keep related information about a single car in one container. That container can be created using a class, and allows you to keep all of this related information that represents a car within the class.

Begin by creating a new ASP.NET project with a single Server Control resultLabel:


cs-asp-036---introduction-to-classes-and-objects.005


In Default.aspx.cs, create a new class called Car alongside the Default class, keeping both classes within the broader “CS-ASP_036” namespace:


cs-asp-036---introduction-to-classes-and-objects.006


Step 5: Methods and Properties as Class Members

What we’re doing here is naming a code-block (“Car”) similar to how methods are named blocks of code that perform some particular process, we can later reference classes as we do with any variable or method, setting or retrieving their properties. Within this code block, we have two basic “members” that immediately belong to it and those members are typically variables (properties) and methods. Class-level properties are much like any variable we have worked with thus far, but are usually meant to describe attributes common to that object’s class. For example, a car is typically defined by properties such as:

  • Make

  • Model

  • Year Built

  • Color

Class-level methods also define something about the class, and that is what the class can do (tasks, processes, behaviors, actions, and so on). A car can among other things do things such as:

  • Accelerate

  • Decelerate

Step 6: Understanding Properties

In this sense, classes often are created to model - insofar as it’s important to the functioning of our application - the behavior and physical properties of their real-world counterparts. Let’s start off by adding the following properties to this class:


cs-asp-036---introduction-to-classes-and-objects.007


Notice that these are just like ordinary variables – with a type, and an identifier – except for the accessibility prefix (in this case, public) as well as the get; and set; postfix, which can be seen as the read/write attributes. You can access the code snippet for this by typing in “prop” and hitting the tab key twice:


cs-asp-036---introduction-to-classes-and-objects.008


Step 7: Objects as Class Instances

Now, to create an instance or actual object of our car in code we can do so by referencing the class as we do any variable type:


cs-asp-036---introduction-to-classes-and-objects.009


By creating an instance of the class we’ve defined, you can look at it like the class is a blueprint, while the object instance is the actual object itself from that blueprint. And just like a blueprint can be reused to create several objects in the real world, you can do so as well with blueprints and objects in code:


cs-asp-036---introduction-to-classes-and-objects.010


Each instance can now have its own unique values for its properties that you can set as you would any variable:


cs-asp-036---introduction-to-classes-and-objects.011


Step 8: Understanding Object Instances in Memory

Each individual value is stored in sections of memory, while another section of memory hold onto myNewCar as a reference to these memory sections and their values:


cs-asp-036---introduction-to-classes-and-objects.012


Now that you have an instance of a Car in memory, with its included properties, you can get those values in memory (again, just like any ordinary variable):


cs-asp-036---introduction-to-classes-and-objects.013


Since Car is a type all its own, you can use it and reference it anywhere. For instance, as an input parameter in a method:


cs-asp-036---introduction-to-classes-and-objects.014


Step 9: Using Your Custom Class as Any Other Type

Notice here that the variable identifier (name) is the same as the type, except that has a different casing. This is perfectly acceptable – even if they share the exact same casing – as the compiler can distinguish between the object’s name and its type. Also, notice that the input parameter is not used in this method, however, you would want to make use of the input parameter in a real-world example. But for the sake of brevity imagine that this method is doing something useful with the information we have about the car that we supply as an input argument at the method call:


cs-asp-036---introduction-to-classes-and-objects.015


And now you can add the value returned into myMarketValueofCar to the resultLabel:


cs-asp-036---introduction-to-classes-and-objects.016


cs-asp-036---introduction-to-classes-and-objects.017


To make this a bit more interesting, let’s actually show how you would go about referencing the input parameter within the method body for determineMarketValue() to modify the result depending on the age of the car:


cs-asp-036---introduction-to-classes-and-objects.018


cs-asp-036---introduction-to-classes-and-objects.019


Step 10: Using Classes to Maintain Separation of Concerns

If you think back to what was said in previous lessons about “Separation of Concerns” it seems that the determineMarketValue() method violates this principle somewhat. In specific, it’s a method that calculates the value of a car, so putting it in the Default class (which is about rendering web page data) is a bit off the mark. Let’s transplant this method to the Car class, where it conceptually fits in a bit better, but with some modifications first:

  1. Change the accessibility to “public,” so that outside classes can call this method.

  2. Remove the input parameter as it is no longer required.

  3. Directly reference the Year property, now that the method can “reach-out” of its scope and reference it at the class-level.


cs-asp-036---introduction-to-classes-and-objects.020


Step 11: Using the Dot Accessor To Reference Instance Members

Now that the method belongs to the Car class, we will have to reference it through the Car instance in outside classes, just as we would the Car properties:


cs-asp-036---introduction-to-classes-and-objects.021


cs-asp-036---introduction-to-classes-and-objects.022


Tip:

As you’ve seen, you can use the dot accessor (period) to peer into a class containment, in order to get/set properties or call methods. In later lessons you will see how class properties can, themselves, be instances of other classes. This creates multiple levels of containment that can be accessed by using multiple dot accessors; peering through one containment level after another.


Related Articles in this Tutorial:

Lesson 1 - Series Introduction

Lesson 2 - Installing Visual Studio 2015

Lesson 3 - Building Your First Web App

Lesson 4 - Understanding What You Just Did

Lesson 5 - Working with Projects in Visual Studio

Lesson 6 - Simple Web Page Formatting in Visual Studio

Challenge 1

Solution 1

Lesson 7 - Variables and Data Types

Lesson 8 - Data Type Conversion

Lesson 9 - Arithmetic Operators

Lesson 10 - C# Syntax Basics

Challenge 2 - ChallengeSimpleCalculator

Solution - ChallengeSimpleCalculator

Lesson 11 - Conditional If Statements

Lesson 12 - The Conditional Ternary Operator

Challenge 3 - ChallengeConditionalRadioButton

Solution - Challenge Conditional RadioButton

Lesson 13 - Comparison and Logical Operators

Lesson 13 Challenge - First Papa Bob's Website

Solution - Challenge First Papa Bob's Website

Lesson 14 - Working with Dates and Times

Lesson 15 - Working With Spans of Time

Lesson 16 - Working with the Calendar Server Control

Challenge 4 - Challenge Days Between Dates

Solution - Challenge Days Between Dates

Lesson 17 - Page_Load and Page.IsPostBack

Lesson 18 - Setting a Break Point and Debugging

Lesson 19 - Formatting Strings

Challenge 5 - Challenge Epic Spies Assignment

Solution - Challenge Epic Spies Assignment

Lesson 20 - Maintaining State with ViewState

Lesson 21 - Storing Values in Arrays

Lesson 22 - Understanding Multidimensional Arrays

Lesson 23 - Changing the Length of an Array

Challenge 6 - Challenge Epic Spies Asset Tracker

Solution - Challenge Epic Spies Asset Tracker

Lesson 24 - Understanding Variable Scope

Lesson 25 - Code Blocks and Nested If Statements

Lesson 26 - Looping with the For Iteration Statement

Challenge 7 - Challenge For Xmen Battle Count

Solution - Challenge For Xmen Battle Count

Lesson 27 - Looping with the while() & do...while() Iteration Statements

Lesson 28 - Creating and Calling Simple Helper Methods

Lesson 29 - Creating Methods with Input Parameters

Lesson 30 - Returning Values from Methods

Lesson 31 - Creating Overloaded Methods

Lesson 32 - Creating Optional Parameters

Lesson 33 - Creating Names Parameters

Lesson 34 - Creating Methods with Output Parameters

Challenge 8 - Challenge Postal Calculator Helper Methods

Solution - Challenge Postal Calculator Helper Methods

Mega Challenge Casino

Solution - Mega Challenge Casino

Lesson 35 - Manipulating Strings

Challenge 9 - Phun With Strings

Solution - Challenge Phun With Strings

Lesson 36 - Introduction to Classes and Objects

Challenge - Hero Monster Classes Part 1

Solution - Hero Monster Classes Part 1

Challenge - Hero Monster Classes Part 2

Solution - Challenge Hero Monster Classes Part 2

Lesson 37 - Creating Class Files Creating Cohesive Classes and Code Navigation

Lesson 38 - Understanding Object References and Object Lifetime

Lesson 39 - Understanding the .NET Framework and Compilation

Lesson 40 - Namespaces and Using Directives

Lesson 41 - Creating Class Libraries and Adding References to Assemblies

Lesson 42 - Accessibility Modifiers, Fields and Properties

Lesson 43 - Creating Constructor Methods

Lesson 44 - Naming Conventions for Identifiers

Lesson 45 - Static vs Instance Members

Challenge 10 - Challenge Simple Darts

Solution - Challenge Simple Darts

Lesson 46 - Working with the List Collection

Lesson 47 - Object Initializers

Lesson 48 - Collection Initializers

Lesson 49 - Working with the Dictionary Collection

Lesson 50 - Looping with the foreach Iteration Statement

Lesson 51 - Implicitly-Typed Variables with the var Keyword

Challenge 11 - Challenge Student Courses

Solution - Challenge Student Courses

Mega Challenge War

Solution - Mega Challenge War

Lesson 52 - Creating GUIDs

Lesson 53 - Working with Enumerations

Lesson 54 - Understanding the switch() Statement

Lesson 55 - First Pass at the Separation of Concerns Principle

Lesson 56 - Understanding Exception Handling

Lesson 57 - Understanding Global Exception Handling

Lesson 58 - Understanding Custom Exceptions

Lesson 59 - Creating a Database in Visual Studio

Lesson 60 - Creating an Entity Data Model

Lesson 61 - Displaying the DbSet Result in an ASP.NET GridView

Lesson 62 - Implementing a Button Command in a GridView

Lesson 63 - Using a Tools-Centric Approach to Building a Database Application

Lesson 64 - Using a Maintenance-Driven Approach to Building a Database Application

Lesson 65 - Creating a New Instance of an Entity and Persisting it to the Database

Lesson 66 - Package Management with NuGet

Lesson 67 - NuGet No-Commit Workflow

Lesson 68 - Introduction the Twitter Bootstrap CSS Framework

Lesson 69 - Mapping Enum Types to Entity Properties in the Framework Designer

Lesson 70 - Deploying the App to Microsoft Azure Web Services Web Apps

Papa Bob's Mega Challenge

Papa Bob's Mega Solution Part 1 - Setting up the Solution

Papa Bob's Mega Solution Part 2 - Adding an Order to the Database

Papa Bob's Mega Solution Part 3 - Passing an Order from the Presentation Layer

Papa Bob's Mega Solution Part 4 - Creating the Order Form

Papa Bob's Mega Solution Part 5 - Adding Enums

Papa Bob's Mega Solution Part 6 - Creating an Order with Validation

Papa Bob's Mega Solution Part 7 - Calculating the Order Price

Papa Bob's Mega Solution Part 8 - Displaying the Price to the User

Papa Bob's Mega Solution Part 9 - Creating the Order Management Page


Comments

Please login or register to add a comment