# Unit 2 – Advanced Demo: Song and Featured Artist

Many songs are collaborations — think of all the tracks with a featured 
artist. This demo extends the Song and Artist demo: songs work the same 
as before, but now a song can also have an optional featured artist. You 
can add one, remove it, or leave the song as a solo track. Unlike the 
main artist, the featured slot can be empty.

## Setting up

1. Compile `Artist` and `Song`.
2. Create two artists: `Artist("Post Malone", "hip-hop")` and 
   `Artist("Swae Lee", "pop")`.
3. Create a solo song: `Song("Wow", postMalone)`.
4. Call `describe()` — no featured artist; the fallback text appears.

## Experimenting

5. Call `feature(swaeLee)` on the song, then `credits()` — now shows 
   `"Wow" by Post Malone ft. Swae Lee`.
6. Call `describe()` — the feature info now comes from the real `Artist` 
   object.
7. Call `clearFeature()`, then `describe()` again — the fallback returns.
8. Create a second song: `Song("Sunflower", postMalone)`. Call 
   `feature(swaeLee)` on it too.
9. Call `clearFeature()` on the first song only — the second is 
   unaffected. Each song owns its featured artist slot independently.

## What to look at in the code

10. Open `Song`. Compare `artist: Artist` (non-nullable, as in the basic 
    demo) with `var featuredArtist: Artist? = null` — the `?` marks it as 
    nullable; it may hold an `Artist` or `null`.
11. In `describe()`, the expression `featuredArtist?.credit() ?: "no 
    featured artist"` calls `credit()` only if `featuredArtist` is not 
    null; if it is null, the Elvis operator `?:` supplies the fallback 
    string.
12. In `credits()`, notice `val featured = featuredArtist` before the 
    null check. Copying the property to a local `val` lets Kotlin confirm 
    the value cannot change between the check and the access — without 
    it, the compiler cannot guarantee safety on a mutable `var` property.
