# How do model a sub type that can fall under two different abstract types?

**URL:** <https://discourse.julialang.org/t/how-do-model-a-sub-type-that-can-fall-under-two-different-abstract-types/59355>\
**Category:** General Usage\
**Created:** [April 15, 2021, 4:16pm UTC](https://discourse.julialang.org/t/how-do-model-a-sub-type-that-can-fall-under-two-different-abstract-types/59355 "2021-04-15T16:16:52Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [April 15, 2021, 4:16pm UTC](https://discourse.julialang.org/t/how-do-model-a-sub-type-that-can-fall-under-two-different-abstract-types/59355/1 "2021-04-15T16:16:52Z")

</div>

Suppose you’re building a medieval role playing game, you’re going to have weapons of different types, so you’ll create an `abstract` type called `Weapon`:

```julia
abstract type GameObject end
abstract type Weapon <: GameObject end

```

You decide that your charcters can cast spells, and spells also have different types, so you can do:

```julia
abstract type Spell <: Weapon end # Fireball, Freeze, etc...

```

The problem? Not every spell is considered a `Weapon`. Suppose you want a spell that manipulates nature, for example, a spell that makes a planet grow faster or a spell that makes spoiled food suddenly fresh again.

I could make `Spell` a direct sub type of `GameObject`, and then `Nature` and `Defense`

```julia
abstract type Spell <: GameObject end
abstract type Nature <: Spell # FreshFood, GrowPlant,etc...
abstract type Defense <: Spell # Fireball,Freeze, etc...

```

When you have a sub types that share attributes of different `abstract` types, how do you model it?

This brings to mind Eric Lippert’s [Wizards and Warrriors](https://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/) series.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [April 15, 2021, 4:26pm UTC](https://discourse.julialang.org/t/how-do-model-a-sub-type-that-can-fall-under-two-different-abstract-types/59355/2 "2021-04-15T16:26:52Z")

</div>

Just answered this in another thread: [Why use subtypes instead of traits and duck typing? - #31 by Raf](https://discourse.julialang.org/t/why-use-subtypes-instead-of-traits-and-duck-typing/59146/31)

You can do a kind of multiple inheritance with subtyped traits. Edit: But this is probably overcomplicating things normal traits are all you need here.

You could also use regular object composition and multiple dispatch.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [April 15, 2021, 4:31pm UTC](https://discourse.julialang.org/t/how-do-model-a-sub-type-that-can-fall-under-two-different-abstract-types/59355/3 "2021-04-15T16:31:45Z")

</div>

My first response is to generally caution you about overusing complex type hierarchies. In  
general, types should be used strictly for dispatch; until you have a function that you need  
to dispatch differently for one set of types versus another, abstract parent types shouldn’t  
be introduced.

But if you do need to control dispatch in a way where simple single-inheritance won’t work,  
you can use a “Holy trait”:

```julia
struct HasMyTrait end
struct HasntMyTrait end

mytrait(_) = HasntMyTrait()

struct MyType end
mytrait(::MyType) = HasMyTrait()

myfunc(x) = _myfunc(x, mytrait(x))

_myfunc(x, ::HasntMyTrait) = ... # Behavior for types without trait
_myfunc(x, ::HasMyTrait) = ... # Behavior for types with trait

```

There are several packages that try to wrap this pattern into a macro to make it more  
pleasant to use, but I’m not personally familiar enough with any of them to make a  
recommendation.
