Skip to main content

Music Streaming Platform

Inheritance hierarchy for platform users with artist rights management

Person (Abstract Base Class)

The parent abstract class for all platform users.

  • firstName: Person's first name (protected - accessible to subclasses)
  • lastName: Person's last name (protected - accessible to subclasses)
  • Person(String firstName, String lastName): Constructor to initialize names
  • getFullName(): Returns concatenated first and last name
  • Protected members allow both Artist and User subclasses to access name information
  • Cannot be instantiated directly - serves as a template for concrete user types

Artist

Music artist or band registered on the platform.

  • bandName: Name of the artist or band (private)
  • size: Number of members in the band (private) - 1 for solo artist, 2+ for bands
  • registration: SACEM registration object (private)
  • Artist(String firstName, String lastName, String bandName, int size): Constructor that calls super()
  • registerWithSacem(SacemRegistration reg): Assigns SACEM registration to this artist
  • getBandName(): Returns the band name
  • Inherits firstName and lastName from Person
  • Must have exactly one SacemRegistration (one-to-one relationship)
  • SacemRegistration is required for copyright protection and royalty collection

User

Regular platform user who can create playlists.

  • id: Unique user identifier (private)
  • userCount: Static counter for total users created (private, shared across all instances)
  • birthDate: User's date of birth for age verification (private)
  • playlists: List of playlists created by this user (private List<Playlist>)
  • User(String firstName, String lastName, Date birthDate): Constructor that calls super() and auto-increments userCount
  • createPlaylist(String name): Creates new playlist and adds to user's collection
  • getPlaylists(): Returns list of user's playlists
  • Inherits firstName and lastName from Person
  • Can create zero or more playlists (one-to-many relationship)
  • Represents listeners/consumers on the platform

SacemRegistration

Rights management registration for artists (SACEM - French music rights organization).

  • reference: Unique registration reference number (private)
  • dateRegistration: Date when artist registered with SACEM (private)
  • SacemRegistration(String reference, Date dateRegistration): Constructor to initialize registration
  • getReference(): Returns the registration reference
  • Each Artist must have exactly one registration
  • Required for copyright protection and royalty payments

Playlist

User-created music playlist.

  • id: Unique playlist identifier (private)
  • createdOn: Timestamp when playlist was created (private)
  • name: Name of the playlist (private)
  • Playlist(String name): Constructor that auto-generates ID and sets creation timestamp
  • getName(): Returns the playlist name
  • Belongs to exactly one User
  • One User can have multiple playlists
  • Represents curated music collections by platform users

Practice Exercise: Implement the Music Streaming Platform

Objective: Implement the complete music streaming platform with abstract base class, static counter, and user/artist management.

Requirements:

  1. Create the abstract Person base class
  2. Implement Artist and User classes extending Person
  3. Implement SacemRegistration and Playlist classes
  4. Demonstrate polymorphism by storing both Artists and Users as Person references
  5. Use static counter for User tracking
💡 Click to see suggested implementation
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

// Abstract base class
public abstract class Person {
protected String firstName;
protected String lastName;

public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

public String getFullName() {
return firstName + " " + lastName;
}

public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
}

// SacemRegistration class
public class SacemRegistration {
private String reference;
private Date dateRegistration;

public SacemRegistration(String reference, Date dateRegistration) {
this.reference = reference;
this.dateRegistration = dateRegistration;
}

public String getReference() { return reference; }
public Date getDateRegistration() { return dateRegistration; }
}

// Artist class
public class Artist extends Person {
private String bandName;
private int size;
private SacemRegistration registration;

public Artist(String firstName, String lastName, String bandName, int size) {
super(firstName, lastName);
this.bandName = bandName;
this.size = size;
this.registration = null; // Not registered initially
}

public void registerWithSacem(SacemRegistration reg) {
this.registration = reg;
System.out.println(bandName + " registered with SACEM. Reference: " + reg.getReference());
}

public boolean isRegistered() {
return registration != null;
}

public String getBandName() { return bandName; }
public int getSize() { return size; }
public SacemRegistration getRegistration() { return registration; }
}

// Playlist class
public class Playlist {
private String id;
private Date createdOn;
private String name;

public Playlist(String name) {
this.id = UUID.randomUUID().toString(); // Auto-generate unique ID
this.name = name;
this.createdOn = new Date(); // Current timestamp
}

public String getId() { return id; }
public String getName() { return name; }
public Date getCreatedOn() { return createdOn; }
}

// User class
public class User extends Person {
private static int userCount = 0; // Static counter
private int id;
private Date birthDate;
private List<Playlist> playlists;

public User(String firstName, String lastName, Date birthDate) {
super(firstName, lastName);
this.id = ++userCount; // Auto-increment ID
this.birthDate = birthDate;
this.playlists = new ArrayList<>();
}

public void createPlaylist(String name) {
Playlist playlist = new Playlist(name);
playlists.add(playlist);
System.out.println(getFullName() + " created playlist: " + name);
}

public List<Playlist> getPlaylists() { return playlists; }
public int getId() { return id; }
public Date getBirthDate() { return birthDate; }
public static int getUserCount() { return userCount; }
}

// Example usage
public class MusicPlatformDemo {
public static void main(String[] args) {
System.out.println("=== Music Streaming Platform Demo ===\n");

// Create artists
Artist artist1 = new Artist("John", "Lennon", "The Beatles", 4);
Artist artist2 = new Artist("Taylor", "Swift", "Taylor Swift", 1);

// Create SACEM registrations
SacemRegistration reg1 = new SacemRegistration("SACEM-001-1960", new Date());
SacemRegistration reg2 = new SacemRegistration("SACEM-002-2006", new Date());

// Register artists
artist1.registerWithSacem(reg1);
artist2.registerWithSacem(reg2);

// Create users
User user1 = new User("Alice", "Johnson", new Date(2000, 1, 15));
User user2 = new User("Bob", "Smith", new Date(1995, 6, 22));
User user3 = new User("Charlie", "Brown", new Date(2002, 11, 3));

System.out.println("\nTotal users created: " + User.getUserCount());

// Users create playlists
System.out.println("\n=== Creating Playlists ===");
user1.createPlaylist("My Favorites");
user1.createPlaylist("Workout Mix");
user2.createPlaylist("Chill Vibes");
user3.createPlaylist("Road Trip");

// Display user info
System.out.println("\n=== User Information ===");
System.out.println("User #" + user1.getId() + ": " + user1.getFullName() +
" - " + user1.getPlaylists().size() + " playlists");
System.out.println("User #" + user2.getId() + ": " + user2.getFullName() +
" - " + user2.getPlaylists().size() + " playlists");
System.out.println("User #" + user3.getId() + ": " + user3.getFullName() +
" - " + user3.getPlaylists().size() + " playlists");

// Display artist info
System.out.println("\n=== Artist Information ===");
System.out.println(artist1.getFullName() + " performs as: " + artist1.getBandName() +
" (" + artist1.getSize() + " members)");
System.out.println(" SACEM Registered: " + artist1.isRegistered());
System.out.println(artist2.getFullName() + " performs as: " + artist2.getBandName() +
" (Solo artist)");
System.out.println(" SACEM Registered: " + artist2.isRegistered());

// Demonstrate polymorphism
System.out.println("\n=== Polymorphism Demo ===");
List<Person> allPeople = new ArrayList<>();
allPeople.add(artist1);
allPeople.add(artist2);
allPeople.add(user1);
allPeople.add(user2);
allPeople.add(user3);

System.out.println("All people on platform:");
for (Person person : allPeople) {
System.out.println(" - " + person.getFullName() +
" (" + person.getClass().getSimpleName() + ")");
}
}
}

Key Implementation Points:

  • Use abstract keyword for Person class
  • Use static keyword for userCount (use $ in Mermaid)
  • Call super(firstName, lastName) in both Artist and User constructors
  • Use UUID.randomUUID() for auto-generating unique playlist IDs
  • Use new Date() for timestamps
  • Polymorphism allows storing Artists and Users in List<Person>
  • Use ++userCount for auto-incrementing static counter
  • Check if Artist is registered before allowing certain operations