Object-Oriented Programming (OOP) is a programming paradigm that uses objects and classes to design and structure code. It helps make flexible design decisions in large-scale applications by promoting code reusability, scalability, and maintainability.
Classes and Objects
Classes: A class is a blueprint for creating objects. It defines a type's properties, methods, and behaviors.
Objects: An object is an instance of a class. It represents a real-world entity and encapsulates state (attributes) and behavior (methods).
Constructors: A constructor is a special method used to initialize objects. It has the same name as the class and does not have a return type.
Methods: Methods define behaviors of the class. They are functions that belong to the class.
Example: Simple Class and Object
using System;
namespace NationalParks
{
class Park
{
public string Name;
public int YearEstablished;
// Constructor
public Park(string name, int year)
{
Name = name;
YearEstablished = year;
}
// Method
public void DisplayInfo()
{
Console.WriteLine($"Park: {Name}, Established: {YearEstablished}");
}
}
class Program
{
static void Main(string[] args)
{
// Creating an object
Park yellowstone = new Park("Yellowstone", 1872);
yellowstone.DisplayInfo();
}
}
}
Explanation:
The Park class has two fields (Name and YearEstablished), a constructor to initialize them, and a method DisplayInfo to display the park's information.
In Main, an object of the Park class is created and its method is called.
Example: Advanced Class and Object with Methods
using System;
namespace NationalParks
{
class Park
{
public string Name { get; private set; }
public int YearEstablished { get; private set; }
public double Area { get; private set; } // in square miles
// Constructor
public Park(string name, int year, double area)
{
Name = name;
YearEstablished = year;
Area = area;
}
// Method to display park info
public void DisplayInfo()
{
Console.WriteLine($"Park: {Name}, Established: {YearEstablished}, Area: {Area} sq mi");
}
// Method to calculate park's age
public int CalculateAge()
{
return DateTime.Now.Year - YearEstablished;
}
// Method to check if the park is larger than a given size
public bool IsLargerThan(double size)
{
return Area > size;
}
}
class Program
{
static void Main(string[] args)
{
Park yosemite = new Park("Yosemite", 1890, 747.95);
yosemite.DisplayInfo();
Console.WriteLine($"Age: {yosemite.CalculateAge()} years");
Console.WriteLine($"Is larger than 500 sq mi: {yosemite.IsLargerThan(500)}");
}
}
}
Explanation:
The Park class includes additional methods (CalculateAge and IsLargerThan) to demonstrate more complex behaviors.
The DisplayInfo, CalculateAge, and IsLargerThan methods show how to encapsulate different functionalities within a class.
Inheritance
Inheritance: Inheritance allows a class to inherit fields and methods from another class. The class that inherits is called the derived class, and the class it inherits from is called the base class.
Example: Simple Inheritance
using System;
namespace NationalParks
{
class Park
{
public string Name { get; set; }
public int YearEstablished { get; set; }
public Park(string name, int year)
{
Name = name;
YearEstablished = year;
}
public void DisplayInfo()
{
Console.WriteLine($"Park: {Name}, Established: {YearEstablished}");
}
}
class NationalPark : Park
{
public string Location { get; set; }
public NationalPark(string name, int year, string location)
: base(name, year)
{
Location = location;
}
public void DisplayLocation()
{
Console.WriteLine($"Location: {Location}");
}
}
class Program
{
static void Main(string[] args)
{
NationalPark yellowstone = new NationalPark("Yellowstone", 1872, "Wyoming");
yellowstone.DisplayInfo();
yellowstone.DisplayLocation();
}
}
}
Explanation:
The NationalPark class inherits from the Park class using the : base(name, year) syntax to call the base class constructor.
The DisplayLocation method is specific to NationalPark.
Example: Advanced Inheritance
using System;
namespace NationalParks
{
class Park
{
public string Name { get; set; }
public int YearEstablished { get; set; }
public double Area { get; set; } // in square miles
public Park(string name, int year, double area)
{
Name = name;
YearEstablished = year;
Area = area;
}
public virtual void DisplayInfo()
{
Console.WriteLine($"Park: {Name}, Established: {YearEstablished}, Area: {Area} sq mi");
}
}
class NationalPark : Park
{
public string Location { get; set; }
public NationalPark(string name, int year, double area, string location)
: base(name, year, area)
{
Location = location;
}
public override void DisplayInfo()
{
base.DisplayInfo();
Console.WriteLine($"Location: {Location}");
}
}
class Program
{
static void Main(string[] args)
{
NationalPark yosemite = new NationalPark("Yosemite", 1890, 747.95, "California");
yosemite.DisplayInfo();
}
}
}
Explanation:
The DisplayInfo method in NationalPark overrides the base class method using the override keyword and calls the base class method using base.DisplayInfo().
Polymorphism
Polymorphism: Polymorphism allows methods to do different things based on the object it is acting upon. It can be achieved through method overloading and method overriding.
Method Overloading: Same method name but different parameters.
Method Overriding: Derived class has a method with the same name and parameters as the base class.
Example: Method Overloading
using System;
namespace NationalParks
{
class Park
{
public string Name { get; set; }
public Park(string name)
{
Name = name;
}
// Overloaded method
public void DisplayInfo()
{
Console.WriteLine($"Park: {Name}");
}
public void DisplayInfo(string extraInfo)
{
Console.WriteLine($"Park: {Name}, Info: {extraInfo}");
}
}
class Program
{
static void Main(string[] args)
{
Park yellowstone = new Park("Yellowstone");
yellowstone.DisplayInfo();
yellowstone.DisplayInfo("First national park in the world");
}
}
}
Example: Method Overriding
using System;
namespace NationalParks
{
class Park
{
public string Name { get; set; }
public Park(string name)
{
Name = name;
}
public virtual void DisplayInfo()
{
Console.WriteLine($"Park: {Name}");
}
}
class NationalPark : Park
{
public string Location { get; set; }
public NationalPark(string name, string location)
: base(name)
{
Location = location;
}
public override void DisplayInfo()
{
Console.WriteLine($"National Park: {Name}, Location: {Location}");
}
}
class Program
{
static void Main(string[] args)
{
Park genericPark = new Park("Generic Park");
genericPark.DisplayInfo();
NationalPark yellowstone = new NationalPark("Yellowstone", "Wyoming");
yellowstone.DisplayInfo();
}
}
}
Explanation:
Method overloading allows multiple DisplayInfo methods with different parameters in the Park class.
Method overriding allows the NationalPark class to provide a specific implementation of DisplayInfo.
Encapsulation
Encapsulation: Encapsulation is the bundling of data with methods that operate on that data. It restricts direct access to some of an object's components, which can prevent the accidental modification of data.
Access Modifiers: public, private, protected, internal, protected internal.
Properties: Properties provide a flexible mechanism to read, write, or compute the values of private fields.
Example: Simple Encapsulation
using System;
namespace NationalParks
{
class Park
{
private string name;
private int yearEstablished;
public string Name
{
get { return name; }
set { name = value; }
}
public int YearEstablished
{
get { return yearEstablished; }
set { yearEstablished = value; }
}
}
class Program
{
static void Main(string[] args)
{
Park yellowstone = new Park();
yellowstone.Name = "Yellowstone";
yellowstone.YearEstablished = 1872;
Console.WriteLine($"Park: {yellowstone.Name}, Established: {yellowstone.YearEstablished}");
}
}
}
Example: Advanced Encapsulation
using System;
namespace NationalParks
{
class Park
{
private string name;
private int yearEstablished;
private double area;
public string Name
{
get { return name; }
set
{
if (!string.IsNullOrEmpty(value))
{
name = value;
}
}
}
public int YearEstablished
{
get { return yearEstablished; }
set
{
if (value > 0)
{
yearEstablished = value;
}
}
}
public double Area
{
get { return area; }
set
{
if (value > 0)
{
area = value;
}
}
}
public void DisplayInfo()
{
Console.WriteLine($"Park: {Name}, Established: {YearEstablished}, Area: {Area} sq mi");
}
}
class Program
{
static void Main(string[] args)
{
Park yosemite = new Park();
yosemite.Name = "Yosemite";
yosemite.YearEstablished = 1890;
yosemite.Area = 747.95;
yosemite.DisplayInfo();
}
}
}
Explanation:
Properties (Name, YearEstablished, Area) control access to private fields and include validation logic.
Abstraction
Abstraction: Abstraction hides complex implementation details and shows only the necessary features of an object. It can be achieved using abstract classes and interfaces.
Abstract Classes: Abstract classes cannot be instantiated and can contain abstract methods, which must be implemented by derived classes.
Interfaces: Interfaces define a contract that implementing classes must fulfill. They can contain only method signatures and properties, without implementation.
Example: Using Abstract Classes
using System;
namespace NationalParks
{
abstract class Park
{
public string Name { get; set; }
public int YearEstablished { get; set; }
public Park(string name, int year)
{
Name = name;
YearEstablished = year;
}
// Abstract method
public abstract void DisplayInfo();
}
class NationalPark : Park
{
public string Location { get; set; }
public NationalPark(string name, int year, string location)
: base(name, year)
{
Location = location;
}
// Implementing abstract method
public override void DisplayInfo()
{
Console.WriteLine($"National Park: {Name}, Established: {YearEstablished}, Location: {Location}");
}
}
class Program
{
static void Main(string[] args)
{
NationalPark yellowstone = new NationalPark("Yellowstone", 1872, "Wyoming");
yellowstone.DisplayInfo();
}
}
}
Example: Using Interfaces
using System;
namespace NationalParks
{
interface IPark
{
string Name { get; set; }
int YearEstablished { get; set; }
void DisplayInfo();
}
class NationalPark : IPark
{
public string Name { get; set; }
public int YearEstablished { get; set; }
public string Location { get; set; }
public NationalPark(string name, int year, string location)
{
Name = name;
YearEstablished = year;
Location = location;
}
public void DisplayInfo()
{
Console.WriteLine($"National Park: {Name}, Established: {YearEstablished}, Location: {Location}");
}
}
class Program
{
static void Main(string[] args)
{
NationalPark yosemite = new NationalPark("Yosemite", 1890, "California");
yosemite.DisplayInfo();
}
}
}
Explanation:
Abstract classes can contain both abstract and non-abstract methods, while interfaces can only contain method signatures.
Both abstract classes and interfaces provide a way to enforce a contract that derived classes or implementing classes must fulfill, promoting flexible and scalable design decisions.