Let’s say we have Foo as an AggregateRoot. And there are generic Foos as well as EnhancedFoos with a number of extended properties. Is it OK to expose “Actions” on a single aggregate root class for generic and enhanced properties and have validation check to throw exception if enhanced action was called on non-enhanced Foo object? Technically, AggregateRoot in this case will aggregate all possible “Actions” for all supported Foo types?
Obviously a lot depends on domain structure, but I think this hypothetical situation is quite common. Probably basic question but I'm just starting with Aggregates/Roots.
Update per feedback
Let’s say we have Foo as an AggregateRoot. And there are generic Foos as well as FlyableFoos, SwimmableFoos, etc. So, Aggregate should "know" about all possible behaviors (fly, quack, swim) and expose it appropriately to Service functionality. And if something is called some reason that is not “supported” by current object, Aggregate may throw an exception “Sorry, penguin can’t fly”.
I don't think that this is a good idea. You should try to keep a clean code at the same time you use the DDD approach. So, I recommend you to respect the SOLID principles when coding the Aggregates and try to favor composition over inheritance.
Also, when designing Aggregates, you should not think about
properties
but state and behavior. This is more important in CQRS as you don't query the Aggregates, you don't have any getters (and according to DDD you don't have any setters as well as you should name your methods according to the ubiquitous language).You could use inheritance but you must be sure that the gain (code reuse) is greater than what you loose (increased cognitive effort). I don't recommend it.
This would break the Liskov substitution principle.