Similar to the answer to the question referenced by Philipp, you might consider using a general system of events and flags for every item:
- CanEquip, OnEquip/OnDeEquip
- CanConsume, OnConsume
- IsQuestItem, OnCompleteQuest
- etc.
This is a much more flexible approach as it allows items to serve multiple purposes as would be the case in, for example, the dry baguette which is both a blunt weapon and a food.
You can then use the OnEquip/OnDeequip to add and remove user actions, status effects, and so on. Imagine a cyborg character who needs to equip limbs. We might consider adding or removing the "Fight" option depending on whether they have their limbs equipped. The DeEquip event also supports having a thief-type character steal equipped items.
To make reusable records for each item, you can use composition. So you might use the Item class for everything, and include a list of components for each, ala:
Item: { Name: "Baguette", Aspects: [ Weapon: { ... }, Food: { ... }, ... ] ... }
Note that the Aspects member is an array. You would implement a base class for that like ItemAspect, and extend that for particulars to each idea, while every Item object could pass through events (OnConsume) and properties (CanConsume) to check in with its aspect members.