# Encapsulation and Interface-like implementations in Julia

**URL:** https://discourse.julialang.org/t/encapsulation-and-interface-like-implementations-in-julia/74616
**Category:** New to Julia
**Tags:** design-pattern
**Created:** [January 14, 2022, 12:39pm UTC](https://discourse.julialang.org/t/encapsulation-and-interface-like-implementations-in-julia/74616 "2022-01-14T12:39:10Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![MAJegh](https://avatars.discourse-cdn.com/v4/letter/m/8edcca/32.png) [@MAJegh](https://discourse.julialang.org/u/MAJegh)
#### Post date: [January 14, 2022, 12:39pm UTC](https://discourse.julialang.org/t/encapsulation-and-interface-like-implementations-in-julia/74616/1 "2022-01-14T12:39:10Z")

</div>

My general question would be : Is there a way to organize code in Julia to improve maintainability/extensibility and make contributions to a project easier? any resources on the matter are welcome.

More specifically, in OOP inheritance and encapsulation can make life easier as they provide a sort of contract that one can follow/implement to extend a project while “ensuring” correctness. In julia, I recognize the strength and performance of multiple dispatch but haven’t found a way to organize myself around it.

To give an example:  
In OOP, we can have the following:

```julia
abstract class Animal {
    name::String
    abstract function make_sound()
    function greet() { println("hello "+name); make_sound(); }
}

class Dog <: Animal {
    function make_sound() { println(name + " barks!")}
}

```

Having the abstract class, We can look at the Animal class (and maybe its superclasses) and deduce the fields we already have as well as the requirements that we needs to satisfy to implement a new `Animal`.

If I want to illustrate this in Julia:

```nohighlight
abstract type Animal end

function greet(animal::Animal)
    println("hello "+ get_name(animal))
    make_sound(animal);
end

struct Dog <: Animal name::String end
function get_name(dog::Dog)
    dog.name
end
function make_sound(dog::Dog) 
    println(get_name(dog) + " barks!")
end

```

Here, It is not obvious what one should do to implement an `Animal`.

In addition, there can be other parts of code using the Animal class that we don’t even know of. For example, we can have the following (which will make a new defined `Cat` fly):

```julia
abstract type FlightAbility end
struct CanFly <: FlightAbility end
struct CannotFly <: FlightAbility end

FlightAbility(::Type{<:Animal}) = CanFly()
FlightAbility(::Type{<:Dog}) = CannotFly()    

```

P.S.  
I’m new to Julia and found that [this post](http://www.stochasticlifestyle.com/type-dispatch-design-post-object-oriented-programming-julia/) is a very interesting read. If some of you have a few pointers to some good resources on ways to organise packages/code I’d be thankful.

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [January 14, 2022, 1:07pm UTC](https://discourse.julialang.org/t/encapsulation-and-interface-like-implementations-in-julia/74616/2 "2022-01-14T13:07:27Z")

</div>

This Invenia blog post is a very good read on this topic in my opinion:

> **[Development with Interface Packages](https://invenia.github.io/blog/2020/11/06/interfacetesting/)**
>
> Over the last two years, our Julia codebase has grown in size and complexity, and is now the centerpiece of both our operations and research. This implies that we need to routinely replace parts of the system like puzzle pieces, and carefully test if...

  

In the case of your example, one simple way to at least document the `Animal` interface would be via bare function definitions with docstrings. Something along the lines of:

```julia
abstract type Animal end

"return the name of an animal"
function get_name end # notice the absence of parentheses. No method is attached to this function (yet)

"make an animal sound"
function make_sound end

function greet(animal::Animal) # this default method uses the previously defined functions
    println("hello "+ get_name(animal))
    make_sound(animal);
end

```

And then any animal implementor can at least have an idea of what to implement by looking at the source code for `Animal`:

```julia
struct Dog <: Animal name::String end

# these define a specific methods for the functions declared above
get_name(dog::Dog) = dog.name
make_sound(dog::Dog) = println(get_name(dog) + " barks!")

# ... and we get a default `greet` implementation for free

```

  

But apart from custom test utilities such as those mentioned in Invenia’s blog post above, most of this relies on good documentation. Examples of well documented interfaces can be found in the Julia manual:

[https://docs.julialang.org/en/v1/manual/interfaces/](https://docs.julialang.org/en/v1/manual/interfaces/)

---

<div class="post-metadata">

### Author: ![MAJegh](https://avatars.discourse-cdn.com/v4/letter/m/8edcca/32.png) [@MAJegh](https://discourse.julialang.org/u/MAJegh)
#### Post date: [January 17, 2022, 8:56am UTC](https://discourse.julialang.org/t/encapsulation-and-interface-like-implementations-in-julia/74616/3 "2022-01-17T08:56:59Z")

</div>

Thanks a lot for your answer and the link. This is most of what I was looking for.
