Interface ایک معاہدہ ہے جو تجریدی طریقوں کے ایک سیٹ کی وضاحت کرتا ہے جسے ایک کلاس کو نافذ کرنا ہوتا ہے۔ Java اور Kotlin میں، انٹرفیس تجرید اور کثیر شکلیت کا بنیادی طریقہ کار ہیں۔ Java 8+ میں، انٹرفیس default اور static طریقے رکھ سکتے ہیں، Kotlin میں — ڈیفالٹ نفاذ۔ Google Android Developers (2025) کے مطابق، 90% Android پروجیکٹس میں آرکیٹیکچر کی تہوں — ریپوزٹریز، UseCases اور سروسز کی وضاحت کے لیے انٹرفیس استعمال ہوتے ہیں۔
اہم نکات
Interface ایک حوالہ قسم ہے جس میں تجریدی طریقے، مستقل اور ڈیفالٹ طریقے ہوتے ہیں۔ انٹرفیس کو نافذ کرنے والی کلاس کو اپنے تمام تجریدی طریقوں کے لیے نفاذ فراہم کرنا ہوتا ہے۔ Java میں، انٹرفیس حالت (مثال کے فیلڈز) نہیں رکھ سکتا؛ Kotlin بھی اس پابندی کی پیروی کرتا ہے لیکن رسائی کاروں کے ساتھ خصوصیات کو سپورٹ کرتا ہے۔
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 | Abstract Class |
|---|---|---|
| حالت (فیلڈز) | صرف static final مستقل | ہاں، کوئی بھی فیلڈز |
| تعمیر کنندگان | نہیں | ہاں |
| متعدد وراثت | ہاں (implements) | نہیں (extends ایک) |
| رسائی کے موڈیفائر | public (Java 8-)، default طریقے | تمام (private, protected, public) |
| کب استعمال کریں | غیر متعلقہ کلاسوں کے لیے معاہدہ | متعلقہ کلاسوں کے لیے مشترکہ بنیاد |
Clean Architecture میں، انٹرفیس اندرونی تہہ (domain) میں رکھے جاتے ہیں، اور نفاذ بیرونی تہہ (data) میں۔ یہ Dependency Rule کو برقرار رکھنے کی اجازت دیتا ہے: بیرونی تہہ اندرونی تہہ پر منحصر ہے، لیکن اس کے برعکس نہیں۔ تجریدی کلاسیں اکثر ٹیمپلیٹ طریقوں (Template Method pattern) کے لیے استعمال ہوتی ہیں۔
Kotlin انٹرفیس Java سے زیادہ لچکدار ہیں: وہ تجریدی خصوصیات کا اعلان کر سکتے ہیں اور طریقوں کے نفاذ فراہم کر سکتے ہیں۔ Java کے برعکس، Kotlin by کلیدی لفظ کے ذریعے نیابت کو سپورٹ کرتا ہے، جو Delegate پیٹرن کو نافذ کرتے ہوئے بوائلر پلیٹ کو طاقتور طریقے سے کم کرتا ہے۔
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 loggerUserService نیابت (by) کے ذریعے Logger انٹرفیس کو نافذ کرتا ہے۔ تمام log() کالز ریپر طریقے لکھے بغیر logger آبجیکٹ کو بھیج دی جاتی ہیں۔ یہ ترکیب کی ایک مثال ہے جس کے لیے Java میں 5-10 لائنوں کے بوائلر پلیٹ کوڈ کی ضرورت ہوگی۔
Clean Architecture for Android ایپلیکیشن کو واضح طور پر تہوں میں تقسیم کرتا ہے۔ انٹرفیس تہوں کے درمیان حدود کا کام کرتے ہیں: Domain ریپوزٹری اور UseCase انٹرفیس کی وضاحت کرتا ہے، Data نفاذ فراہم کرتا ہے۔ یہ کاروباری منطق کو تبدیل کیے بغیر نفاذ کو تبدیل کرنے کی اجازت دیتا ہے — Room سے Firebase یا REST سے GraphQL میں منتقلی کے وقت ایک اہم فائدہ۔
// 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 کی جانچ کی اجازت دیتا ہے۔
Default طریقے Java 8 میں پسماندہ مطابقت کو توڑے بغیر انٹرفیس کے ارتقائی توسیع کے لیے شامل کیے گئے۔ اگر ArrayList Collection میں شامل کردہ نئے stream() طریقہ کو نافذ نہیں کرتا، پرانا کوڈ کام کرتا رہتا۔ انٹرفیس میں static طریقے انٹرفیس سے متعلق افادیت کے طور پر کام کرتے ہیں — افادیت کلاسوں کا متبادل۔
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 کی خلاف ورزیوں کا باعث بنتی ہیں۔ آئیے تین عام مسائل دیکھتے ہیں۔
15+ طریقوں والا انٹرفیس Interface Segregation Principle (ISP) کی خلاف ورزی کرتا ہے۔ ایک مثال پرانا java.util.Dictionary ہے جس میں 10+ طریقے ہیں۔ حل: کئی چھوٹے انٹرفیس میں تقسیم کریں — ReadableRepository, WritableRepository, SearchableRepository۔ کلائنٹ (سروس) صرف ان طریقوں پر منحصر ہے جن کی اسے ضرورت ہے۔
کثیر شکلیت کی حقیقی ضرورت کے بغیر ہر کلاس کے لیے انٹرفیس بنانا Interface overkill اینٹی پیٹرن ہے۔ اشارہ: انٹرفیس کا بالکل ایک نفاذ ہے اور پروجیکٹ میں متبادل شامل کرنے کا کوئی منصوبہ نہیں ہے۔ حل: صرف اس وقت انٹرفیس شامل کریں جب دوسرا نفاذ کا آپشن ظاہر ہو یا جانچ کے لیے موک کی ضرورت ہو۔
اکثر پوچھے گئے سوالات
Interface صرف ایک معاہدہ (طریقوں کے دستخط) کی وضاحت کرتا ہے، حالت نہیں رکھ سکتا اور متعدد وراثت کو سپورٹ کرتا ہے۔ Abstract class میں فیلڈز، تعمیر کنندگان اور نافذ کردہ طریقے ہو سکتے ہیں، لیکن ایک کلاس صرف ایک تجریدی کلاس کو وراثت میں لے سکتی ہے۔ Java 8 سے، انٹرفیس کو default اور static طریقے ملے ہیں، جس سے فرق کم ہوا ہے۔
ہاں، Java اور Kotlin میں انٹرفیس وراثت کو سپورٹ کرتے ہیں۔ public interface AdvancedRepository<T> extends Repository<T>, Pageable ایک انٹرفیس ہے جو دو دیگر کو یکجا کرتا ہے۔ AdvancedRepository کو نافذ کرنے والی کلاس کو دونوں والدین انٹرفیس کے تمام طریقوں کو نافذ کرنا ہوگا۔ متعدد وراثت صرف انٹرفیس کے لیے اجازت ہے۔
فنکشنل انٹرفیس ایک ہی تجریدی طریقہ (SAM — Single Abstract Method) والا انٹرفیس ہے۔ @FunctionalInterface اینوٹیشن اس پابندی کی ضمانت دیتا ہے۔ مثالیں: Runnable, Callable, Comparator, Consumer۔ فنکشنل انٹرفیس Java 8 lambda اظہار کی بنیاد ہیں: () -> System.out.println() Runnable کو نافذ کرتا ہے۔
Default طریقے تمام نافذ کرنے والی کلاسوں کو تبدیل کیے بغیر انٹرفیس میں نئے طریقے شامل کرنے کی اجازت دیتے ہیں۔ مثال کے طور پر، Java 8 نے Collection میں stream() کو default طریقہ کے طور پر شامل کیا۔ اس طریقہ کار کے بغیر، foreach()، stream() اور دیگر طریقوں کے لیے JDK میں ہزاروں کلاسوں میں تبدیلی کی ضرورت ہوتی۔ Default پسماندہ مطابقت رکھنے والا توسیع کا ایک طریقہ ہے۔
Kotlin کلاسوں کی متعدد وراثت کو منع کرتا ہے لیکن انٹرفیس کے متعدد نفاذ کی اجازت دیتا ہے۔ اگر دو انٹرفیس میں ایک ہی دستخط اور ڈیفالٹ نفاذ والا طریقہ ہے، کمپائلر super<InterfaceName>.method() کال کے ساتھ واضح اوور رائڈنگ کا تقاضا کرتا ہے۔ یہ compilation کی سطح پر diamond problem کو حل کرتا ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں