Interface: सार, Android के लिए Java और Kotlin में कॉन्ट्रैक्ट

लेखक: IT Sectr प्रकाशित: 2026-02-18 पढ़ने का समय: 9 मिनट

Interface एक कॉन्ट्रैक्ट है जो अमूर्त विधियों के एक सेट को परिभाषित करता है जिन्हें क्लास को लागू करना होता है। Java और Kotlin में, इंटरफ़ेस एब्स्ट्रैक्शन और पॉलिमॉर्फिज़म की प्राथमिक प्रणाली हैं। Java 8+ में, इंटरफ़ेस default और static विधियाँ रख सकते हैं, Kotlin में — डिफ़ॉल्ट इम्प्लीमेंटेशन। Google Android Developers (2025) के अनुसार, 90% Android प्रोजेक्ट्स में इंटरफ़ेस का उपयोग आर्किटेक्चर लेयर — रिपॉज़िटरी, UseCase और सेवाओं को परिभाषित करने के लिए किया जाता है।

मुख्य बिंदु

  • 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 का उपयोग करके इंटरफ़ेस को लागू करता है। यह दृष्टिकोण वास्तविक डेटाबेस के बिना इंटरफ़ेस mock के माध्यम से डेटा लेयर का परीक्षण करने की अनुमति देता है।

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 पैटर्न को लागू करते समय boilerplate को शक्तिशाली रूप से कम करता है।

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 लाइन boilerplate कोड की आवश्यकता होगी।

Clean Architecture Android में Interface

Clean Architecture 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 और स्थानीय डेटाबेस को मिलाकर इंटरफ़ेस को लागू करता है। यह आर्किटेक्चर डेटाबेस या नेटवर्क सेट किए बिना mock रिपॉज़िटरी के साथ 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 एंटीपैटर्न है। संकेत: इंटरफ़ेस का ठीक एक इम्प्लीमेंटेशन है, और प्रोजेक्ट में विकल्प जोड़ने की कोई योजना नहीं है। समाधान: इंटरफ़ेस तभी जोड़ें जब दूसरा इम्प्लीमेंटेशन विकल्प दिखाई दे या परीक्षण के लिए mock की आवश्यकता हो।

अक्सर पूछे जाने वाले प्रश्न

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 लैम्ब्डा एक्सप्रेशन का आधार हैं: () -> System.out.println() Runnable को लागू करता है।

Java इंटरफ़ेस में default विधियों की आवश्यकता क्यों है?

Default विधियाँ सभी लागू करने वाली क्लासों को बदले बिना इंटरफ़ेस में नई विधियाँ जोड़ने की अनुमति देती हैं। उदाहरण के लिए, Java 8 ने Collection में stream() को default विधि के रूप में जोड़ा। इस प्रणाली के बिना, foreach(), stream() और अन्य विधियों के लिए JDK में हज़ारों क्लासों में बदलाव की आवश्यकता होती। Default पिछड़ी-संगत विस्तार का एक तरीका है।

Kotlin एकाधिक वंशानुक्रम की समस्या कैसे हल करता है?

Kotlin क्लासों के एकाधिक वंशानुक्रम को प्रतिबंधित करता है लेकिन इंटरफ़ेस के एकाधिक इम्प्लीमेंटेशन की अनुमति देता है। यदि दो इंटरफ़ेस में समान हस्ताक्षर और डिफ़ॉल्ट इम्प्लीमेंटेशन वाली विधि है, तो कंपाइलर super<InterfaceName>.method() कॉल के साथ स्पष्ट ओवरराइडिंग की आवश्यकता रखता है। यह कंपाइलेशन स्तर पर diamond problem को हल करता है।

सारांश

  • Interface एक कॉन्ट्रैक्ट है जो उन विधियों को परिभाषित करता है जिन्हें क्लास को लागू करना होता है; Java और Kotlin में पॉलिमॉर्फिज़म की प्राथमिक प्रणाली
  • Java 8+ ने इंटरफ़ेस में default और static विधियाँ जोड़ीं, अमूर्त क्लास के साथ अंतर कम किया
  • Kotlin interfaces अमूर्त प्रॉपर्टी, डिफ़ॉल्ट इम्प्लीमेंटेशन और by के माध्यम से डेलिगेशन का समर्थन करते हैं
  • Clean Architecture Domain और Data लेयरों के बीच सीमा के रूप में इंटरफ़ेस का उपयोग करती है
  • Interface Segregation Principle बड़े इंटरफ़ेस को विशिष्ट इंटरफ़ेस में विभाजित करने की आवश्यकता रखता है
  • फंक्शनल इंटरफ़ेस (Single Abstract Method) लैम्ब्डा एक्सप्रेशन और Stream API का आधार हैं
  • अनुशंसा: इंटरफ़ेस तब जोड़ें जब दूसरा इम्प्लीमेंटेशन दिखाई दे या परीक्षण के लिए mock की आवश्यकता हो

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें