# How do you make subtype fields consistent and mandatory?

**URL:** <https://discourse.julialang.org/t/how-do-you-make-subtype-fields-consistent-and-mandatory/59208>\
**Category:** General Usage\
**Tags:** type\
**Created:** [April 13, 2021, 3:17pm UTC](https://discourse.julialang.org/t/how-do-you-make-subtype-fields-consistent-and-mandatory/59208 "2021-04-13T15:17:34Z")\
**Posts on this page:** 2\
**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 13, 2021, 3:17pm UTC](https://discourse.julialang.org/t/how-do-you-make-subtype-fields-consistent-and-mandatory/59208/1 "2021-04-13T15:17:34Z")

</div>

Consider the following code:

```julia
abstract type AbstractTransport end

mutable struct Car <: AbstractTransport

    name::String
    engine_type::String
    number_of_people::Int32

    function Car(name::String, engine_type::String, number_of_people::Int32)
        # Validation left out. 
        new(name,engine_type,number_of_people)
    end 
end

```

```julia
mutable struct StarShip <: AbstractTransport

    number_of_people::Int32

    function StarShip(number_of_people::Int32)
        # Validation left out. 
        new(number_of_people)
    end 
end

```

As you can see both transports are sub types of `AbstractTransport` but they don’t have consistent fields. I won’t get an error until I use a method that requires certain fields:

```julia
function transport_info(transport::AbstractTransport)
    println(transport.name)
    println(transport.engine_type)
end

```

```julia
uss_enterprise = StarShip(100)
transport_info(uss_enterprise) # type StarShip has no field name

```

Is there a way to make certain fields mandatory during construction of sub types? For example in OOP, you would have an `Abstract` class that contains all the attributes common to all subclasses. When constructing an object, you would pass the required fields to the `Abstract` class using the constructor.

In OOP, I would put the `name` and `engine_type` in the abstract class, so even if a subclass doesn’t provide new attributes it at least has to provide `name` and `engine_type`.

I could use `hasfields()` but then each method that uses an `AbstractTransport` would need to check for the required fields.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [April 13, 2021, 4:02pm UTC](https://discourse.julialang.org/t/how-do-you-make-subtype-fields-consistent-and-mandatory/59208/2 "2021-04-13T16:02:45Z")

</div>

Julia has no data inheritance. IMHO, the Julian way is to either:

1. Do not ever access fields of an object that you received from a parameter typed generically. Create two functions `name` and `engine_type`, and document they should be defined for every subtype of this `abstract type`, use these functions instead. In other, basically, use setters and getters you want to use OOP concepts.
2. Document the `abstract type` to indicate any subtype needs to have a field called `engine_type`. I think this is clunky and has basically no performance improvements over getters and setters, but hey, it is a solution.
3. Combine both previous solutions with a small dose of enforcement. When you define the getters and setters, let the generic version (that does not define the type of any arguments) check if the field exists, if it exists use the field, otherwise throw an error explaining to the used that “Type X is a subtype of Type Y and breached the contract by not having a field called `z`.”. For the best you should yet use the getters and setters in your generic code but at least people that subtype your type “in the wrong fashion” will get a good error message and they do not need to define their own getters and setters (the generic one will do the job for them).

Probably there some hacky improvements to these ideas, but I would recommend following either path 1 or 3. A solution in a kind different direction would be creating a `TransportInfo` concrete type, with both `name` and `engine_type` fields, and require (by means of documentation) that your `AbstractTransport` subtypes define a method for `get_transport_info` (or some better name) that always return a `TransportInfo` object.
