التغليف

التغليف (Encapsulation) هو أحد المبادئ الأساسية للبرمجة الكائنية. يعني إخفاء البيانات الداخلية وספק واجهة عامة للوصول إليها.

مبدأ التغليف

المبدأ الوصف
إخفاء البيانات اجعل المتغيرات private
واجهة عامة استخدم getters/setters public
التحقق من الصحة تحقق من المدخلات في setters

بدون تغليف (❌ سيء)

JAVA
public class Student {
    public String name;
    public int age;
}

// أي شخص يمكنه تعديل البيانات مباشرة
Student s = new Student();
s.name = "أحمد";
s.age = -5;  // ❌ عمر سالب — غير منطقي!

مع تغليف (✅ جيد)

JAVA
public class Student {
    private String name;
    private int age;
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        if (name != null && !name.isEmpty()) {
            this.name = name;
        }
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if (age >= 0 && age <= 150) {
            this.age = age;
        } else {
            System.out.println("عمر غير صالح!");
        }
    }
}

// الاستخدام
Student s = new Student();
s.setName("أحمد");
s.setAge(-5);  // سيطبع "عمر غير صالح!" ولا يُغير القيمة

مثال كامل: حساب بنكي

JAVA
public class BankAccount {
    private String accountNumber;
    private String owner;
    private double balance;
    private boolean isActive;
    
    public BankAccount(String accountNumber, String owner, double initialDeposit) {
        this.accountNumber = accountNumber;
        this.owner = owner;
        this.balance = initialDeposit;
        this.isActive = true;
    }
    
    // Getter فقط — لا يمكن تغيير رقم الحساب
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public String getOwner() {
        return owner;
    }
    
    public double getBalance() {
        return balance;
    }
    
    public boolean isActive() {
        return isActive;
    }
    
    public void setActive(boolean active) {
        this.isActive = active;
    }
    
    public boolean deposit(double amount) {
        if (!isActive) {
            System.out.println("الحساب غير نشط!");
            return false;
        }
        if (amount <= 0) {
            System.out.println("المبلغ يجب أن يكون موجباً!");
            return false;
        }
        balance += amount;
        System.out.println("تم إيداع " + amount + " ريال. الرصيد: " + balance);
        return true;
    }
    
    public boolean withdraw(double amount) {
        if (!isActive) {
            System.out.println("الحساب غير نشط!");
            return false;
        }
        if (amount <= 0) {
            System.out.println("المبلغ يجب أن يكون موجباً!");
            return false;
        }
        if (amount > balance) {
            System.out.println("رصيد غير كافٍ!");
            return false;
        }
        balance -= amount;
        System.out.println("تم سحب " + amount + " ريال. الرصيد: " + balance);
        return true;
    }
    
    @Override
    public String toString() {
        return "الحساب: " + accountNumber + "، المالك: " + owner + 
               "، الرصيد: " + balance + " ريال";
    }
}

// الاستخدام
BankAccount account = new BankAccount("123456", "أحمد", 1000);
account.deposit(500);      // تم إيداع 500 ريال. الرصيد: 1500
account.withdraw(200);     // تم سحب 200 ريال. الرصيد: 1300
account.withdraw(2000);    // رصيد غير كافٍ!
System.out.println(account);

فوائد التغليف

الفائدة الوصف
حماية البيانات لا يمكن الوصول للمتغيرات مباشرة
التحقق من الصحة التحقق من المدخلات في setters
المرونة يمكنك تغيير الداخلي دون تأثير على المستخدمين
سهولة الصيانة الكود أكثر تنظيمًا ووضوحًا

مثال: فئة مع حقول فقط للقراءة

JAVA
public class Product {
    private final String id;      // لا يمكن تغييره بعد الإنشاء
    private final String name;    // لا يمكن تغييره
    private double price;         // يمكن تغييره
    
    public Product(String id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
    
    // Getters فقط
    public String getId() { return id; }
    public String getName() { return name; }
    public double getPrice() { return price; }
    
    // Setter للسعر فقط
    public void setPrice(double price) {
        if (price >= 0) {
            this.price = price;
        }
    }
}

❓ أسئلة شائعة

س هل يجب أن تكون جميع المتغيرات private؟
ج عادةً نعم. إذا كنت تريد مشاركة البيانات، استخدم getters/setters.
س ما الفرق بين private و protected؟
ج private: مرئي فقط داخل الفئة. protected: مرئي في الفئة والفئات الفرعية.
س هل يمكن أن يكون المُنشئ private؟
ج نعم، هذا يمنع إنشاء كائنات من خارج الفئة (مثل نمط Singleton).

📖 ملخص

📝 تمارين

  1. مستطيل: أنشئ فئة Rectangle مع getters/setters وتحقق من صحة الأبعاد
  2. طالب: أنشئ فئة Student مع تحقق من صحة الاسم والعمر والدرجة
  3. منتج: أنشئ فئة Product مع حقول للقراءة فقط وحقل سعر قابل للتغيير

الدرس التالي

في الدرس التالي، سنتعلم الوراثة — توسيع الفئات.

100%