A didactic project demonstrating the four pillars of Object-Oriented Programming in C#.
SchoolSystem/
├── Interfaces/
│ ├── IEvaluable.cs → Contract: CalculateAverage() and GetGrade()
│ └── IReport.cs → Contract: GenerateReport()
├── Models/
│ ├── Person.cs → ABSTRACT class (base for Student and Teacher)
│ ├── Student.cs → Inherits Person, implements IEvaluable and IReport
│ └── Teacher.cs → Inherits Person, implements IReport
├── Services/
│ └── Classroom.cs → Groups Students and Teacher, implements IReport
├── Program.cs → Entry point — demonstrates all concepts
└── SchoolSystem.csproj
- Private fields (
_name,_ssn,_grades) exposed only through controlled properties - Setters with validation (e.g. SSN with 9 digits, grades between 0 and 10)
- Internal logic protected (enrollment ID generation, salary calculation by experience)
// Grades can only be added via method — which validates the value
student.AddGrade(8.5); // ✅ OK
student.AddGrade(15); // ❌ Throws exceptionStudentandTeacherboth inherit fromPerson(abstract class)- Constructors use
base(...)to reuse the parent class logic protectedmodifier allows controlled access in subclasses
public class Student : Person { ... }
public class Teacher : Person { ... }Introduce()is virtual inPersonand overridden inStudentandTeacherGetType()is abstract: forces each subclass to provide its own implementation- A
List<Person>can hold Students and Teachers — the correct method is called at runtime
List<Person> people = new() { teacher, student1, student2 };
foreach (var p in people)
Console.WriteLine(p.Introduce()); // Each one responds differently!IEvaluable→ implemented only byStudent(has grades and an average)IReport→ implemented byStudent,Teacher, andClassroom- Allows different objects to be treated uniformly via the interface type
List<IReport> reports = new() { teacher, student, classroom };
foreach (var r in reports)
Console.WriteLine(r.GenerateReport()); // Each generates its owncd SchoolSystem
dotnet runRequirement: .NET 8 SDK