TypeScript📅 2026-10-05⏱ 11 دقائق قراءة📘 مقال 6 من 10

الفئات في TypeScript — دليل شامل Classes 2026

دليل عملي مفصل للفئات في TypeScript — التعريف، الوراثة، Access Modifiers، Abstract Classes، مع تمارين وحلول

في المقال السابق، تعلمت الدوال مع الأنواع. الآن سنتعمق في الفئات (Classes) — وهي أساس البرمجة كائنية التوجه (OOP) في TypeScript.

في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم الفئات، والوراثة، ومحددات الوصول، مع تمارين وحلول.

ما هي الفئة (Class)؟

الفئة هي قالب لإنشاء كائنات (Objects). تحتوي على:

  • الخصائص (Properties): البيانات.
  • الطرق (Methods): الدوال.
  • Constructor: دالة تُنفَّذ عند إنشاء الكائن.

مثال بسيط:

class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `مرحباً، اسمي ${this.name} وعمري ${this.age}`;
  }
}

const ahmed = new Person("أحمد", 25);
console.log(ahmed.greet());  // مرحباً، اسمي أحمد وعمري 25

شرح:

  • class Person: تعريف فئة.
  • name: string: خاصية.
  • constructor: دالة تُنفَّذ عند new Person(...).
  • greet(): طريقة (method).
  • new Person("أحمد", 25): إنشاء كائن جديد.

لماذا نحتاج الفئات؟

  • التنظيم: تجميع البيانات والوظائف معاً.
  • إعادة الاستخدام: الوراثة (Inheritance).
  • الأمان: تحديد من يمكنه الوصول للبيانات.
  • الوضوح: الكود يعكس كائنات العالم الحقيقي.

تعريف فئة بسيطة

class Car {
  brand: string;
  model: string;
  year: number;

  constructor(brand: string, model: string, year: number) {
    this.brand = brand;
    this.model = model;
    this.year = year;
  }

  getInfo(): string {
    return `${this.brand} ${this.model} (${this.year})`;
  }
}

const car = new Car("تويوتا", "كامري", 2024);
console.log(car.getInfo());  // تويوتا كامري (2024)

Constructor — البانية

الـ Constructor هي دالة خاصة تُنفَّذ عند إنشاء الكائن:

class User {
  name: string;
  email: string;

  constructor(name: string, email: string) {
    this.name = name;
    this.email = email;
    console.log("تم إنشاء مستخدم جديد!");
  }
}

const user = new User("أحمد", "[email protected]");
// يطبع: تم إنشاء مستخدم جديد!

طريقة مختصرة (Parameter Properties)

يمكنك تعريف الخصائص مباشرة في الـ Constructor:

class Person {
  constructor(
    public name: string,
    public age: number,
    private email: string
  ) {}

  getInfo(): string {
    return `${this.name} (${this.age})`;
  }
}

const person = new Person("أحمد", 25, "[email protected]");
console.log(person.name);  // أحمد
console.log(person.age);   // 25
// console.log(person.email);  // ❌ خطأ: private

الفائدة: كود أقل، ووضوح أكثر.

محددات الوصول (Access Modifiers)

TypeScript توفر 3 محددات وصول:

المحددالوصولالاستخدام
publicمن أي مكان (افتراضي)للخصائص العامة
privateداخل الفئة فقطللبيانات الحساسة
protectedداخل الفئة والفئات الوريثةللمشاركة مع الفئات الفرعية

1. public

class Person {
  public name: string;

  constructor(name: string) {
    this.name = name;
  }
}

const person = new Person("أحمد");
console.log(person.name);  // ✅ أحمد

2. private

class BankAccount {
  private balance: number;

  constructor(initialBalance: number) {
    this.balance = initialBalance;
  }

  deposit(amount: number): void {
    this.balance += amount;
  }

  getBalance(): number {
    return this.balance;
  }
}

const account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance());  // 1500
// console.log(account.balance);  // ❌ خطأ: private

3. protected

class Animal {
  protected name: string;

  constructor(name: string) {
    this.name = name;
  }
}

class Dog extends Animal {
  bark(): void {
    console.log(`${this.name} يقول: هاو هاو!`);  // ✅ يمكن الوصول
  }
}

const dog = new Dog("روكي");
dog.bark();  // روكي يقول: هاو هاو!

Readonly Properties

class User {
  readonly id: number;
  name: string;

  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
  }
}

const user = new User(1, "أحمد");
user.name = "محمد";  // ✅
// user.id = 2;  // ❌ خطأ: readonly

الوراثة (Inheritance)

الوراثة تسمح لفئة بأخذ خصائص وطرق فئة أخرى:

class Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  makeSound(): void {
    console.log("صوت غير معروف");
  }
}

class Dog extends Animal {
  makeSound(): void {
    console.log(`${this.name} يقول: هاو هاو!`);
  }
}

class Cat extends Animal {
  makeSound(): void {
    console.log(`${this.name} يقول: مياو!`);
  }
}

const dog = new Dog("روكي");
dog.makeSound();  // روكي يقول: هاو هاو!

const cat = new Cat("مشمش");
cat.makeSound();  // مشمش يقول: مياو!

شرح:

  • extends Animal: فئة Dog ترث من Animal.
  • makeSound(): إعادة تعريف (override) للطريقة.

super — استدعاء الفئة الأم

class Animal {
  constructor(public name: string) {}

  makeSound(): void {
    console.log("صوت غير معروف");
  }
}

class Dog extends Animal {
  constructor(name: string, public breed: string) {
    super(name);  // استدعاء constructor الفئة الأم
  }

  makeSound(): void {
    super.makeSound();  // استدعاء طريقة الفئة الأم
    console.log("هاو هاو!");
  }
}

const dog = new Dog("روكي", "جولدن");
dog.makeSound();
// صوت غير معروف
// هاو هاو!

الفئات المجردة (Abstract Classes)

الفئة المجردة لا يمكن إنشاء كائن منها مباشرة، بل يجب أن تُورَّث:

abstract class Shape {
  abstract area(): number;  // يجب على الفئة الوريثة تنفيذها

  describe(): string {
    return `المساحة: ${this.area()}`;
  }
}

class Circle extends Shape {
  constructor(private radius: number) {
    super();
  }

  area(): number {
    return Math.PI * this.radius ** 2;
  }
}

class Rectangle extends Shape {
  constructor(private width: number, private height: number) {
    super();
  }

  area(): number {
    return this.width * this.height;
  }
}

const circle = new Circle(5);
console.log(circle.describe());  // المساحة: 78.5398...

const rect = new Rectangle(4, 6);
console.log(rect.describe());  // المساحة: 24

// const shape = new Shape();  // ❌ خطأ: abstract

Getters و Setters

class User {
  private _name: string = "";

  get name(): string {
    return this._name;
  }

  set name(value: string) {
    if (value.length < 2) {
      throw new Error("الاسم قصير جداً");
    }
    this._name = value;
  }
}

const user = new User();
user.name = "أحمد";
console.log(user.name);  // أحمد

// user.name = "أ";  // ❌ خطأ: الاسم قصير جداً

Static Properties و Methods

Static تعني أن الخاصية أو الطريقة تنتمي للفئة نفسها، وليس للكائنات:

class MathUtils {
  static PI: number = 3.14159;

  static add(a: number, b: number): number {
    return a + b;
  }

  static multiply(a: number, b: number): number {
    return a * b;
  }
}

console.log(MathUtils.PI);          // 3.14159
console.log(MathUtils.add(5, 3));   // 8
console.log(MathUtils.multiply(4, 5)); // 20

// لا تحتاج إلى new MathUtils()

تنفيذ الواجهات (implements)

الفئات يمكنها تنفيذ الواجهات:

interface Animal {
  name: string;
  makeSound(): void;
}

class Dog implements Animal {
  constructor(public name: string) {}

  makeSound(): void {
    console.log(`${this.name} يقول: هاو هاو!`);
  }
}

const dog = new Dog("روكي");
dog.makeSound();

مثال عملي: نظام موظفين

abstract class Employee {
  constructor(
    public id: number,
    public name: string,
    protected salary: number
  ) {}

  abstract calculateBonus(): number;

  getDetails(): string {
    return `الموظف: ${this.name} (ID: ${this.id})`;
  }

  getSalary(): number {
    return this.salary;
  }
}

class Manager extends Employee {
  constructor(id: number, name: string, salary: number, private teamSize: number) {
    super(id, name, salary);
  }

  calculateBonus(): number {
    return this.salary * 0.2;  // 20% مدير
  }
}

class Developer extends Employee {
  constructor(id: number, name: string, salary: number, private language: string) {
    super(id, name, salary);
  }

  calculateBonus(): number {
    return this.salary * 0.1;  // 10% مطور
  }

  getLanguage(): string {
    return this.language;
  }
}

const manager = new Manager(1, "أحمد", 10000, 5);
console.log(manager.getDetails());         // الموظف: أحمد (ID: 1)
console.log(manager.calculateBonus());     // 2000

const developer = new Developer(2, "محمد", 8000, "TypeScript");
console.log(developer.getDetails());       // الموظف: محمد (ID: 2)
console.log(developer.calculateBonus());   // 800
console.log(developer.getLanguage());      // TypeScript

تمارين عملية

تمرين 1: فئة Person

أنشئ فئة Person لها name و age وطريقة greet().

الحل:

class Person {
  constructor(public name: string, public age: number) {}

  greet(): string {
    return `مرحباً، اسمي ${this.name} وعمري ${this.age}`;
  }
}

const person = new Person("أحمد", 25);
console.log(person.greet());

تمرين 2: فئة Rectangle

أنشئ فئة Rectangle لها width و height، وطريقة area().

الحل:

class Rectangle {
  constructor(public width: number, public height: number) {}

  area(): number {
    return this.width * this.height;
  }
}

const rect = new Rectangle(5, 10);
console.log(rect.area());  // 50

تمرين 3: الوراثة

أنشئ فئة Animal، ثم Dog و Cat ترث منها.

الحل:

class Animal {
  constructor(public name: string) {}

  makeSound(): void {
    console.log("صوت غير معروف");
  }
}

class Dog extends Animal {
  makeSound(): void {
    console.log(`${this.name}: هاو هاو!`);
  }
}

class Cat extends Animal {
  makeSound(): void {
    console.log(`${this.name}: مياو!`);
  }
}

new Dog("روكي").makeSound();   // روكي: هاو هاو!
new Cat("مشمش").makeSound();   // مشمش: مياو!

تمرين 4: Private

أنشئ فئة BankAccount لها balance خاص.

الحل:

class BankAccount {
  private balance: number = 0;

  deposit(amount: number): void {
    if (amount > 0) this.balance += amount;
  }

  withdraw(amount: number): void {
    if (amount > 0 && amount <= this.balance) {
      this.balance -= amount;
    }
  }

  getBalance(): number {
    return this.balance;
  }
}

const account = new BankAccount();
account.deposit(1000);
account.withdraw(300);
console.log(account.getBalance());  // 700

تمرين 5: Abstract Class

أنشئ فئة مجردة Shape لها area().

الحل:

abstract class Shape {
  abstract area(): number;

  describe(): string {
    return `المساحة: ${this.area()}`;
  }
}

class Circle extends Shape {
  constructor(private radius: number) {
    super();
  }

  area(): number {
    return Math.PI * this.radius ** 2;
  }
}

console.log(new Circle(5).describe());

تمرين 6: Static

أنشئ فئة MathUtils لها دوال static.

الحل:

class MathUtils {
  static add(a: number, b: number): number {
    return a + b;
  }

  static subtract(a: number, b: number): number {
    return a - b;
  }
}

console.log(MathUtils.add(5, 3));       // 8
console.log(MathUtils.subtract(5, 3));  // 2

تمرين 7: Getters و Setters

أنشئ فئة Temperature لها celsius مع getter/setter.

الحل:

class Temperature {
  private _celsius: number = 0;

  get celsius(): number {
    return this._celsius;
  }

  set celsius(value: number) {
    if (value < -273.15) {
      throw new Error("أقل من الصفر المطلق!");
    }
    this._celsius = value;
  }

  get fahrenheit(): number {
    return this._celsius * 9 / 5 + 32;
  }
}

const temp = new Temperature();
temp.celsius = 25;
console.log(temp.celsius);      // 25
console.log(temp.fahrenheit);   // 77

تمرين 8: نظام حيوانات

أنشئ نظاماً كاملاً بفئات حيوانات.

الحل:

abstract class Animal {
  constructor(public name: string) {}
  abstract makeSound(): string;
}

class Dog extends Animal {
  makeSound(): string {
    return `${this.name}: هاو هاو!`;
  }
}

class Cat extends Animal {
  makeSound(): string {
    return `${this.name}: مياو!`;
  }
}

class Cow extends Animal {
  makeSound(): string {
    return `${this.name}: مووو!`;
  }
}

const animals: Animal[] = [
  new Dog("روكي"),
  new Cat("مشمش"),
  new Cow("بقرودة"),
];

animals.forEach((animal) => console.log(animal.makeSound()));

حل المشاكل الشائعة

🔴 المشكلة 1: Property 'X' has no initializer

السبب: خاصية لم تُهيأ في الـ Constructor.

class Person {
  name: string;  // ❌ خطأ
}

الحل:

class Person {
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

// أو:
class Person {
  name: string = "";
}

// أو:
class Person {
  constructor(public name: string) {}
}

🔴 المشكلة 2: Cannot access 'X' before initialization

السبب: استخدام this قبل super().

class Dog extends Animal {
  constructor(name: string) {
    this.name = name;  // ❌
    super();
  }
}

الحل: استدعِ super() أولاً:

class Dog extends Animal {
  constructor(name: string) {
    super();
    this.name = name;  // ✅
  }
}

🔴 المشكلة 3: Cannot create an instance of an abstract class

السبب: محاولة إنشاء كائن من فئة مجردة.

abstract class Shape {}
const shape = new Shape();  // ❌

الحل: أنشئ فئة فرعية ترث منها.

🔴 المشكلة 4: Property 'X' is private

السبب: الوصول لخاصية private من خارج الفئة.

class User {
  private password: string = "123";
}
const user = new User();
console.log(user.password);  // ❌

الحل: اجعلها public أو أضف getter.

جدول الأوامر الأساسية

الأمرالوظيفة
class X { }تعريف فئة
constructor() { }الـ Constructor
new X()إنشاء كائن
class X extends Yوراثة
super()استدعاء الفئة الأم
public, private, protectedمحددات الوصول
readonlyللقراءة فقط
abstractفئة مجردة
staticينتمي للفئة
get / setGetters/Setters
implementsتنفيذ واجهة

قائمة تحقق نهائية

المهمةالحالة
فهم تعريف الفئات والـ Constructor⬜
محددات الوصول (public, private, protected)⬜
الوراثة (extends) و super⬜
الفئات المجردة (abstract)⬜
Static Properties/Methods⬜
Getters و Setters⬜
تنفيذ الواجهات (implements)⬜
حل التمارين الثمانية⬜

ماذا بعد هذا المقال؟

الآن بعد أن أتقنت الفئات، أنت جاهز للمقال التالي:

  1. الأدوية (Generics) — الأنواع العامة.
  2. الأنواع المتقدمة — Utility Types.
  3. مشروع React — تطبيق عملي.

الخلاصة

في هذا المقال، تعلمت:

  • ✅ تعريف الفئات والـ Constructor.
  • ✅ محددات الوصول (public, private, protected).
  • ✅ Readonly Properties.
  • ✅ الوراثة (extends) و super.
  • ✅ الفئات المجردة (abstract).
  • ✅ Getters و Setters.
  • ✅ Static Properties/Methods.
  • ✅ تنفيذ الواجهات (implements).

تذكر: الفئات هي أساس البرمجة كائنية التوجه. أتقنها جيداً، وستتمكن من بناء تطبيقات معقدة.

هل أتقنت الفئات؟ شاركنا في التعليقات!

📚 مقالات ذات صلة

TypeScript

مشروع Node.js مع TypeScript — API كامل 2026

مشروع عملي لبناء API كامل بـ Node.js و Express و TypeScript — خطوة بخطوة مع الكود الكامل والشرح

TypeScript

مشروع React مع TypeScript — تطبيق مهام كامل 2026

مشروع عملي لبناء تطبيق مهام (Todo App) بـ React و TypeScript — خطوة بخطوة مع الكود الكامل والشرح

TypeScript

الأنواع المتقدمة في TypeScript — دليل شامل 2026

دليل عملي مفصل للأنواع المتقدمة في TypeScript — Union, Intersection, Conditional, Mapped, Template Literal، مع تمارين وحلول