liveBook · Manning

Concrete type

As explained in Julia as a Second Language

A concrete type is a type that can be directly instantiated or used as the representation of values rather than serving only as an abstract classification.

A battle simulator needs actual archers, pikemen, and knights—not just a label for all warriors. In Julia, Archer, Pikeman, and Knight can be concrete types: you can create objects of each. Warrior can be an abstract type that groups them, but you cannot create a Warrior object. 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

These definitions put three concrete types under the abstract type Warrior. Each mutable struct declares the fields its objects store. section 7.3.1

A composite type is a concrete type with fields; a primitive type is concrete and has a single value. Abstract types have no fields. Although each warrior above has a name and health, Warrior does not enforce those fields—that shared shape is a convention. section 7.3.1

julia> robin = Archer("Robin Hood", 34, 24)
Archer("Robin Hood", 34, 24)
julia> Warrior()
ERROR: MethodError: no constructors have been defined for Warrior

The REPL contrast is the key test: constructing an Archer works; calling Warrior() fails because an abstract type has no constructor. section 7.3.1

Use <: to place a concrete type under an abstract type, as in Archer <: Warrior. A concrete type cannot be a subtype of another concrete type. In a type hierarchy, concrete types therefore occupy leaf nodes. section 7.3.1 section 7.5

That hierarchy is useful for behavior, not just organization. A battle!(a::Warrior, b::Warrior) method accepts different concrete warrior types. When it calls attack!, Julia selects the applicable method at runtime using the arguments’ types, even though the broad Warrior annotations do not specify which concrete combatants will arrive. section 7.4.2 section 7.5

How Julia as a Second Language covers it

How deep it goes
Defines instantiation, fields, hierarchy limits, and a dispatch implication; stops short of implementing primitive types.
Examples
Contrasts an Archer constructor with a failing Warrior() call and uses archers, pikemen, and knights in a battle simulator.
What it assumes
Assumes familiarity with objects and functions while introducing abstract-versus-concrete types through definitions and REPL calls.
What you can do after
Build it from scratch: define instantiable warrior types under an abstract type and use them with shared battle methods.
How it connects
Connects abstract types, composite types, primitive types, subtyping, constructors, and multiple dispatch.

Also explained in

Compare how 3 books explain concrete type →

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.