Object-Oriented Programming in .NET
Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data in the form of fields (often known as attributes or properties) and code in the form of procedures (often known as methods).
Microsoft's .NET platform provides robust support for OOP principles, enabling developers to build scalable, maintainable, and reusable software. This documentation explores the core OOP concepts as implemented within the .NET ecosystem.
Introduction
OOP allows developers to model real-world entities and their interactions, leading to code that is easier to understand, debug, and extend. .NET, with languages like C# and Visual Basic, fully embraces this paradigm.
Classes and Objects
A class is a blueprint for creating objects, defining the properties (data) and methods (behavior) that objects of that class will have. An object is an instance of a class.
In C#, you define a class like this:
public class Car
{
public string Make;
public string Model;
public int Year;
public void StartEngine()
{
Console.WriteLine("Engine started!");
}
}
And you create an object (instance) from the class:
Car myCar = new Car();
myCar.Make = "Toyota";
myCar.Model = "Camry";
myCar.Year = 2023;
myCar.StartEngine();
Encapsulation
Encapsulation is the bundling of data (fields) and methods that operate on the data into a single unit, the class. It also involves restricting direct access to some of an object's components, which is known as data hiding.
In .NET, access modifiers like public
, private
, protected
, and internal
are used to control visibility.
public class BankAccount
{
private decimal balance; // Data hidden
public void Deposit(decimal amount)
{
if (amount > 0)
{
balance += amount; // Method controls data access
}
}
public decimal GetBalance()
{
return balance; // Provides controlled access
}
}
Inheritance
Inheritance allows a new class (derived class or subclass) to inherit properties and methods from an existing class (base class or superclass). This promotes code reuse and establishes a relationship between classes (is-a relationship).
public class Vehicle { /* ... */ }
public class ElectricCar : Vehicle // ElectricCar inherits from Vehicle
{
public int BatteryCapacity;
}
Polymorphism
Polymorphism (meaning "many forms") allows objects of different classes to be treated as objects of a common base class. This is often achieved through method overriding and interfaces.
Method Overriding:
public class Shape
{
public virtual void Draw() { Console.WriteLine("Drawing a generic shape."); }
}
public class Circle : Shape
{
public override void Draw() { Console.WriteLine("Drawing a circle."); }
}
// Usage:
Shape myShape = new Circle();
myShape.Draw(); // Outputs: Drawing a circle.
Abstraction
Abstraction is the process of hiding complex implementation details and exposing only the essential features of an object. It focuses on what an object does rather than how it does it.
Interfaces and abstract classes are key mechanisms for achieving abstraction in .NET.
Interfaces
An interface is a contract that defines a set of method signatures without any implementation. Classes that implement an interface must provide an implementation for all its members.
public interface IShape
{
double CalculateArea();
}
public class Square : IShape
{
public double SideLength { get; set; }
public double CalculateArea()
{
return SideLength * SideLength;
}
}
Abstract Classes
An abstract class is a class that cannot be instantiated directly. It can contain abstract methods (without implementation) and concrete methods (with implementation). Derived classes must implement abstract methods.
public abstract class Animal
{
public abstract void MakeSound(); // Abstract method
public void Eat() // Concrete method
{
Console.WriteLine("Eating.");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Woof!");
}
}
Constructors and Destructors
A constructor is a special method used to initialize an object when it is created. A destructor (or finalizer in C#) is used for cleanup before an object is garbage collected.
public class Person
{
public string Name;
// Constructor
public Person(string name)
{
Name = name;
Console.WriteLine($"Person object '{Name}' created.");
}
// Destructor (Finalizer)
~Person()
{
Console.WriteLine($"Person object '{Name}' is being finalized.");
}
}
Properties and Indexers
Properties provide a flexible mechanism to read, write, or compute the value of a private field. Indexers allow instances of a class to be indexed as if they were arrays.
Properties:
public class Product
{
private decimal price;
public decimal Price
{
get { return price; }
set
{
if (value >= 0)
{
price = value;
}
}
}
}
Indexers:
public class Collection
{
private string[] items = new string[10];
public string this[int index]
{
get { return items[index]; }
set { items[index] = value; }
}
}
Generics
Generics allow you to define type-safe classes, interfaces, methods, and delegates without specifying the exact type. This enhances code reusability and performance.
public class GenericList
{
private T[] elements = new T[100];
private int count;
public void Add(T item)
{
elements[count++] = item;
}
public T Get(int index)
{
return elements[index];
}
}
// Usage:
GenericList numbers = new GenericList();
numbers.Add(10);
GenericList names = new GenericList();
names.Add("Alice");