如果 Category 需要是一个密封的类(例如,IncomeCategory 和 ExpenseCategory 的实例需要携带状态),你会这样做。顶级 Transaction 类使用泛型类型来表示其类别,因此如果您想要两种 Transaction 类型的列表,您可以声明一个List<Transaction<Category>>.
sealed class Category
class IncomeCategory: Category()
class ExpenseCategory: Category()
abstract class Transaction<out T: Category>(val category: T)
class Income(category: IncomeCategory): Transaction<IncomeCategory>(category)
class Expense(category: ExpenseCategory): Transaction<ExpenseCategory>(category)
如果您需要能够更改类别实例,那么您不能在声明站点将类型声明T为协变out的,并且您必须在引用列表的地方声明它是协变的:List<Transaction<out Category>>。然后你可以使用var而不是valfor category。
如果Category可以只是一个枚举,这更简单,因为您不需要泛型:
enum class Category {
IncomeCategory,
ExpenseCategory
}
abstract class Transaction(val category: Category)
class Income(): Transaction(Category.IncomeCategory)
class Expense(): Transaction(Category.ExpenseCategory)