# Is it possible to preserve the fields and methods of a type when creating a subtype?

**URL:** <https://discourse.julialang.org/t/is-it-possible-to-preserve-the-fields-and-methods-of-a-type-when-creating-a-subtype/88719>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 14, 2022, 10:11am UTC](https://discourse.julialang.org/t/is-it-possible-to-preserve-the-fields-and-methods-of-a-type-when-creating-a-subtype/88719 "2022-10-14T10:11:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [October 14, 2022, 10:11am UTC](https://discourse.julialang.org/t/is-it-possible-to-preserve-the-fields-and-methods-of-a-type-when-creating-a-subtype/88719/1 "2022-10-14T10:11:43Z")

</div>

Hi suppose I have a SubDataFrame A with columns A.Roll, A.Pitch, A.Yaw. Further suppose I create a new type in order to apply specific methods.

```julia
struct Plane
    flight :: SubDataFrame 
end 

B = Plane(A)

```

Is it possible for `type Plane` to inherit the fields of a SubDataFrame? So for example ‘A.Roll’ would return the column Roll. `B.Roll` however returns `ERROR: type plane has no field Roll`.  
Likewise `A.Time = [1,2,3]` would add a new column `Time` to `A` whereas it does not work for type Plane. I realize in the first instance I could do something like

```julia
Roll(Plane) = Plane.flight.Roll 

```

But I was just wondering if there was a way to get Plane \<: SubDataFrame so that it can use the same fields and methods? Thanks and sorry if this is another newbie question.

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [October 14, 2022, 12:33pm UTC](https://discourse.julialang.org/t/is-it-possible-to-preserve-the-fields-and-methods-of-a-type-when-creating-a-subtype/88719/2 "2022-10-14T12:33:10Z")

</div>

You can overload `getproperty` and `setproperty!`:

```julia
mutable struct SubDataFrame
    Roll
    Pitch
    Yaw
end

struct Plane
    flight :: SubDataFrame
end

A = SubDataFrame(1,2,3)
B = Plane(A)

get_flight(B :: Plane) = getfield(B, :flight);
Base.getproperty(B :: Plane, n :: Symbol) = getproperty(get_flight(B), n)
Base.setproperty!(B :: Plane, n :: Symbol, x) = setproperty!(get_flight(B), n, x)

A.Roll === B.Roll #true
A.Roll = 17
B.Roll # 17

```

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [October 15, 2022, 3:07am UTC](https://discourse.julialang.org/t/is-it-possible-to-preserve-the-fields-and-methods-of-a-type-when-creating-a-subtype/88719/3 "2022-10-15T03:07:11Z")

</div>

Thanks so much, this works great! Sorry for the delayed response. Would you mind clarifying how `Base.getproperty` and `Base.setpropperty!` are working? After a bunch of googling and reading the documentation in Julia I’m still not sure I have it right.

My understanding is that with:  
`Base.getproperty(B :: Plane, n :: Symbol) = getproperty(get_flight(B), n)`  
we are setting `B.n === A.n` or Plane.n ===SubDataFrame.n

likewise:  
`Base.setproperty!(B :: Plane, n :: Symbol, x) = setproperty!(get_flight(B), n, x)`  
allowing us to create a new column `x` in `B` via `B.n = x` just as we would with SubDataFrame. Is this correct?

Also why is it that the `Base` module is required on one side of the assignment but not the other? Sorry just trying to understand this a little better. Thanks.

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [October 15, 2022, 1:03pm UTC](https://discourse.julialang.org/t/is-it-possible-to-preserve-the-fields-and-methods-of-a-type-when-creating-a-subtype/88719/4 "2022-10-15T13:03:58Z")

</div>

`Base.getproperty` is what is called when you write `B.Roll`.  
The overloading makes that effectively into `B.flight.Roll`.  
We need the `get_flight` because  
`getproperty(B.flight, :Roll`  
expands to  
`getproperty(getproperty(B, :flight), :Roll)`  
which results in a `StackOverflow` (infinite recursion).

To avoid that, we need to use `getfield(B, :flight)` to retrieve the `flight` field.  
Internally, `getproperty` defaults to `getfield` unless we overload it.

Basically the same happens with `setproperty!`.  
So the expected syntax `B.Roll` for retrieval and `B.Roll = 17` for assignment work.

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [October 17, 2022, 7:50am UTC](https://discourse.julialang.org/t/is-it-possible-to-preserve-the-fields-and-methods-of-a-type-when-creating-a-subtype/88719/5 "2022-10-17T07:50:16Z")

</div>

awesome thanks so much for clearing that up!
