Interface: جوہر، Android کے لیے Java اور Kotlin میں معاہدے

مصنف: IT Sectr اشاعت: 2026-02-18 مطالعے کا وقت: 9 منٹ

Interface ایک معاہدہ ہے جو تجریدی طریقوں کے ایک سیٹ کی وضاحت کرتا ہے جسے ایک کلاس کو نافذ کرنا ہوتا ہے۔ Java اور Kotlin میں، انٹرفیس تجرید اور کثیر شکلیت کا بنیادی طریقہ کار ہیں۔ Java 8+ میں، انٹرفیس default اور static طریقے رکھ سکتے ہیں، Kotlin میں — ڈیفالٹ نفاذ۔ Google Android Developers (2025) کے مطابق، 90% Android پروجیکٹس میں آرکیٹیکچر کی تہوں — ریپوزٹریز، UseCases اور سروسز کی وضاحت کے لیے انٹرفیس استعمال ہوتے ہیں۔

اہم نکات

  • Interface ایک تجریدی قسم ہے جو نفاذ کے بغیر طریقوں کے دستخطوں کی وضاحت کرتی ہے (Java 8 سے پہلے)
  • Implements ایک کلیدی لفظ ہے جو کلاس کو انٹرفیس سے جوڑتا ہے؛ ایک کلاس متعدد انٹرفیس نافذ کر سکتی ہے
  • Default method Java انٹرفیس میں نفاذ کے ساتھ ایک طریقہ، Java 8 میں پسماندہ مطابقت کے لیے شامل کیا گیا
  • Kotlin interface گیٹرز کے ساتھ خصوصیات اور طریقوں کے نفاذ کو سپورٹ کرتا ہے، بہت سے منظرناموں میں abstract class کی جگہ لیتا ہے
  • Markup interface ایک خالی انٹرفیس ہے جو مارکر کے طور پر استعمال ہوتا ہے (Serializable, Cloneable, RandomAccess)

Java اور Kotlin میں Interface کیا ہے؟

Interface ایک حوالہ قسم ہے جس میں تجریدی طریقے، مستقل اور ڈیفالٹ طریقے ہوتے ہیں۔ انٹرفیس کو نافذ کرنے والی کلاس کو اپنے تمام تجریدی طریقوں کے لیے نفاذ فراہم کرنا ہوتا ہے۔ Java میں، انٹرفیس حالت (مثال کے فیلڈز) نہیں رکھ سکتا؛ Kotlin بھی اس پابندی کی پیروی کرتا ہے لیکن رسائی کاروں کے ساتھ خصوصیات کو سپورٹ کرتا ہے۔

Java
public interface Repository {
    T findById(Long id);
    List findAll();
    T save(T entity);
    void deleteById(Long id);
    
    default long count() {
        return findAll().size();
    }
}

@Entity
public class UserEntity {
    private Long id;
    private String email;
    // گیٹرز اور سیٹرز
}

public class UserRepositoryImpl implements Repository {
    private final EntityManager em;
    
    public UserEntity findById(Long id) {
        return em.find(UserEntity.class, id);
    }
    
    public List findAll() {
        return em.createQuery("FROM UserEntity", UserEntity.class)
                .getResultList();
    }
    // دوسرے طریقے
}

Repository<T> CRUD طریقوں کے ساتھ ایک عام انٹرفیس ہے۔ ڈیفالٹ طریقہ count() ایک ڈیفالٹ نفاذ فراہم کرتا ہے جسے اوور رائڈ کیا جا سکتا ہے۔ UserRepositoryImpl ڈیٹا تک رسائی کے لیے EntityManager استعمال کرکے انٹرفیس کو نافذ کرتا ہے۔ یہ نقطہ نظر حقیقی ڈیٹا بیس کے بغیر انٹرفیس موک کے ذریعے ڈیٹا کی تہہ کی جانچ کی اجازت دیتا ہے۔

Interface vs abstract class: کب کیا انتخاب کریں

انٹرفیس اور تجریدی کلاس کے درمیان انتخاب مشترکہ حالت کی موجودگی اور اقسام کے درمیان تعلقات پر منحصر ہے۔ انٹرفیس ایک معاہدہ (کلاس کیا کر سکتی ہے) کی وضاحت کرتا ہے، تجریدی کلاس ایک مشترکہ نفاذ (کلاس کیا ہے) کی وضاحت کرتی ہے۔

معیارInterfaceAbstract Class
حالت (فیلڈز)صرف static final مستقلہاں، کوئی بھی فیلڈز
تعمیر کنندگاننہیںہاں
متعدد وراثتہاں (implements)نہیں (extends ایک)
رسائی کے موڈیفائرpublic (Java 8-)، default طریقےتمام (private, protected, public)
کب استعمال کریںغیر متعلقہ کلاسوں کے لیے معاہدہمتعلقہ کلاسوں کے لیے مشترکہ بنیاد

Clean Architecture میں، انٹرفیس اندرونی تہہ (domain) میں رکھے جاتے ہیں، اور نفاذ بیرونی تہہ (data) میں۔ یہ Dependency Rule کو برقرار رکھنے کی اجازت دیتا ہے: بیرونی تہہ اندرونی تہہ پر منحصر ہے، لیکن اس کے برعکس نہیں۔ تجریدی کلاسیں اکثر ٹیمپلیٹ طریقوں (Template Method pattern) کے لیے استعمال ہوتی ہیں۔

Kotlin میں Interface: خصوصیات اور مندوبین

Kotlin انٹرفیس Java سے زیادہ لچکدار ہیں: وہ تجریدی خصوصیات کا اعلان کر سکتے ہیں اور طریقوں کے نفاذ فراہم کر سکتے ہیں۔ Java کے برعکس، Kotlin by کلیدی لفظ کے ذریعے نیابت کو سپورٹ کرتا ہے، جو Delegate پیٹرن کو نافذ کرتے ہوئے بوائلر پلیٹ کو طاقتور طریقے سے کم کرتا ہے۔

Kotlin
interface ApiService {
    val baseUrl: String  // تجریدی خاصیت
    
    suspend fun fetchData(): Result>
    
    fun getEndpoint(path: String): String {
        return "$baseUrl/$path"  // ڈیفالٹ نفاذ
    }
}

class RetrofitApiService(
    override val baseUrl: String
) : ApiService {
    private val client = Retrofit.Builder()
        .baseUrl(baseUrl)
        .build()
    
    override suspend fun fetchData(): Result> {
        // درخواست کا نفاذ
    }
}

// by کے ذریعے نیابت
interface Logger {
    fun log(message: String)
}

class ConsoleLogger : Logger {
    override fun log(message: String) = println(message)
}

class UserService(logger: Logger) : Logger by logger

UserService نیابت (by) کے ذریعے Logger انٹرفیس کو نافذ کرتا ہے۔ تمام log() کالز ریپر طریقے لکھے بغیر logger آبجیکٹ کو بھیج دی جاتی ہیں۔ یہ ترکیب کی ایک مثال ہے جس کے لیے Java میں 5-10 لائنوں کے بوائلر پلیٹ کوڈ کی ضرورت ہوگی۔

Clean Architecture Android میں Interface

Clean Architecture for Android ایپلیکیشن کو واضح طور پر تہوں میں تقسیم کرتا ہے۔ انٹرفیس تہوں کے درمیان حدود کا کام کرتے ہیں: Domain ریپوزٹری اور UseCase انٹرفیس کی وضاحت کرتا ہے، Data نفاذ فراہم کرتا ہے۔ یہ کاروباری منطق کو تبدیل کیے بغیر نفاذ کو تبدیل کرنے کی اجازت دیتا ہے — Room سے Firebase یا REST سے GraphQL میں منتقلی کے وقت ایک اہم فائدہ۔

Kotlin
// Domain layer — انٹرفیس (معاہدہ)
interface UserRepository {
    suspend fun getUser(id: String): User
    suspend fun updateUser(user: User)
}

// Domain layer — use case (انٹرفیس پر منحصر)
class GetUserUseCase(
    private val repository: UserRepository
) {
    suspend operator fun invoke(id: String): Result {
        return runCatching { repository.getUser(id) }
    }
}

// Data layer — نفاذ
class UserRepositoryImpl(
    private val api: UserApi,
    private val dao: UserDao
) : UserRepository {
    override suspend fun getUser(id: String): User {
        val cached = dao.getUser(id)
        if (cached != null) return cached
        val remote = api.fetchUser(id)
        dao.insertUser(remote)
        return remote
    }
    // updateUser...
}

UserRepository domain تہہ میں ایک انٹرفیس ہے۔ GetUserUseCase نفاذ پر نہیں، انٹرفیس پر منحصر ہے۔ data تہہ میں UserRepositoryImpl API اور مقامی ڈیٹا بیس کو ملا کر انٹرفیس کو نافذ کرتا ہے۔ یہ آرکیٹیکچر ڈیٹا بیس یا نیٹ ورک ترتیب دیے بغیر موک ریپوزٹری کے ساتھ UseCases کی جانچ کی اجازت دیتا ہے۔

Java 8+ میں default اور static طریقے

Default طریقے Java 8 میں پسماندہ مطابقت کو توڑے بغیر انٹرفیس کے ارتقائی توسیع کے لیے شامل کیے گئے۔ اگر ArrayList Collection میں شامل کردہ نئے stream() طریقہ کو نافذ نہیں کرتا، پرانا کوڈ کام کرتا رہتا۔ انٹرفیس میں static طریقے انٹرفیس سے متعلق افادیت کے طور پر کام کرتے ہیں — افادیت کلاسوں کا متبادل۔

Java
public interface Vehicle {
    void start();
    void stop();
    
    default void honk() {
        System.out.println("Beep!");
    }
    
    static Vehicle of(String type) {
        if ("car".equals(type)) return new Car();
        return new Bicycle();
    }
    
    // مستقل
    String CATEGORY = "transport";
}

Default طریقے diamond problem کو حل کرتے ہیں: اگر ایک کلاس ایک ہی default طریقہ والے دو انٹرفیس نافذ کرتی ہے، کمپائلر واضح اوور رائڈنگ کا تقاضا کرتا ہے۔ Static طریقے انٹرفیس کے نام کے ذریعے بلائے جاتے ہیں — Vehicle.of("car")، مثال کے بغیر۔

انٹرفیس ڈیزائن میں عام غلطیاں

انٹرفیس ڈیزائن میں غلطیاں نازک کوڈ، جانچ کی پیچیدگی اور SOLID کی خلاف ورزیوں کا باعث بنتی ہیں۔ آئیے تین عام مسائل دیکھتے ہیں۔

Interface Pollution — ایک انٹرفیس میں بہت زیادہ طریقے

15+ طریقوں والا انٹرفیس Interface Segregation Principle (ISP) کی خلاف ورزی کرتا ہے۔ ایک مثال پرانا java.util.Dictionary ہے جس میں 10+ طریقے ہیں۔ حل: کئی چھوٹے انٹرفیس میں تقسیم کریں — ReadableRepository, WritableRepository, SearchableRepository۔ کلائنٹ (سروس) صرف ان طریقوں پر منحصر ہے جن کی اسے ضرورت ہے۔

ضرورت سے زیادہ تجرید — ہر کلاس کے لیے انٹرفیس

کثیر شکلیت کی حقیقی ضرورت کے بغیر ہر کلاس کے لیے انٹرفیس بنانا Interface overkill اینٹی پیٹرن ہے۔ اشارہ: انٹرفیس کا بالکل ایک نفاذ ہے اور پروجیکٹ میں متبادل شامل کرنے کا کوئی منصوبہ نہیں ہے۔ حل: صرف اس وقت انٹرفیس شامل کریں جب دوسرا نفاذ کا آپشن ظاہر ہو یا جانچ کے لیے موک کی ضرورت ہو۔

اکثر پوچھے گئے سوالات

Java میں interface، abstract class سے کیسے مختلف ہے؟

Interface صرف ایک معاہدہ (طریقوں کے دستخط) کی وضاحت کرتا ہے، حالت نہیں رکھ سکتا اور متعدد وراثت کو سپورٹ کرتا ہے۔ Abstract class میں فیلڈز، تعمیر کنندگان اور نافذ کردہ طریقے ہو سکتے ہیں، لیکن ایک کلاس صرف ایک تجریدی کلاس کو وراثت میں لے سکتی ہے۔ Java 8 سے، انٹرفیس کو default اور static طریقے ملے ہیں، جس سے فرق کم ہوا ہے۔

کیا انٹرفیس کسی دوسرے انٹرفیس کو وراثت میں لے سکتا ہے؟

ہاں، Java اور Kotlin میں انٹرفیس وراثت کو سپورٹ کرتے ہیں۔ public interface AdvancedRepository<T> extends Repository<T>, Pageable ایک انٹرفیس ہے جو دو دیگر کو یکجا کرتا ہے۔ AdvancedRepository کو نافذ کرنے والی کلاس کو دونوں والدین انٹرفیس کے تمام طریقوں کو نافذ کرنا ہوگا۔ متعدد وراثت صرف انٹرفیس کے لیے اجازت ہے۔

Java میں فنکشنل انٹرفیس کیا ہے؟

فنکشنل انٹرفیس ایک ہی تجریدی طریقہ (SAM — Single Abstract Method) والا انٹرفیس ہے۔ @FunctionalInterface اینوٹیشن اس پابندی کی ضمانت دیتا ہے۔ مثالیں: Runnable, Callable, Comparator, Consumer۔ فنکشنل انٹرفیس Java 8 lambda اظہار کی بنیاد ہیں: () -> System.out.println() Runnable کو نافذ کرتا ہے۔

Java انٹرفیس میں default طریقوں کی ضرورت کیوں ہے؟

Default طریقے تمام نافذ کرنے والی کلاسوں کو تبدیل کیے بغیر انٹرفیس میں نئے طریقے شامل کرنے کی اجازت دیتے ہیں۔ مثال کے طور پر، Java 8 نے Collection میں stream() کو default طریقہ کے طور پر شامل کیا۔ اس طریقہ کار کے بغیر، foreach()، stream() اور دیگر طریقوں کے لیے JDK میں ہزاروں کلاسوں میں تبدیلی کی ضرورت ہوتی۔ Default پسماندہ مطابقت رکھنے والا توسیع کا ایک طریقہ ہے۔

Kotlin متعدد وراثت کے مسئلے کو کیسے حل کرتا ہے؟

Kotlin کلاسوں کی متعدد وراثت کو منع کرتا ہے لیکن انٹرفیس کے متعدد نفاذ کی اجازت دیتا ہے۔ اگر دو انٹرفیس میں ایک ہی دستخط اور ڈیفالٹ نفاذ والا طریقہ ہے، کمپائلر super<InterfaceName>.method() کال کے ساتھ واضح اوور رائڈنگ کا تقاضا کرتا ہے۔ یہ compilation کی سطح پر diamond problem کو حل کرتا ہے۔

خلاصہ

  • Interface ایک معاہدہ ہے جو ان طریقوں کی وضاحت کرتا ہے جنہیں کلاس کو نافذ کرنا ہوتا ہے؛ Java اور Kotlin میں کثیر شکلیت کا بنیادی طریقہ کار
  • Java 8+ نے انٹرفیس میں default اور static طریقے شامل کیے، تجریدی کلاسوں کے ساتھ فرق کم کیا
  • Kotlin interfaces تجریدی خصوصیات، ڈیفالٹ نفاذ اور by کے ذریعے نیابت کو سپورٹ کرتے ہیں
  • Clean Architecture Domain اور Data تہوں کے درمیان حد کے طور پر انٹرفیس استعمال کرتی ہے
  • Interface Segregation Principle بڑے انٹرفیس کو مخصوص انٹرفیس میں تقسیم کرنے کا تقاضا کرتا ہے
  • فنکشنل انٹرفیس (Single Abstract Method) lambda اظہار اور Stream API کی بنیاد ہیں
  • سفارش: انٹرفیس اس وقت شامل کریں جب دوسرا نفاذ ظاہر ہو یا جانچ کے لیے موک کی ضرورت ہو

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں