.NET Classes
Introduction
Classes are the fundamental building blocks of Object-Oriented Programming (OOP) in .NET. They serve as blueprints or templates that define the structure and behavior of objects. In this tutorial, we'll explore how classes work in .NET, how to create and use them, and best practices for designing effective class structures.
A class encapsulates data (fields and properties) and behavior (methods) into a single unit. This encapsulation is one of the key principles of OOP, allowing you to create modular, reusable, and maintainable code.
Understanding .NET Classes
What is a Class?
A class is a user-defined data type that contains:
- Fields: Variables that store data
- Properties: Special methods that provide access to fields
- Methods: Functions that perform operations
- Events: Notifications that the class can send to other code
- Constructors: Special methods that initialize objects
Here's the basic syntax for defining a class in C#:
// Basic class structure
public class Person
{
// Fields
private string name;
private int age;
// Constructor
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
// Properties
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
// Method
public void Introduce()
{
Console.WriteLine($"Hello, my name is {name} and I am {age} years old.");
}
}
Creating and Using Classes
Declaring a Class
Let's create a simple Book
class to demonstrate how to define and use classes:
public class Book
{
// Fields
private string title;
private string author;
private int pages;
// Constructor
public Book(string title, string author, int pages)
{
this.title = title;
this.author = author;
this.pages = pages;
}
// Properties
public string Title
{
get { return title; }
set { title = value; }
}
public string Author
{
get { return author; }
set { author = value; }
}
public int Pages
{
get { return pages; }
set { pages = value; }
}
// Methods
public string GetBookInfo()
{
return $"'{title}' by {author}, {pages} pages";
}
}
Instantiating a Class
To use a class, you need to create an instance (an object) of that class:
// Creating an instance of the Book class
Book myBook = new Book("The Great Gatsby", "F. Scott Fitzgerald", 218);
// Accessing properties
Console.WriteLine(myBook.Title); // Output: The Great Gatsby
// Calling methods
string bookInfo = myBook.GetBookInfo();
Console.WriteLine(bookInfo); // Output: 'The Great Gatsby' by F. Scott Fitzgerald, 218 pages
Using Auto-Implemented Properties
C# provides a shorthand syntax for properties that don't require custom logic in their accessors:
public class Product
{
// Auto-implemented properties
public string Name { get; set; }
public decimal Price { get; set; }
public int StockQuantity { get; set; }
public Product(string name, decimal price, int stockQuantity)
{
Name = name;
Price = price;
StockQuantity = stockQuantity;
}
public bool IsInStock()
{
return StockQuantity > 0;
}
}
Using the Product
class:
Product laptop = new Product("Laptop", 999.99m, 10);
Console.WriteLine($"{laptop.Name}: ${laptop.Price}, In stock: {laptop.IsInStock()}");
// Output: Laptop: $999.99, In stock: True
Class Constructors
Constructors are special methods that initialize objects when they are created. They have the same name as the class and don't have a return type.
Default Constructor
If you don't define any constructors, C# provides a default parameterless constructor:
public class Student
{
public string Name { get; set; }
public int ID { get; set; }
// No constructor defined, so C# provides a default one
}
// Using the default constructor
Student student = new Student();
student.Name = "Alice";
student.ID = 12345;
Parameterized Constructors
You can define multiple constructors with different parameters:
public class Student
{
public string Name { get; set; }
public int ID { get; set; }
// Parameterless constructor
public Student()
{
Name = "Unknown";
ID = 0;
}
// Parameterized constructor
public Student(string name, int id)
{
Name = name;
ID = id;
}
}
// Using different constructors
Student student1 = new Student();
Console.WriteLine($"{student1.Name}, ID: {student1.ID}"); // Output: Unknown, ID: 0
Student student2 = new Student("Bob", 67890);
Console.WriteLine($"{student2.Name}, ID: {student2.ID}"); // Output: Bob, ID: 67890
Static Members
Static members belong to the class itself rather than to any specific object:
public class MathHelper
{
// Static field
public static double PI = 3.14159265359;
// Static method
public static double CalculateCircleArea(double radius)
{
return PI * radius * radius;
}
}
// Using static members (no need to create an instance)
double area = MathHelper.CalculateCircleArea(5);
Console.WriteLine($"Circle area: {area}"); // Output: Circle area: 78.5398163397
Real-World Example: Banking Application
Let's create a more practical example of a simple banking system:
public class BankAccount
{
// Static field for generating account numbers
private static int accountCounter = 1000;
// Properties
public string AccountNumber { get; private set; }
public string OwnerName { get; set; }
public decimal Balance { get; private set; }
// Constructor
public BankAccount(string ownerName, decimal initialDeposit)
{
AccountNumber = GenerateAccountNumber();
OwnerName = ownerName;
Balance = initialDeposit;
}
// Private method to generate account number
private string GenerateAccountNumber()
{
accountCounter++;
return $"ACC-{accountCounter}";
}
// Methods
public void Deposit(decimal amount)
{
if (amount <= 0)
{
Console.WriteLine("Deposit amount must be positive.");
return;
}
Balance += amount;
Console.WriteLine($"Deposited: ${amount}. New balance: ${Balance}");
}
public bool Withdraw(decimal amount)
{
if (amount <= 0)
{
Console.WriteLine("Withdrawal amount must be positive.");
return false;
}
if (amount > Balance)
{
Console.WriteLine("Insufficient funds.");
return false;
}
Balance -= amount;
Console.WriteLine($"Withdrew: ${amount}. New balance: ${Balance}");
return true;
}
public string GetAccountInfo()
{
return $"Account: {AccountNumber}, Owner: {OwnerName}, Balance: ${Balance}";
}
}
Using the BankAccount Class
Here's how you might use the BankAccount
class in a simple banking application:
// Create some bank accounts
BankAccount account1 = new BankAccount("John Doe", 1000m);
BankAccount account2 = new BankAccount("Jane Smith", 500m);
// Display initial account information
Console.WriteLine(account1.GetAccountInfo());
// Output: Account: ACC-1001, Owner: John Doe, Balance: $1000
Console.WriteLine(account2.GetAccountInfo());
// Output: Account: ACC-1002, Owner: Jane Smith, Balance: $500
// Perform some transactions
account1.Deposit(250m);
// Output: Deposited: $250. New balance: $1250
account1.Withdraw(100m);
// Output: Withdrew: $100. New balance: $1150
account2.Withdraw(600m);
// Output: Insufficient funds.
// Transfer money between accounts
decimal transferAmount = 200m;
if (account1.Withdraw(transferAmount))
{
account2.Deposit(transferAmount);
Console.WriteLine($"Transferred ${transferAmount} from {account1.OwnerName} to {account2.OwnerName}");
}
// Display final account information
Console.WriteLine(account1.GetAccountInfo());
// Output: Account: ACC-1001, Owner: John Doe, Balance: $950
Console.WriteLine(account2.GetAccountInfo());
// Output: Account: ACC-1002, Owner: Jane Smith, Balance: $700
Best Practices for Creating Classes
- Single Responsibility Principle: Each class should have only one reason to change.
- Encapsulation: Keep fields private and provide access through properties.
- Meaningful Names: Use clear and descriptive names for classes, properties, and methods.
- Appropriate Access Modifiers: Use
public
,private
,protected
, andinternal
appropriately. - Validation: Validate data in constructors and property setters.
- Documentation: Use XML comments to document your classes and members.
Here's an example applying these best practices:
/// <summary>
/// Represents a customer in the system.
/// </summary>
public class Customer
{
private string email;
/// <summary>
/// Gets or sets the customer's ID.
/// </summary>
public int Id { get; private set; }
/// <summary>
/// Gets or sets the customer's name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets the customer's email address.
/// </summary>
public string Email
{
get { return email; }
set
{
if (string.IsNullOrEmpty(value) || !value.Contains("@"))
{
throw new ArgumentException("Invalid email address");
}
email = value;
}
}
/// <summary>
/// Creates a new customer with the specified details.
/// </summary>
/// <param name="id">The customer's unique identifier.</param>
/// <param name="name">The customer's name.</param>
/// <param name="email">The customer's email address.</param>
public Customer(int id, string name, string email)
{
Id = id;
Name = name;
Email = email; // This will use the validation in the property setter
}
/// <summary>
/// Returns a string representation of the customer.
/// </summary>
public override string ToString()
{
return $"Customer {Id}: {Name} ({Email})";
}
}
Summary
In this tutorial, we've explored:
- The fundamentals of classes in .NET
- How to define fields, properties, and methods
- Creating and using constructors
- Working with static members
- A real-world example of using classes in a banking application
- Best practices for designing classes
Classes are essential to object-oriented programming in .NET. They allow you to model real-world concepts, create reusable components, and build complex applications from smaller, manageable parts. Understanding classes is critical for becoming proficient in .NET development.
Exercises
- Create a
Rectangle
class withWidth
andHeight
properties, and methods to calculateArea
andPerimeter
. - Design a
Library
class that can store and manage a collection ofBook
objects. - Implement a
Person
class with properties for name, age, and address. Add validation to ensure age is positive and name is not empty. - Create a
ShoppingCart
class that can add products, remove products, and calculate the total price. - Design a simple
Logger
class with static methods to log messages to the console or a file.
Additional Resources
- Microsoft Documentation: Classes (C# Programming Guide)
- C# Class Design Best Practices
- Object-Oriented Programming in C#
Happy coding!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)