2016-11-02 13 views
8

Я хочу сделать что-то вроде этого:Можно ли указать статическую функцию в интерфейсе Kotlin?

interface Serializable<FromType, ToType> { 
    fun serialize(): ToType 
    companion object { 
     abstract fun deserialize(serialized: ToType): FromType 
    } 
} 

или даже это будет работать для меня:

interface Serializable<ToType> { 
    fun serialize(): ToType 
    constructor(serialized: ToType) 
} 

но ни компилирует. Есть ли синтаксис для этого, или я буду вынужден использовать этот интерфейс для фабрики? Или есть еще один ответ? Это было бы здорово!

ответ

5

В принципе, ничто в companion object не может быть abstract или open (и, таким образом, быть перекрыты), и нет никакого способа, чтобы требовать реализации companion object с, чтобы иметь метод или определить/требуется конструктор в интерфейсе.

Возможное решение для Вас, чтобы разделить эти две функции на два интерфейса:

interface Serializable<ToType> { 
    fun serialize(): ToType 
} 

interface Deserializer<FromType, ToType> { 
    fun deserialize(serialized: ToType): FromType 
} 

Таким образом, вы будете иметь возможность реализовать первый интерфейс в классе и сделать его companion object реализовать другую:

class C: Serializable<String> { 
    override fun serialize(): String = "..." 

    companion object : Deserializer<C, String> { 
     override fun deserialize(serialized: String): C = C() 
    } 
} 

Кроме того, существует серьезное ограничение, что only a single generic specialization of a type can be used as a supertype, так что эта модель сериализации через реализацию интерфейса может оказаться не масштабируется достаточно, не позволяя несколько реализаций с дифферем t ToType s.

+3

Но почему? Почему он был разработан таким образом? – cuddlecheek

0

Я относительно новичок с Котлином. Вот мои 2 ¢

  1. Сопутствующий объект является экземпляром класса и, как таковой, не может быть унаследован. Вот почему абстрактная функция не будет иметь места для реализации. В Java аналогичный результат требует анонимного класса, реализующего абстрактный класс, но сильно отличается от переопределяющего метода для экземпляра класса.

  2. Интерфейс не может использоваться для создания экземпляра, поэтому для конструктора в интерфейсе нет необходимости.

Почему бы вам не создать общий абстрактный класс? Тогда абстрактная или открытая функция будет работать для сериализации(): ToType и десериализации (сериализованная: ToType): функции FromType.