# About inheritance and abstract types

**URL:** <https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801>\
**Category:** New to Julia\
**Tags:** inheritance\
**Created:** [September 9, 2017, 5:28pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801 "2017-09-09T17:28:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tobydriscoll](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobydriscoll/32/1843_2.png) [@tobydriscoll](https://discourse.julialang.org/u/tobydriscoll)\
**Post date:** [September 9, 2017, 5:28pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/1 "2017-09-09T17:28:13Z")

</div>

There’s something about Julia style that I’m just not getting. Let’s say I want a Curve type for a curve in the complex plane. It’s meant to be abstract, since I will have different subtypes of Curve (Line, Circle, etc). But all objects of Curve type should have a `pos` field that gives the position z as a function of a parameter. This is all that’s needed for a lot of Curve functionality.

In a purer OOP language I’d have Curve as an abstract class that has a `pos` property and methods that work on all Curves. All those methods know that the object has a `pos` property, even though the class is abstract.

In Julia, if I have an abstract `Curve` type and methods that operate on all `Curve`s, those methods will need to use the `pos` property. Every concrete subtype of `Curve` then has to be responsible for declaring a `pos` property, rather than having it be guaranteed as part of `Curve`. That’s a recipe for mayhem.

Essentially I’m looking for the concept of an interface. What is the Julia equivalent? Or does Julia have another way to look at this?

---

<div class="post-metadata">

**Author:** ![malmaud](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/malmaud/32/29_2.png) [@malmaud](https://discourse.julialang.org/u/malmaud)\
**Post date:** [September 9, 2017, 5:50pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/2 "2017-09-09T17:50:04Z")

</div>

With the ‘interface’ style, you might be looking for something like

```julia
abstract type Curve end

get_pos(c::Curve) = error("No get_pos method defined for curve type $(typeof(c))")

type Line <: Curve
pos::...
end

get_pos(line::Line) = line.pos

do_something(c::Curve) = get_pos(c) + ...

```

and you’ll get an appropriate run-time error if a given Curve subtype doesn’t conform to the implicit `get_pos` interface. There is discussion around adding language-level support for a formal interface concept in a future release of Julia.

---

<div class="post-metadata">

**Author:** ![tobias.knopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobias.knopp/32/7551_2.png) [@tobias.knopp](https://discourse.julialang.org/u/tobias.knopp)\
**Post date:** [September 10, 2017, 1:25pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/3 "2017-09-10T13:25:09Z")

</div>

```julia
using Graphics: @mustimplement

abstract type Curve end

@mustimplement get_pos(c::Curve)

...

```

the same just a little bit more terse using the must implement macro

---

<div class="post-metadata">

**Author:** ![tobias.knopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobias.knopp/32/7551_2.png) [@tobias.knopp](https://discourse.julialang.org/u/tobias.knopp)\
**Post date:** [September 10, 2017, 1:27pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/4 "2017-09-10T13:27:45Z")

</div>

Its also not just shorter but IMHO it reads really nice and makes the code self documenting. I use this a lot to program against defined interfaces and it works pretty well.

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [September 10, 2017, 3:34pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/5 "2017-09-10T15:34:08Z")

</div>

what can I find this `@mustimplement` macro?

---

<div class="post-metadata">

**Author:** ![tobias.knopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobias.knopp/32/7551_2.png) [@tobias.knopp](https://discourse.julialang.org/u/tobias.knopp)\
**Post date:** [September 10, 2017, 6:38pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/6 "2017-09-10T18:38:08Z")

</div>

[https://github.com/JuliaGraphics/Graphics.jl/blob/master/src/Graphics.jl#L292](https://github.com/JuliaGraphics/Graphics.jl/blob/master/src/Graphics.jl#L292)

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [September 10, 2017, 6:53pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/7 "2017-09-10T18:53:51Z")

</div>

Ah thanks - somehow I misread that this was in Base. I use a similar macro and also find it very useful and clear

---

<div class="post-metadata">

**Author:** ![tobias.knopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobias.knopp/32/7551_2.png) [@tobias.knopp](https://discourse.julialang.org/u/tobias.knopp)\
**Post date:** [September 10, 2017, 7:03pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/8 "2017-09-10T19:03:20Z")

</div>

It was in base but went to the Graphics package. Actually it does not really belong there but the discussion on interfaces in Base have kind of stopped.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [September 10, 2017, 9:32pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/9 "2017-09-10T21:32:39Z")

</div>

If you want to also “inherit” the behaviour, you can define a fallback method for the abstract type (rather than an error), and override only when required for concrete sub-types.

```julia
abstract type Curve end
get_pos(c::Curve) = c.pos

type Line <: Curve
    pos::Float64
end

type Arc <: Curve
    pos::Float64
end
get_pos(arc::Arc) = arc.pos + 1

type Circle <: Curve
    centre::Float64
end

get_pos(Line(2.5)) # use default fallback
get_pos(Arc(2.5)) # use Arc-specific method
get_pos(Circle(2.5)) # ERROR: type Circle has no field pos

```

---

<div class="post-metadata">

**Author:** ![MikaelSlevinsky](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikaelslevinsky/32/38545_2.png) [@MikaelSlevinsky](https://discourse.julialang.org/u/MikaelSlevinsky)\
**Post date:** [September 10, 2017, 11:45pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/10 "2017-09-10T23:45:06Z")

</div>

One advantage to the Julia approach is dealing with degeneracy. For example, the point (1.0,1.0) is a 0-dimensional curve that could be represented as:

```julia
type One <: Curve end
get_pos(one::One) = (1.0, 1.0)

```

In this example, the savings are trivial, but in general it allows for degenerate subtypes of an abstract supertype to be as light as they can be. If a family of types were to contain a matrix, then it’s reasonable for a degenerate subtype to instead have the identity, `I`, that doesn’t need to be stored in every concrete instance of the degenerate subtype.

---

<div class="post-metadata">

**Author:** ![williamfgc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/williamfgc/32/15445_2.png) [@williamfgc](https://discourse.julialang.org/u/williamfgc)\
**Post date:** [June 11, 2020, 1:41pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/11 "2020-06-11T13:41:14Z")

</div>

On that note, how is it possible to get something common to all types extending the `abstract type`. For example, if I have a field called `type::String`. Do I need to implement `get_type` in every subtype? Is it possible to have a common `get_type` defined at the base (abstract or not abstract) level.

`get_type(curve::BaseType) -> "curve", "straight-line", "circle"` depending on how it was constructed?

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [June 11, 2020, 2:41pm UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/12 "2020-06-11T14:41:55Z")

</div>

If all subtypes have the field, then

```julia
get_type(curve::BaseType) = curve.type

```

works. And if some subtype then goes and puts that info elsewhere, then you can special-case it:

```julia
get_type(curve::SomeSubType) = curve.some_other_field

```

---

<div class="post-metadata">

**Author:** ![williamfgc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/williamfgc/32/15445_2.png) [@williamfgc](https://discourse.julialang.org/u/williamfgc)\
**Post date:** [June 12, 2020, 2:51am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/13 "2020-06-12T02:51:21Z")

</div>

> if all subtypes have the field

I think the above is key. Thanks for the answer, that’s exactly how I’m addressing that, but code duplication grows pretty quickly without inheritance.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [June 12, 2020, 3:10am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/14 "2020-06-12T03:10:09Z")

</div>

It might be possible to make a macro that makes Julia act as if it had inheritance. The rough idea would be to store a dict keyed on abstract types who’s values were vectors of fields to be inherited.

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [June 12, 2020, 3:18am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/15 "2020-06-12T03:18:45Z")

</div>

There are quite a few of those out there, many are listed in this thread:

> [@Composition and inheritance: the Julian way](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/80):
>
> Both @forward and @quasiabstract allow to implement reusing patterns. But what is the best pattern depends on the problem and the boundary conditions (i.e. if Alice and Bob talks to each other…). Hence it makes sense to provide them in a single package to facilitate switch back and forth, and to provide a clear comparison of the approaches in the examples. AFAIK, the @forward macro in ReusePatterns.jl is the only one which automatically forwads all the necessary methods. I’m not sure you …

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 12, 2020, 9:22am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/16 "2020-06-12T09:22:07Z")

</div>

> [@williamfgc](#):
>
> code duplication grows pretty quickly without inheritance

If the duplication comes from repeating the fields, consider using composition.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [June 12, 2020, 9:42am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/17 "2020-06-12T09:42:11Z")

</div>

I think that this guide is useful for users coming to Julia with OO mindset:

> **[GitHub - ninjaaron/oo-and-polymorphism-in-julia: A short, opinionated guide...](https://github.com/ninjaaron/oo-and-polymorphism-in-julia)**
>
> A short, opinionated guide to object orientation and polymorphism in Julia - GitHub - ninjaaron/oo-and-polymorphism-in-julia: A short, opinionated guide to object orientation and polymorphism in Julia

Also you may want to use this package for your specific question:

> **[GitHub - rjplevin/Classes.jl: A simple, Julian approach to inheritance of...](https://github.com/rjplevin/Classes.jl)**
>
> A simple, Julian approach to inheritance of structure and methods - GitHub - rjplevin/Classes.jl: A simple, Julian approach to inheritance of structure and methods

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [June 12, 2020, 9:54am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/18 "2020-06-12T09:54:31Z")

</div>

There is also [GitHub - mauro3/OO.jl: OO for Julia](https://github.com/mauro3/OO.jl) 😉  
(please don’t use it!)

---

<div class="post-metadata">

**Author:** ![williamfgc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/williamfgc/32/15445_2.png) [@williamfgc](https://discourse.julialang.org/u/williamfgc)\
**Post date:** [June 12, 2020, 11:03am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/19 "2020-06-12T11:03:40Z")

</div>

> if the duplication comes from repeating the fields, consider using composition.

Thanks for the input. My 2 cents is that Julia can benefit from OO if we want to use it in large projects. My understanding is that composition, while nice, still doesn’t save from code duplication in all derived types.

---

<div class="post-metadata">

**Author:** ![williamfgc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/williamfgc/32/15445_2.png) [@williamfgc](https://discourse.julialang.org/u/williamfgc)\
**Post date:** [June 12, 2020, 11:07am UTC](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801/20 "2020-06-12T11:07:16Z")

</div>

More than the mindset, it is the practical aspect of maintaining large code bases. Many projects are switching from Fortran to C++ in my field due to the multiparadigm and modern features availability. While I like Julia and what it offers, it is still hard to sell the alternatives to OO as it is very similar to Fortran. type dispatch is great, but I think it’s orthogonal/complementary to inheritance. I’d still use Julia for small projects, though.

[Next page](https://discourse.julialang.org/t/about-inheritance-and-abstract-types/5801.md?page=2)
