So far, we have dealt with variables and methods separately, but from now on, we will learn about classes, which deal with data and functions as one. A class is a frame (blueprint) that produces an object, and an instance made from that frame is an object.
Learning Objectives
- You can define a new type with the
classkeyword. - You can distinguish between fields, methods, and constructors.
- Know the role of the
thiskeyword - Access limiters (
public/private/internal/protected) can be used where appropriate. - Create objects with
newand understand what reference variables actually point to.
Key concepts
1) Classes as blueprints, objects as instances
class Person //blueprint
{
public string Name = "";
public int Age;
}
Person alice = new Person(); //Entity (object) printed as a blueprint
alice.Name = "Alice";
alice.Age = 30;
Person itself has no data in memory. An object is created in memory only when new Person() is called, and the variable alice contains the reference (address) of the object.
2) Fields and methods
- Field: Data (variable) held by the class
- method: Action (function) of the class
class Counter
{
public int Count; //field
public void Increase() => Count++; //method
}
3) Constructor and this
This is a special method that is automatically called when an object is created. Make it the same as the class name, and do not use the return type.
class Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
this.Name = name; //this.Name is a field, name is a parameter
this.Age = age;
}
}
this is a keyword that indicates “the object itself that is currently operating.” It is often used for differentiation when parameter and field names overlap.
4) Access modifiers
| Keyword | Who can access it? |
|---|---|
public |
Anywhere |
private |
Only within the same class (default) |
internal |
Only within the same assembly (project) |
protected |
Same class + child class |
Basics of encapsulation: Expose data as private as much as possible, only operations for external use as public.
5) new keywords and references
Person a = new Person("Alice", 30);
Person b = a; //b points to the same object as a (not a copy!)
b.Age = 99;
Console.WriteLine(a.Age); //99 → a also changes
A class is a reference type. Even if you substitute another variable for a variable, the object is not duplicated, and both variables point to the same object.
See as example
Example 1 — PersonBasic: The simplest class
// Program.cs
using CodingNow.Lecture.Oop06;
var alice = new Person("Alice", 30);
alice.Greet();
var bob = new Person("Bob", 25);
bob.Greet();
// Person.cs
namespace CodingNow.Lecture.Oop06;
internal class Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
this.Name = name;
this.Age = age;
}
public void Greet()
{
Console.WriteLine($"Hello, I am {Name}({Age} years old).");
}
}
Execution result
Hi, I'm Alice (30 years old).
Hi, I'm Bob (25 years old).
Note: We created two independent objects with one Person class.
Example 2 — AccessModifiers: Demonstrating access limiters
// Program.cs
using CodingNow.Lecture.Oop06;
var account = new Account(1000);
account.Deposit(500); // public — OK
Console.WriteLine($"Balance: {account.GetBalance()}");
//account.balance = 0; // private — compilation error
account.LogInternal(); //internal — OK because it’s in the same project
// Account.cs
namespace CodingNow.Lecture.Oop06;
internal class Account
{
private int balance; //No direct external changes
public Account(int initial)
{
balance = initial;
}
public void Deposit(int amount) //public action
{
if (amount <= 0) return;
balance += amount;
}
public int GetBalance() => balance;
internal void LogInternal() //only within the same assembly
{
Console.WriteLine($"[Internal Log] Balance={balance}");
}
}
Execution result
Balance: 1500
[Internal Log] Current balance = 1500
Memo: By blocking balance with private and leaving only Deposit open, you can prevent incorrect changes (negative deposits, etc.).
Example 3 — MultiConstructor: Constructor overloading + this(...)
// Program.cs
using CodingNow.Lecture.Oop06;
var p1 = new Point(); // (0, 0)
var p2 = new Point(5); // (5, 5)
var p3 = new Point(3, 7); // (3, 7)
p1.Print();
p2.Print();
p3.Print();
// Point.cs
namespace CodingNow.Lecture.Oop06;
internal class Point
{
public int X;
public int Y;
public Point() : this(0, 0) { } //delegate to another constructor
public Point(int v) : this(v, v) { } //One value for both X and Y
public Point(int x, int y)
{
X = x;
Y = y;
}
public void Print() => Console.WriteLine($"({X}, {Y})");
}
Execution result
(0, 0)
(5, 5)
(3, 7)
Memo: : this(...) means "call other constructors of the same class first." Reduces duplicate code.
Example 4 — NewKeyword: Checking the meaning of a reference
// Program.cs
using CodingNow.Lecture.Oop06;
var a = new Box(10);
var b = a; //It's not a copy! b also points to the same object.
b.Value = 99;
Console.WriteLine($"a.Value = {a.Value}");
Console.WriteLine($"b.Value = {b.Value}");
var c = new Box(10); //completely different object
Console.WriteLine($"a == b ? {ReferenceEquals(a, b)}");
Console.WriteLine($"a == c ? {ReferenceEquals(a, c)}");
// Box.cs
namespace CodingNow.Lecture.Oop06;
internal class Box
{
public int Value;
public Box(int value) => Value = value;
}
Execution result
a.Value = 99
b.Value = 99
a == b ? True
a == c ? False
Note: b = a is “copy address”. Separate comparison logic (such as Properties/partEquals in the next section) is needed to see if the values themselves are equal.
Common Mistakes
- I know that an instance is not created because only
new Personis used and()is omitted — the call form must benew Person(). - The field and parameter names are the same, but instead of adding
this., write a code that substitutes itself (Name = Name;). - If you try to change the
privatefield directly from the outside, you change it topublic— broken encapsulation. Solved using the properties in the next section. - Without knowing that the two variables point to the same object, you can rest assured that only one side has been changed.
- Name the constructor like
Person CreatePerson(), notPerson()— it must be exactly the same as the class name.
Cleanup
- A class is a blueprint, and an object is an entity taken from that blueprint (created with
new) - Fields are data, methods are actions, and constructors are initialization code when an object is created.
thisis the current object itself, andprivate/publiccontrols the external exposure range.- Classes are reference types — variables contain the address of an object, not the object itself.
Try it yourself
cd src/PersonBasic
dotnet run
cd ../AccessModifiers
dotnet run
cd ../MultiConstructor
dotnet run
cd ../NewKeyword
dotnet run