In my Android app, I have a parent class named FilterOption
which has 2 child classes named UserFilterOption
and BusinessFilterOption
.
abstract class FilterOption<T> {
abstract fun match(filter: T): Boolean
}
The child classes implement this class and pass their T
types, as expected. This is fine.
I have another function in my custom View
class that takes a Set<>
of these filters and does work on them:
interface FilterableView<T> {
fun onFilterOptionChanged(filterOption: FilterOption<T>)
private fun addFilter(menu: Menu, labelResId: Int, filterOptions: Set<FilterOption<T>>, filterOption: FilterOption<T>) {
menu.add(labelResId).apply {
isCheckable = true
isChecked = filterOptions.contains(filterOption)
setOnMenuItemClickListener {
onFilterOptionChanged(filterOption)
true
}
}
}
}
I define my Views like this:
class BusinessFragment : FilterableView<BusinessFilterType> {
....
}
But when I try to call this function in the FilterableView
class, I get errors:
private fun addBusinessFilters(menu: Menu, businessFilterOptions: Set<FilterOption<T>>) {
addFilter(
menu, R.string.general_open, businessFilterOptions,
BusinessFilterOption.BusinessType.Open <-- ERROR HERE
)
addFilter(
menu, R.string.general_closed, businessFilterOptions,
BusinessFilterOption.BusinessType.Closed <-- ERROR HERE
)
}
ERROR:
Type mismatch.
Required: FilterOption<T>
Found: BusinessFilterOption.BusinessType.Open
This is the same for the other type ("Closed"), as well as all the other types on the UserFilter
.
This is the definition of the BusinessFilters:
sealed class BusinessFilterOption : FilterOption<Business.View.BusinessModel>() {
sealed class BusinessFiltersType(private val type: BusinessFilterType) : BusinessFilterOption() {
override fun match(filter: Business.View.BusinessModel): Boolean {
//check if match with open or closed
}
object Open : BusinessFiltersType(BusinessFilterType.OPEN)
object Closed : BusinessFiltersType(BusinessFilterType.CLOSED)
}
}
So what i'm trying to do is make the addfilter
method generic so I can pass UserFilterOption
and BusinessFilterOption
to it, because they both inherit from FilterOption<T>
, so I don't understand why the error is telling me I need to pass the parent class, when I'm passing the child class.
Can anybody help? Thanks
T
of addFilter
is defined in FilterableView<T>
. This means that the type passed to FilterableView
determines the valid parameters that can be passed to addFilter
. For BusinessFragment
, only BusinessFilterOption
would be allowed.
Where is addBusinessFilters
defined? This method seems counterintuitive given the generic FilterableView<T>
you have defined prior.
So what i'm trying to do is make the addfilter method generic so I can pass UserFilterOption and BusinessFilterOption to it
Do not confuse generics with inheritance , although you might be interested in reading more about generic constraints .
If that is what you want, you need polymorphism, and your view should be allowed to take any FilterOptions<T>
. At the risk of not understanding your design considerations, you likely want to not make FilterableView<T>
generic and instead make addFilter
a generic method.
private fun <T> addFilter(
...,
filterOptions: Set<FilterOption<T>>,
filterOption: FilterOption<T>
) { ... }
I think the only issue you have is with the declaration of your BusinessFragment
. Your FilterableView
interface takes in a T
which is the same type as the T
in your FilterOption
.
Your BusinessFilterType
classes are FilterOption<Business.View.BusinessModel>
, so your BusinessFragment
should be declared as BusinessFragment<Business.View.BusinessModel>
rather than BusinessFragment<BusinessFilterType>
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.