# Union Type vs Inheritance from Abstract Type

**URL:** <https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000>\
**Category:** General Usage\
**Tags:** inheritance\
**Created:** [January 7, 2021, 6:12pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000 "2021-01-07T18:12:00Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![ykkan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ykkan/32/14541_2.png) [@ykkan](https://discourse.julialang.org/u/ykkan)\
**Post date:** [January 7, 2021, 6:12pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/1 "2021-01-07T18:12:00Z")

</div>

If I have several structures:

```nohighlight
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:

```nohighlight
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?

---

<div class="post-metadata">

**Author:** ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)\
**Post date:** [January 7, 2021, 6:23pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/2 "2021-01-07T18:23:56Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [January 7, 2021, 6:32pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/3 "2021-01-07T18:32:58Z")

</div>

Just remember that you normally want your struct fields to have concrete types, so instead of something like this,

```julia
abstract type AbstractChild end

struct Mother{N}
    children::NTuple{N, AbstractChild}
end

```

you would probably want something like this:

```julia
abstract type AbstractChild end

struct Mother{N, T <: AbstractChild}
    children::NTuple{N, T}
end

```

---

<div class="post-metadata">

**Author:** ![ykkan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ykkan/32/14541_2.png) [@ykkan](https://discourse.julialang.org/u/ykkan)\
**Post date:** [January 7, 2021, 6:50pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/4 "2021-01-07T18:50:28Z")

</div>

Thanks for reply. Is there any difference from the point view of performance?

---

<div class="post-metadata">

**Author:** ![ykkan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ykkan/32/14541_2.png) [@ykkan](https://discourse.julialang.org/u/ykkan)\
**Post date:** [January 7, 2021, 6:51pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/5 "2021-01-07T18:51:56Z")

</div>

Thanks for your answer! I modified my question a little bit. Would it be still possible to do it with abstract type.

---

<div class="post-metadata">

**Author:** ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)\
**Post date:** [January 7, 2021, 7:00pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/6 "2021-01-07T19:00:44Z")

</div>

Hm, I don’t think so. Unions used to be less efficient but this got fixed between Julia 0.7 and 1.0.

> **[Union-splitting: what it is, and why you should care](https://julialang.org/blog/2018/08/union-splitting/)**
>
> Union-splitting: what it is, and why you should care | Among those who follow Julia's development closely, one of the (many) new features causing great excitement is something called

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [January 7, 2021, 7:03pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/7 "2021-01-07T19:03:15Z")

</div>

Yup, either of the following would work:

```julia
abstract type AbstractChild{N, T} end

struct Mother{M, C <: AbstractChild}
    children::NTuple{M, C}
end

```

or:

```julia
abstract type AbstractChild{N, T} end

struct Mother{M, N, T, C <: AbstractChild{N, T}}
    children::NTuple{M, C}
end

```

---

<div class="post-metadata">

**Author:** ![ykkan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ykkan/32/14541_2.png) [@ykkan](https://discourse.julialang.org/u/ykkan)\
**Post date:** [January 7, 2021, 8:47pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/8 "2021-01-07T20:47:39Z")

</div>

But, how could we make Child2{T} inherited from AbstractChild{N,T}?

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [January 7, 2021, 8:52pm UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/9 "2021-01-07T20:52:07Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![ykkan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ykkan/32/14541_2.png) [@ykkan](https://discourse.julialang.org/u/ykkan)\
**Post date:** [January 8, 2021, 6:26am UTC](https://discourse.julialang.org/t/union-type-vs-inheritance-from-abstract-type/53000/10 "2021-01-08T06:26:41Z")

</div>

I start to be confused what is the benefit (or reason) of using

```nohighlight
abstract type AbstractChild end

struct Mother{N}
    children::NTuple{N, AbstractChild}
end

```

in stead of using

```nohighlight
abstract type AbstractChild end

struct Mother{N, T <: AbstractChild}
    children::NTuple{N, T}
end

```
