الفئات المتداخلة الثابتة
عرّف فئات متداخلة ثابتة بوصفها أنواعًا مساعدة مرتبطة دون مرجع إلى كائن الفئة الحاوية
الفئات المتداخلة الثابتة درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
الأصناف الساكنة المتداخلة
يُعرَّف الصنف الساكن المتداخل داخل صنف آخر باستخدام الكلمة المفتاحية static. ولا يملك مرجعًا إلى مثيل الصنف الحاوي — فهو مجمَّع معه منطقيًا فقط.
تعريف صنف ساكن متداخل
استخدم اسم الصنف الخارجي للوصول إلى الصنف المتداخل من خارجه.
class LinkedList<T> {
private Node<T> head;
// Static nested class — no outer instance reference
private static class Node<T> {
T data;
Node<T> next;
Node(T data) { this.data = data; }
}
public void addFirst(T item) {
Node<T> node = new Node<>(item);
node.next = head;
head = node;
}
}الوصول من الخارج
أشِر إلى الصنف الساكن المتداخل العام باستخدام OuterClass.InnerClass.
class Builder {
public static class Config {
public final String host;
public final int port;
Config(String host, int port) {
this.host = host; this.port = port;
}
}
}
Builder.Config config = new Builder.Config("localhost", 8080);
System.out.println(config.host + ":" + config.port); // localhost:8080الصنف الساكن المتداخل مقارنةً بالصنف الداخلي
الفرق الرئيسي: لا تملك الأصناف الساكنة المتداخلة مرجعًا ضمنيًا إلى مثيل الصنف الخارجي، بينما تملك الأصناف الداخلية (غير الساكنة) هذا المرجع.
class Outer {
private int x = 10;
// Static nested: no access to x
static class StaticNested {
void doSomething() {
// System.out.println(x); // compile error — no outer reference!
System.out.println("Static nested");
}
}
// Inner class: has access to x
class Inner {
void doSomething() {
System.out.println(x); // 10 — can access outer fields
}
}
}نمط Builder باستخدام صنف ساكن متداخل
يستخدم نمط Builder التقليدي صنفًا ساكنًا متداخلًا، ولذلك لا يحتاج المستدعون إلى مثيل خارجي لإنشاء أداة البناء.
class Pizza {
private final String size, crust;
private final List<String> toppings;
private Pizza(Builder b) {
this.size = b.size; this.crust = b.crust; this.toppings = List.copyOf(b.toppings);
}
public static class Builder {
private String size = "medium", crust = "thin";
private List<String> toppings = new ArrayList<>();
public Builder size(String s) { this.size = s; return this; }
public Builder crust(String c) { this.crust = c; return this; }
public Builder topping(String t) { this.toppings.add(t); return this; }
public Pizza build() { return new Pizza(this); }
}
}Entry في الخرائط
تُعد Map.Entry واجهة ساكنة متداخلة معروفة، وتُستخدم للتكرار على أزواج المفتاح والقيمة.
import java.util.*;
Map<String, Integer> scores = Map.of("Alice", 95, "Bob", 87, "Carol", 92);
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.printf("%-10s: %d%n", entry.getKey(), entry.getValue());
}
// Modern: using var
for (var entry : scores.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}الاختبار باستخدام صنف ساكن متداخل
في اختبارات الوحدات، يمكن لصنف ساكن متداخل أن يحتوي على تجهيزات الاختبار أو تطبيقات وهمية محصورة ضمن صنف الاختبار.
class UserServiceTest {
// Static nested fake/stub — no outer instance needed
static class FakeUserRepository implements UserRepository {
private final Map<Long, User> store = new HashMap<>();
public void save(User u) { store.put(u.id(), u); }
public Optional<User> findById(long id) {
return Optional.ofNullable(store.get(id));
}
}
// @Test methods use FakeUserRepository
void testFindUser() {
FakeUserRepository repo = new FakeUserRepository();
// ...
}
}الصنف الساكن المتداخل لمنطق المجال
اجمع الأنواع ذات الصلة باستخدام أصناف ساكنة متداخلة لتحسين التنظيم في نماذج المجال.
class Order {
private final long id;
private final List<LineItem> items;
// Static nested — logically belongs to Order, no outer reference needed
public static class LineItem {
public final String sku;
public final int quantity;
public final double unitPrice;
public LineItem(String sku, int qty, double price) {
this.sku = sku; this.quantity = qty; this.unitPrice = price;
}
public double total() { return quantity * unitPrice; }
}
// ...
}مقارنة: الصنف الساكن المتداخل والصنف الأعلى مستوى
فضّل الصنف الساكن المتداخل عندما يُستخدم الصنف في سياق الصنف الخارجي فقط. واستخدم صنفًا أعلى مستوى عندما تكون قابلية استخدامه أوسع.
الصنف الساكن المتداخل مع الأنواع العامة
تشارك الأصناف الساكنة المتداخلة في الأنواع العامة بالطريقة نفسها التي تشارك بها الأصناف الأعلى مستوى.
class Pair<A, B> {
// Static nested with its own type params
public static class Mutable<X, Y> {
public X first;
public Y second;
public Mutable(X first, Y second) {
this.first = first; this.second = second;
}
}
public static <X, Y> Mutable<X, Y> mutableOf(X x, Y y) {
return new Mutable<>(x, y);
}
}
Pair.Mutable<String, Integer> p = Pair.mutableOf("Alice", 30);
System.out.println(p.first + " is " + p.second); // Alice is 30كفاءة الذاكرة
لا تحتفظ الأصناف الساكنة المتداخلة بمرجع إلى المثيل الخارجي. ويمنع ذلك الاحتفاظ غير المقصود بالكائن الخارجي في الذاكرة، مما قد يسبب تسرّبات للذاكرة في البنى طويلة العمر.
تحقق سريع
ما الذي يميز الصنف الساكن المتداخل عن الصنف الداخلي (غير الساكن)؟
مراجعة: الأصناف الساكنة المتداخلة
أهم النقاط:
- تُجمع الأصناف الساكنة المتداخلة مع الصنف الخارجي، لكنها لا تملك مرجعًا إلى مثيل خارجي
- الوصول من الخارج: OuterClass.NestedClass
- يعني عدم وجود مرجع ضمني عدم الاحتفاظ غير المقصود بمثيل الصنف الخارجي في الذاكرة
- يستخدم نمط Builder عادةً صنف Builder ساكنًا متداخلًا
- تُعد Map.Entry واجهة ساكنة متداخلة معروفة
- فضّل الصنف الساكن المتداخل عندما لا يحتاج الصنف الداخلي إلى الوصول إلى مثيل الصنف الخارجي
الأسئلة الشائعة
هل درس «الفئات المتداخلة الثابتة» مجاني؟
نعم — نص درس «الفئات المتداخلة الثابتة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «الفئات المتداخلة الثابتة»؟
عرّف فئات متداخلة ثابتة بوصفها أنواعًا مساعدة مرتبطة دون مرجع إلى كائن الفئة الحاوية تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «الفئات المتداخلة الثابتة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الفئات المتداخلة الثابتة
- الفئات الداخلية والوصول إلى الفئة الخارجية
- الفئات المحلية والمجهولة
- اختيار استراتيجية التداخل المناسبة