Sam Stone
04/12/2022, 5:39 PMFilterableListAdapter
that keeps track of what the previous search was, whether the user initiated a search or it was from the system, etc. I am going to initialize those values to false/empty string on every single implementor, and it just becomes boilerplate to do so.
If the interface could define them, classes would be much cleaner and focused on what makes them unique.Youssef Shoaib [MOD]
04/12/2022, 5:42 PMinterface FilterableListAdapter {
val previousSearch: String get() = ""
}
Sam Stone
04/12/2022, 5:43 PMPaul Griffith
04/12/2022, 5:44 PMSam Stone
04/12/2022, 5:45 PMandroidx.ListAdapter
.Paul Griffith
04/12/2022, 5:46 PMSam Stone
04/12/2022, 6:06 PMFilterableListAdapter
implements FilterableScreen
to add some logic specific to list adapters, but many different screens implement FilterableScreen
, which extend many different classes (e.g. androidx.Dialog
, androidx.Activity
, etc.), so it needs to be an interface.Paul Griffith
04/12/2022, 6:12 PMSam Stone
04/12/2022, 6:13 PMPaul Griffith
04/12/2022, 6:17 PMget/set
methods on the Java interface - there is no such thing as a true instance member variable on an interface in Java/Kotlin: https://stackoverflow.com/questions/2430756/why-are-interface-variables-static-and-final-by-defaultSam Stone
04/12/2022, 6:19 PMYoussef Shoaib [MOD]
04/12/2022, 6:48 PMimport kotlin.time.*
interface FilterableListAdapter {
var previousSearch: String
var lastSearchTime: Duration
var wasSearchInitiatedByUser: Boolean
var otherValue: Int
var evenMoreValues: List<Any>?
}
class FilterableListAdapterFields : FilterableListAdapter {
override var previousSearch: String = ""
override var lastSearchTime: Duration = 5.minutes
override var wasSearchInitiatedByUser: Boolean = false
override var otherValue: Int = 42
override var evenMoreValues: List<Any>? = null
}
open class Baz
class FooBar: Baz(), FilterableListAdapter by FilterableListAdapterFields() {
fun myCustomFunctionality() {
println(previousSearch)
previousSearch = "hello"
}
}
class MapImplementationOfFilterableListAdapterForSomeReason: HashMap<Any, Any>(), FilterableListAdapter by FilterableListAdapterFields() {
override var evenMoreValues: List<Any>? = listOf() // if you override any of the behavior on your own, you'll sadly need to initialize the property
get() = field!! + this.values
}
fun main() {
val fooBar = FooBar()
fooBar.myCustomFunctionality()
fooBar.myCustomFunctionality()
}
Youssef Shoaib [MOD]
04/12/2022, 6:48 PMSam Stone
04/12/2022, 10:58 PMYoussef Shoaib [MOD]
04/13/2022, 9:42 AM*Fields
class. A way around that is to split the interface into 2: 1 is the parent that just has the fields that will have defaults, and then 1 which has all the methods that a class needs to implement. Then your *Fields
class will implement the parent interface, while each child will implement the interface with all the required methods. Finally, your implementors will delegate the fields to the *Fields
class, and will also implement the "real" interface. E.g.:
interface FilterableListAdapterDef {
var previousSearch: String
var lastSearchTime: Duration
var wasSearchInitiatedByUser: Boolean
var otherValue: Int
var evenMoreValues: List<Any>?
}
interface FilterableListAdapter: FilterableListAdapterDef {
fun methodTheImplementorsHaveToImplement()
}
class FilterableListAdapterFields : FilterableListAdapterDef {
override var previousSearch: String = ""
override var lastSearchTime: Duration = 5.minutes
override var wasSearchInitiatedByUser: Boolean = false
override var otherValue: Int = 42
override var evenMoreValues: List<Any>? = null
}
open class Baz
// Error: Class 'FooBar' is not abstract and does not implement abstract member public abstract fun methodTheImplementorsHaveToImplement(): Unit defined in FilterableListAdapter
class FooBar: Baz(), FilterableListAdapterDef by FilterableListAdapterFields(), FilterableListAdapter {
fun myCustomFunctionality() {
println(previousSearch)
previousSearch = "hello"
}
}
It might be a bit too much boilerplate though for you. If the people writing the implementors are aware that they need to implement the methods even without their IDE screaming at them, then you should be fine. Otherwise, the workaround above might be needed to bring back the screaming IDE.elizarov
05/18/2022, 5:55 PMSam Stone
05/31/2022, 1:11 AMSam Stone
05/31/2022, 1:12 AMelizarov
05/31/2022, 9:35 AM