# Julia OOP example

**URL:** <https://discourse.julialang.org/t/julia-oop-example/27568>\
**Category:** General Usage\
**Created:** [August 15, 2019, 2:33am UTC](https://discourse.julialang.org/t/julia-oop-example/27568 "2019-08-15T02:33:44Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![zhangliye](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zhangliye/32/3208_2.png) [@zhangliye](https://discourse.julialang.org/u/zhangliye)\
**Post date:** [August 15, 2019, 2:33am UTC](https://discourse.julialang.org/t/julia-oop-example/27568/1 "2019-08-15T02:33:44Z")

</div>

I am a C++ and Python user and quite accustomed to OOP for some tasks. The following is a small example of using OOP style in Julia. Please give comments if there are better ways to do that. Thank! Hope it could help the users have the similar demand.

```julia
# animal.jl
abstract type AbstractAnimal end

mutable struct BaseAnimal
    name::String 
    weight::Float64 
    BaseAnimal() = new("", 1.)
end

function get_weight( animal::AbstractAnimal )
    return animal.base.weight #no member variable in AbstractAnimal
end

```

```julia
#file2, dog.jl
mutable struct Dog <: AbstractAnimal
    base::BaseAnimal 
    owner_name::String
    Dog( name::String ) = new( BaseAnimal(), name)
end

function get_owner_name( dog::Dog )
    return dog.owner_name
end

```

```julia
#file3 cat.jl
mutable struct Cat <: AbstractAnimal
    base::BaseAnimal 
    climbing_speed::Float64
    Cat( speed::Float64 ) = new( BaseAnimal(), speed )
end

function get_climbing_speed( cat::Cat )
    return cat.climbing_speed
end

```

```julia
#file4 OOPTest.jl
module OOPTest

export Dog, Cat,
        get_climbing_speed, get_owner_name, get_weight

include("animal.jl") #it must be put before cat.jl and dog.jl, or there is error
include("cat.jl")
include("dog.jl")
end # module

```

```julia
#file5 runtest.jl
using OOPTest

dog = Dog("Tom")
cat = Cat(10.)

@show get_owner_name( dog )
@show get_climbing_speed( cat ) 
@show get_weight( dog )  
@show get_weight( cat )  

```

---

<div class="post-metadata">

**Author:** ![zhangliye](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zhangliye/32/3208_2.png) [@zhangliye](https://discourse.julialang.org/u/zhangliye)\
**Post date:** [August 15, 2019, 3:27am UTC](https://discourse.julialang.org/t/julia-oop-example/27568/2 "2019-08-15T03:27:29Z")

</div>

This is not so convenient to access the member variable of the base class. The user should remember which variable belongs to the parent class and use `base` variable to access the parent’s variable. It made extra workload for the user. For the up mentioned example, the user should access the member variable of `dog` as follows,

```julia
dog.owner_name # very straightforward
dog.base.weight # user should remember that this variable belong's to its parent, or there will be error
dog.base.name       

```

@StefanKarpinski Is it possible to solve this on the Language-level?

Then the user can access the parent’s variable directly using

```julia
dog.name
dog.weight

```

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [August 15, 2019, 4:25am UTC](https://discourse.julialang.org/t/julia-oop-example/27568/3 "2019-08-15T04:25:38Z")

</div>

there was an intersting discusion about this:

> [@Composition and inheritance: the Julian way](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231):
>
> I am a relatively newbie and I am wondering what is the most appropriate Julian way to reuse the code. I don’t want to trigger discussions on topics already discussed a million times. This post simply aims to lay down a clear list of rules to be followed to write good Julia code, and pose a couple of questions. Let’s start with an example: I have a type Person mutable struct Person \<: AbstractPerson name::String age::Int end and a lot (hundreds) of methods dealing with it. Now I wa…

---

<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:** [August 15, 2019, 9:22am UTC](https://discourse.julialang.org/t/julia-oop-example/27568/4 "2019-08-15T09:22:05Z")

</div>

There are some macros to make composition easier, eg `Lazy.@forward` and similar.

You can also define

```julia
Base.parent(dog::Dog) = dog.base

```

etc and then the user would not need to remember slot names.

I would advise to just let go of OO as a general style in Julia (which does not mean that you can’t use building blocks from it, just that you should not design your code like you would in C++), multiple dispatch meshes better with other idioms.

The problem with simplistic examples of animal classes etc is that they rarely reflect the problems of real life code. You can study code from others (eg read Base, it is very instructive).

(Also, I am not sure why you are pinging Stefan Karpinski on this; generally it is considered unnecessary unless you have a good reason).

---

<div class="post-metadata">

**Author:** ![zhangliye](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zhangliye/32/3208_2.png) [@zhangliye](https://discourse.julialang.org/u/zhangliye)\
**Post date:** [August 15, 2019, 1:31pm UTC](https://discourse.julialang.org/t/julia-oop-example/27568/5 "2019-08-15T13:31:50Z")

</div>

Thank you so much! Very helpful information. I am currently rewrite some simulation system written in Python with OOP design. I try to translate into Julia and found the coding style is a quite different and and is not convenient to translate directly.  
If there are some books or manuals, such as `Thinking in Julia` or `From C++/Python to Julia`, it would be helpful. I will try to learn how to drop the C++ OOP style in Julia.

---

<div class="post-metadata">

**Author:** ![catawbasam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/catawbasam/32/2936_2.png) [@catawbasam](https://discourse.julialang.org/u/catawbasam)\
**Post date:** [August 15, 2019, 3:36pm UTC](https://discourse.julialang.org/t/julia-oop-example/27568/6 "2019-08-15T15:36:42Z")

</div>

[https://benlauwens.github.io/ThinkJulia.jl/latest/book.html](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html)

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 15, 2019, 4:56pm UTC](https://discourse.julialang.org/t/julia-oop-example/27568/7 "2019-08-15T16:56:52Z")

</div>

As `variable.something` translates into `getproperty(variable, :something)`, you can overload `getproperty()` for the derived types, like:

```julia
function Base.getproperty(animal::T, p::Symbol) where {T<:AbstractAnimal}
    if p in fieldnames(T)
        getfield(animal, p)
    elseif :base in fieldnames(T)
        Base.getproperty(animal.base, p)
    else
        error("type $T has no property $p")
    end
end

```

However, the dot syntax is intended mainly for the development purposes (like private fields in more OOP languages, I guess). The users are supposed to have accessor functions.

---

<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:** [August 15, 2019, 8:12pm UTC](https://discourse.julialang.org/t/julia-oop-example/27568/8 "2019-08-15T20:12:30Z")

</div>

While I don’t personally find the ideas of OOP helpful when thinking about programming, @ninjaaron wrote a guide to his view of the topic a few months ago that didn’t seem to drag too many of the objectionable bits of OOP along when I skimmed it. It at least frames some of the patterns of the language in ways that may be familiar if you’re more comfortable with OOP. The section in the polymorphism notebook titled “Composition and method forwarding: an alternative to inheritance.” specifically addresses what you’re trying to do here.

> **[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

My own advice for grokking the “Julia” way of structuring code is to not overuse types. Think of them as simple containers for data rather than “objects” that interact. And as for how I would structure your example (although I also think animal examples aren’t super helpful):

```julia
abstract type Animal end

name(a::Animal) = a.name
weight(a::Animal) = a.weight

struct Dog <: Animal
    name::String
    weight:Float64
    owner::String
end#struct

owner(d::Dog) = d.owner

struct Cat <: Animal
    name::String
    weight::Float64
    climbing_speed::Float64
end#struct

climbing_speed(c::Cat) = c.climbing_speed

```

This provides fallback `name` and `weight` implementations for `Animal`s that happen to have fields with those names while still allowing overriding if the data comes from elsewhere:

```julia
mutable struct Fred <: Animal
    burgers_consumed::Int
end
Fred() = Fred(0)

eat!(fred::Fred) = fred.burgers_consumed += 1

name(::Fred) = "Fred"
weight(fred::Fred) = 200.0 + 0.5fred.burgers_consumed

```

---

<div class="post-metadata">

**Author:** ![zhangliye](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zhangliye/32/3208_2.png) [@zhangliye](https://discourse.julialang.org/u/zhangliye)\
**Post date:** [August 16, 2019, 1:50am UTC](https://discourse.julialang.org/t/julia-oop-example/27568/9 "2019-08-16T01:50:59Z")

</div>

Thanks for the sharing! The suggested document is concise and useful, which saves me a lot of time to find solution from large amount of discussions on this website. [Object Orientation and Polymorphism in Julia](https://github.com/ninjaaron/oo-and-polymorphism-in-julia)

As a C++/Python user, I found Julia’s solution for OOP is quite different from the languages I used. Maybe, Julia just weakly supports OOP and have better solution to replace OOP.  
[Type-Dispatch Design: Post Object-Oriented Programming for Julia](https://github.com/ninjaaron/oo-and-polymorphism-in-julia)

---

<div class="post-metadata">

**Author:** ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)\
**Post date:** [August 19, 2019, 12:58am UTC](https://discourse.julialang.org/t/julia-oop-example/27568/10 "2019-08-19T00:58:54Z")

</div>

> [@zhangliye](#):
>
> Type-Dispatch Design: Post Object-Oriented Programming for Julia

It seems you copy twice the same links.  
Second one may be [Type-Dispatch Design: Post Object-Oriented Programming for Julia - Stochastic Lifestyle](http://www.stochasticlifestyle.com/type-dispatch-design-post-object-oriented-programming-julia/)
