A trait method doesn't have to be abstract. You can give it a default implementation right in the trait, and types get it for free unless they override it.
Behavior for free
Provide a body in the trait definition, and every implementor inherits it without writing anything. A type can still override the default when it needs custom behavior. This is how a trait offers a rich API while requiring implementors to write only a small core.
Defaults calling required methods
The powerful move: a default method can call other methods of the same trait — including ones with no default. So you require implementors to provide one small method, and the trait builds a whole family of behaviors on top of it. The standard library's Iterator works exactly this way: implement next, get dozens of methods (map, filter, sum...) for free.
Iterator requires only next() and hands you 70+ adapter methods built on it. Design your traits the same way.Why this beats inheritance
In class-based languages you'd get shared behavior by inheriting from a base class — dragging along its data and its place in a hierarchy. Default trait methods give you the shared behavior with none of the coupling: any type, anywhere, can opt into the trait and get the defaults, without being forced into a family tree.