struct Child1{N,T} end
struct Child2{T} end
const Child1OrChild2{N,T} = Union{Child1{N,T}, Child2{T}}
struct Mother{M,N,T}
children::NTuple{M,Child1OrChild2{N,T}}
end
Would it be possible to do similar thing by defining an abstract type instead of using Union Type? Like this:
abstract struct AbstractChild{N,T} end
struct Child1{N,T} <: AbstractChild{N,T}end
struct Child2{T} <: AbstractChild{N,T} end # this is not allowed
struct Mother{M,N,T}
children::NTuple{M,AbstractChild{N,T}}
end
I am still confused when to use inheritance from an abstract type and when to use Union type. What is the disadvantage of using Union type?
AFAICT, AbstractTypes are more extendable. You could make AbstractChild a subtype of AbstractDescendant (with its own specific descendent types) and dispatch based on that, for example. You could also add Child3, Child4, etc (in addition to Child1 and Child2) as instantiations of AbstractChild.
Union types can be more useful if you don’t need a bunch of generalizability. For example, AbstractVecOrMat =Union{AbstractArray{T,1}, AbstractArray{T,2}} is useful if you don’t want the full generality of an AbstractArray (e.g., exclude higher dimensional arrays).
Subtypes have to have at least as many type parameters as their parent types. So, if one of your AbstractChild subtypes only has one type parameter, then AbstractChild should have either one or zero type parameters. In other words, AbstractChild should only include parameters that are required in all subtypes of AbstractChild.