liveBook · Manning

Abstract type

As explained in Julia as a Second Language

An abstract type is a type that defines a conceptual interface or classification without directly representing concrete instances.

Suppose a battle simulator has archers, pikemen, and knights. Each needs its own data and behavior, but all belong to the broader category of warrior. In Julia, an abstract type names that shared category; concrete subtypes represent the objects you can create. section 7.3 section 7.3.1

Listing 7.5 Definition of types in battle simulator
abstract type Warrior end           #1
 
mutable struct Archer <: Warrior    #2
    name::String
    health::Int
    arrows::Int
end
 
mutable struct Pikeman <: Warrior
    name::String
    health::Int
end
 
mutable struct Knight <: Warrior
    name::String
    health::Int
    mounted::Bool                   #3
 end

The `Warrior` declaration establishes the category. Each `mutable struct` uses `<:` to become a concrete subtype and supplies its own fields. section 7.3.1

Create a warrior, not the category

`Archer("Robin Hood", 34, 24)` creates an object. `Warrior()` fails because abstract types have no constructors for instances. An abstract type also cannot declare fields: the shared `name` and `health` fields in the warrior types are a convention, not a requirement Julia enforces. section 7.3.1

Only an abstract type can be a supertype in a Julia subtype declaration; a concrete type cannot be subclassed. Related types can instead share an abstract supertype while functions provide behavior. Multiple dispatch selects a method from the types of all its arguments. section 7.3.1 section 7.5

Listing 8.14 Allowing a rocket to be the payload of another rocket
abstract type Rocket end                       #1
 
struct Payload <: Rocket                       #2
    mass::Float64
end
 
struct StagedRocket <: Rocket
    nextstage::Rocket                          #3
    tank::Tank
    engine::Engine
end
 
function Rocket(payload::Rocket, tank::Tank,
 engine::Engine)                             #4
    StagedRocket(payload, tank, engine)
end
 
thrust(r::Payload) = 0.0  # no engines
thrust(r::StagedRocket) = thrust(r.engine)

A rocket uses the same idea for composition: `Payload` and `StagedRocket` are concrete subtypes of abstract `Rocket`, and a stage’s `nextstage::Rocket` can refer to either kind. Separate `thrust` methods handle their different behavior. section 8.7

Use an abstract type when related concrete objects must fit one role without having identical representations. Paired with multiple dispatch, it lets code work with that shared role while retaining type-specific behavior. section 8.0 section 8.9

How Julia as a Second Language covers it

How deep it goes
Defines declaration, instantiation, fields, and subtyping through worked hierarchies; notes that shared fields are conventional rather than enforced.
Examples
Uses warrior subtypes and a nested rocket whose payload or next stage can be another rocket.
What it assumes
Assumes basic Julia objects and functions, while introducing the distinction between abstract and concrete types through examples.
What you can do after
Build it from scratch: define abstract categories, add concrete subtypes, and use methods to distinguish their behavior.
How it connects
Connects type hierarchies and concrete types to composite types, subtyping, and multiple dispatch.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Julia as a Second Language. The section links point to the parts of the book it draws on.