Team members are assigned or jointly choose a cohesive, logical block of the system to individually develop and maintain. The architecture of a system expects blocks to be handled by individuals and provides additional attention to the internal system boundaries of these blocks.
If/When there is a relative period of downtime, team members may experiment with working in other's blocks to see/experiment/learn other practices. These periods are marks of a healthy project.
Specialization is for ants but expertise is built by repeated habit. While most coding interactions could be viewed as unique events, the repeated task is summoning -- and then alteration of -- the mental model of the software. Pushing engineers all over a project's problem space at best slows repetition and therefore mastery of the individual components of a project.
Many projects have system models far too large to fit into any single engineer's mind at a time and will necessarily be broken into coherent blocks that are dealt with together abstractly and only individually in detail. In most situations, the entire system model isn't relevant besides. When engineers grapple with the mental model of the system, they will be doing so in logical chunks. Those are the same chunks to give individual ownership over.