Interface: mahiyyəti, Java və Kotlin-də Android üçün kontraktlar

Müəllif: IT Sectr Dərc olunub: 2026-02-18 Oxuma vaxtı: 9 dəq

Interface — sinifin tətbiq etməli olduğu abstrakt metodlar toplusunu müəyyən edən kontraktdır. Java və Kotlin-də interfeyslər abstraksiya və polimorfizmin əsas mexanizmidir. Java 8+-da interfeyslər default və static metodlar ehtiva edə bilər, Kotlin-də isə standart tətbiqlər ola bilər. Google Android Developers (2025) məlumatına görə, interfeyslər Android layihələrinin 90%-də arxitektura qatlarını — repozitoriləri, UseCase və xidmətləri təyin etmək üçün istifadə olunur.

Əsas məqamlar

  • Interface — tətbiq olmadan metodların siqnaturasını təyin edən abstrakt tip (Java 8-dən əvvəl)
  • Implements — sinifi interfeyslə birləşdirən açar söz; sinif bir neçə interfeysi tətbiq edə bilər
  • Default method — Java interfeysində tətbiqi olan metod, Java 8-də geriyə uyğunluq üçün əlavə edilib
  • Kotlin interface getter-lərlə xassələri və metod tətbiqlərini dəstəkləyir, bir çox ssenaridə abstract class-ı əvəz edir
  • Markup interface — etiket kimi istifadə olunan boş interfeys (Serializable, Cloneable, RandomAccess)

Java və Kotlin-də Interface nədir?

Interface — abstrakt metodlar, sabitlər və standart metodlar ehtiva edən istinad tipidir. İnterfeysi tətbiq edən sinif onun bütün abstrakt metodlarının tətbiqini təmin etməlidir. Java-da interfeys vəziyyətə (instansiya sahələrinə) malik ola bilməz, Kotlin də bu məhdudiyyətə riayət edir, lakin aksessorlarla xassələri dəstəkləyir.

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;
    // getterlər və setterlər
}

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();
    }
    // qalan metodlar
}

Repository<T> — CRUD metodları olan generic interfeys. Default-metod count() standart tətbiqi təmin edir, onu ləğv etmək olar. UserRepositoryImpl interfeysi tətbiq edir, məlumatlara giriş üçün EntityManager istifadə edir. Bu yanaşma real verilənlər bazası olmadan interfeysin mock vasitəsilə məlumat qatını test etməyə imkan verir.

Interface vs abstract class: nə vaxt hansı seçilməli

İnterfeys və abstrakt sinif arasında seçim ümumi vəziyyətin mövcudluğundan və tiplər arasındakı münasibətlərdən asılıdır. İnterfeys kontraktı (sinifin nə edə biləcəyini), abstrakt sinif isə ümumi tətbiqi (sinifin nə olduğunu) müəyyən edir.

KriteriyaInterfaceAbstract Class
Vəziyyət (sahələr)Yalnız static final sabitlərBəli, istənilən sahələr
KonstruktorlarXeyrBəli
Çoxlu mirasBəli (implements)Xeyr (extends bir)
Giriş modifikatorlarıpublic (Java 8-), default metodlarHamısı (private, protected, public)
Nə vaxt istifadə etməliƏlaqəsiz siniflər üçün kontraktQohum siniflər üçün ümumi baza

Clean Architecture-də interfeyslər daxili qatda (domain), tətbiqlər isə xarici qatda (data) yerləşir. Bu, Asılılıq Qaydasına (Dependency Rule) riayət etməyə imkan verir: xarici qat daxili qatdan asılıdır, əksinə deyil. Abstrakt siniflər daha çox şablon metodlar üçün (Template Method pattern) istifadə olunur.

Kotlin-də Interface: xassələr və deleqatlar

Kotlin interfeysləri Java-dan daha çevikdir: onlar abstrakt xassələr elan edə və metod tətbiqləri təmin edə bilər. Java-dan fərqli olaraq, Kotlin by açar sözü ilə deleqasiyanı dəstəkləyir və bu, Delegate nümunəsini tətbiq edərkən boilerplate-ı əhəmiyyətli dərəcədə azaldır.

Kotlin
interface ApiService {
    val baseUrl: String  // abstrakt xassə
    
    suspend fun fetchData(): Result>
    
    fun getEndpoint(path: String): String {
        return "$baseUrl/$path"  // standart tətbiq
    }
}

class RetrofitApiService(
    override val baseUrl: String
) : ApiService {
    private val client = Retrofit.Builder()
        .baseUrl(baseUrl)
        .build()
    
    override suspend fun fetchData(): Result> {
        // sorğunun icrası
    }
}

// by ilə deleqasiya
interface Logger {
    fun log(message: String)
}

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

class UserService(logger: Logger) : Logger by logger

UserService Logger interfeysini deleqasiya (by) vasitəsilə tətbiq edir. Bütün log() çağırışları sarğı metodları yazmadan logger obyektinə yönləndirilir. Bu, Java-da 5-10 sətir boilerplate-kod tələb edəcək kompozisiya nümunəsidir.

Clean Architecture Android-də Interface

Clean Architecture Android üçün tətbiqi aydın şəkildə qatlara ayırır. İnterfeyslər qatlar arasında sərhəd rolunu oynayır: Domain repozitorilərin və UseCase-lərin interfeyslərini təyin edir, Data tətbiqləri təmin edir. Bu, biznes məntiqini dəyişmədən tətbiqləri əvəz etməyə imkan verir — Room-dan Firebase-ə və ya REST-dən GraphQL-ə miqrasiya zamanı əsas üstünlük.

Kotlin
// Domain qatı — interfeys (kontrakt)
interface UserRepository {
    suspend fun getUser(id: String): User
    suspend fun updateUser(user: User)
}

// Domain qatı — use case (interfeysdən asılıdır)
class GetUserUseCase(
    private val repository: UserRepository
) {
    suspend operator fun invoke(id: String): Result {
        return runCatching { repository.getUser(id) }
    }
}

// Data qatı — tətbiq
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 qatında interfeys. GetUserUseCase tətbiqdən deyil, interfeysdən asılıdır. Data qatında UserRepositoryImpl interfeysi tətbiq edir, API və yerli verilənlər bazasını birləşdirir. Bu arxitektura verilənlər bazası və ya şəbəkə konfiqurasiyası olmadan UseCase-i mock-repozitori ilə test etməyə imkan verir.

Java 8+-da Default və static metodlar

Default metodlar Java 8-də geriyə uyğunluğu pozmadan interfeysləri təkamül yolu ilə genişləndirmək üçün əlavə edilmişdir. ArrayList Collection-a əlavə edilmiş yeni stream() metodunu tətbiq etməsəydi, köhnə kod işləməyə davam edərdi. İnterfeyslərdə static metodlar interfeyslə əlaqəli alətlər üçün xidmət edir — alət siniflərinə alternativ.

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();
    }
    
    // sabit
    String CATEGORY = "transport";
}

Default-metodlar almaz problemi (diamond problem) həll edir: əgər sinif eyni default-metoda malik iki interfeysi tətbiq edirsə, kompilyator aşkar şəkildə ləğv etməyi tələb edir. Static-metodlar interfeys adı vasitəsilə çağırılır — Vehicle.of("car"), instansiya olmadan.

İnterfeys layihələndirərkən tipik səhvlər

İnterfeys layihələndirməsində səhvlər kövrək koda, test etmədə çətinliklərə və SOLID pozuntularına gətirib çıxarır. Üç tez-tez rast gəlinən problemi nəzərdən keçirək.

Interface Pollution — bir interfeysdə çox metod

15+ metodu olan interfeys Interface Segregation Principle (ISP) prinsipini pozur. Nümunə — 10+ metodu olan köhnə java.util.Dictionary. Həll yolu: bir neçə kiçik interfeysə bölmək — ReadableRepository, WritableRepository, SearchableRepository. Müştəri (xidmət) yalnız ehtiyacı olan metodlardan asılıdır.

Həddindən artıq abstraksiya — hər sinif üçün interfeys

Polimorfizmə real ehtiyac olmadan hər sinif üçün interfeys yaratmaq Interface overkill anti-nümunəsidir. Əlamət: interfeysin düz bir tətbiqi var və layihədə alternativ əlavə etmək planı yoxdur. Həll yolu: interfeysi yalnız ikinci tətbiq variantı və ya testlər üçün mock ehtiyacı yarandıqda əlavə edin.

Tez-tez verilən suallar

Java-da interface abstract class-dan nə ilə fərqlənir?

Interface yalnız kontraktı (metod siqnaturalarını) müəyyən edir, vəziyyətə malik ola bilməz və çoxlu mirası dəstəkləyir. Abstract class sahələr, konstruktorlar və tətbiq olunmuş metodlar ehtiva edə bilər, lakin sinif yalnız bir abstrakt sinifdən miras ala bilər. Java 8-dən etibarən interfeyslər default və static metodlar əldə edərək fərqi azaldıb.

İnterfeys başqa interfeysdən miras ala bilərmi?

Bəli, Java və Kotlin-də interfeyslər mirası dəstəkləyir. public interface AdvancedRepository<T> extends Repository<T>, Pageable — iki başqa interfeysi birləşdirən interfeys. AdvancedRepository-i tətbiq edən sinif hər iki valideyn interfeysin bütün metodlarını tətbiq etməlidir. Çoxlu miras yalnız interfeyslər üçün icazəlidir.

Java-da funksional interfeys nədir?

Funksional interfeys — bir abstrakt metodu olan interfeys (SAM — Single Abstract Method). @FunctionalInterface annotasiyası bu məhdudiyyəti təmin edir. Nümunələr: Runnable, Callable, Comparator, Consumer. Funksional interfeyslər Java 8 lambda ifadələrinin əsasıdır: () -> System.out.println() Runnable-i tətbiq edir.

Java interfeyslərində default metodlar nə üçün lazımdır?

Default metodlar bütün tətbiq edən sinifləri dəyişmədən interfeysə yeni metodlar əlavə etməyə imkan verir. Məsələn, Java 8 Collection-a stream() metodunu default-metod kimi əlavə etdi. Bu mexanizm olmasaydı, foreach(), stream() və digər metodlar JDK-da minlərlə sinfin dəyişdirilməsini tələb edərdi. Default — geriyə uyğun genişləndirmə üsuludur.

Kotlin çoxlu miras problemini necə həll edir?

Kotlin siniflərin çoxlu mirasını qadağan edir, lakin interfeyslərin çoxlu tətbiqinə icazə verir. Əgər iki interfeys eyni siqnatura və standart tətbiqə malik metoda sahibdirsə, kompilyator super<InterfaceName>.method() çağırışı ilə aşkar şəkildə ləğv etməyi tələb edir. Bu, almaz problemini kompilyasiya səviyyəsində həll edir.

Xülasə

  • Interface — sinifin tətbiq etməli olduğu metodları müəyyən edən kontrakt; Java və Kotlin-də polimorfizmin əsas mexanizmi
  • Java 8+ interfeyslərə default və static metodlar əlavə edərək abstrakt siniflərlə fərqi azaldıb
  • Kotlin interfaces abstrakt xassələri, standart tətbiqləri və by ilə deleqasiyanı dəstəkləyir
  • Clean Architecture interfeysləri Domain və Data qatları arasında sərhəd kimi istifadə edir
  • Interface Segregation Principle böyük interfeyslərin ixtisaslaşdırılmış interfeyslərə bölünməsini tələb edir
  • Funksional interfeyslər (Single Abstract Method) — lambda ifadələri və Stream API-nin əsası
  • Tövsiyə: interfeysi ikinci tətbiq və ya test üçün mock ehtiyacı yarandıqda əlavə edin

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun