Menu
CoddyTech

Desain Interface

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Python di Coddy. Pelajaran 26 dari 64.

Interface mendefinisikan kontrak yang harus dipatuhi oleh class. Di Python, kita membuat interface menggunakan abstract base class yang semua method-nya bersifat abstrak.

Impor module abc:

from abc import ABC, abstractmethod

Buat antarmuka yang hanya memiliki method abstrak:

class Drawable(ABC):
    @abstractmethod
    def draw(self):
        pass
    @abstractmethod
    def resize(self, width, height):
        pass

Semua method dalam interface harus bersifat abstract: method tersebut menentukan hal yang harus dilakukan oleh class yang mengimplementasikannya, bukan cara melakukannya.

Implementasikan antarmuka dalam class konkret:

class Circle(Drawable):
    def __init__(self, radius):
        self.radius = radius
    def draw(self):
        return "Drawing a circle"
    def resize(self, width, height):
        self.radius = min(width, height) / 2
        return f"Resized circle to radius {self.radius}"

Buat class lain yang mengimplementasikan interface yang sama:

class Rectangle(Drawable):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def draw(self):
        return "Drawing a rectangle"
    def resize(self, width, height):
        self.width = width
        self.height = height
        return f"Resized rectangle to {width}x{height}"

Gunakan antarmuka secara polimorfik:

shapes = [Circle(5), Rectangle(3, 4)]
for shape in shapes:
    print(shape.draw())
    print(shape.resize(10, 8))

Keluaran:

Drawing a circle
Resized circle to radius 4.0
Drawing a rectangle
Resized rectangle to 10x8

Kamu juga dapat menggunakan interface sebagai petunjuk tipe:

def render_shape(drawable: Drawable):
    return drawable.draw()
circle = Circle(3)
print(render_shape(circle))

output:

Drawing a circle

Poin utama: Interface menentukan apa yang harus dilakukan class, bukan bagaimana cara melakukannya. Gunakan class dasar abstrak yang hanya memiliki method abstrak untuk membuat kontrak yang jelas dan harus diikuti oleh class yang mengimplementasikannya. Ini memastikan perilaku yang konsisten pada berbagai implementasi.

challenge icon

Tantangan

Sedang

Dalam tantangan ini, kamu akan mengimplementasikan sistem pemutar media dengan interface.

Kamu perlu mengedit file berikut:

  • playable.py - Implementasikan abstract base class (interface)
  • song.py - Implementasikan class Song
  • video.py - Implementasikan class Video
  • mediaplayer.py - Implementasikan class MediaPlayer

Setiap file berisi komentar TODO terperinci untuk memandu implementasimu. Ikuti komentar ini untuk membuat sistem pemutar media yang lengkap dengan inheritance dan implementasi interface yang tepat.

Coba sendiri

from song import Song
from video import Video
from mediaplayer import MediaPlayer
from playable import Playable, MediaInfo

# Penangan kasus uji yang menyeluruh
test_case = input()

if test_case == "default_test":
    # Kasus uji bawaan dari soal asli
    song = Song("Bohemian Rhapsody", "Queen", 355)
    video = Video("Python Tutorial", "1080p", 1800)
    player = MediaPlayer()

    # Uji dengan lagu
    player.set_media(song)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())
    print()  # Baris kosong agar mudah dibaca

    # Uji dengan video
    player.set_media(video)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())

elif test_case == "empty_player":
    # Uji pemutar media tanpa media yang dipilih
    player = MediaPlayer()
    print(player.play())  # Seharusnya mencetak "No media set"
    print(player.pause())  # Seharusnya mencetak "No media set"
    print(player.stop())  # Seharusnya mencetak "No media set"

elif test_case == "time_formatting":
    # Uji format waktu dalam method get_info()
    song1 = Song("Short Song", "Artist A", 65)  # 1:05
    song2 = Song("Long Song", "Artist B", 3661)  # 61:01
    video1 = Video("Hour Video", "720p", 3600)  # 60:00
    
    print(song1.get_info())
    print(song2.get_info())
    print(video1.get_info())

elif test_case == "interface_compliance":
    # Uji apakah Song dan Video menerapkan antarmuka dengan benar
    song = Song("Test Song", "Test Artist", 180)
    video = Video("Test Video", "480p", 240)
    
    # Periksa penerapan antarmuka
    print(f"Song implements Playable: {isinstance(song, Playable)}")
    print(f"Song implements MediaInfo: {isinstance(song, MediaInfo)}")
    print(f"Video implements Playable: {isinstance(video, Playable)}")
    print(f"Video implements MediaInfo: {isinstance(video, MediaInfo)}")
    
    # Uji semua method antarmuka
    print(song.play())
    print(song.pause())
    print(song.stop())
    print(song.get_title())
    print(song.get_duration())
    print(song.get_info())
    
    print(video.play())
    print(video.pause())
    print(video.stop())
    print(video.get_title())
    print(video.get_duration())
    print(video.get_info())

elif test_case == "polymorphism":
    # Uji perilaku polimorfik dengan list berisi berbagai tipe media
    media_list = [
        Song("Song 1", "Artist 1", 180),
        Video("Video 1", "720p", 300),
        Song("Song 2", "Artist 2", 240),
        Video("Video 2", "1080p", 420)
    ]
    
    player = MediaPlayer()
    
    for media in media_list:
        player.set_media(media)
        print(f"Media: {media.get_title()}")
        print(f"Info: {media.get_info()}")
        print(f"Play: {player.play()}")
        print()

elif test_case == "edge_cases":
    # Uji kasus-kasus ekstrem
    empty_song = Song("", "", 0)
    edge_video = Video("A" * 100, "", -10)  # Judul sangat panjang, resolusi kosong, durasi negatif
    
    print(f"Empty song info: {empty_song.get_info()}")
    print(f"Edge video info: {edge_video.get_info()}")
    
    player = MediaPlayer()
    player.set_media(empty_song)
    print(player.play())
    player.set_media(edge_video)
    print(player.play())

elif test_case == "stress_test":
    # Buat uji beban dengan banyak object media
    songs = [Song(f"Song {i}", f"Artist {i}", i * 30) for i in range(1, 101)]
    videos = [Video(f"Video {i}", f"{i*10}p", i * 60) for i in range(1, 101)]
    
    player = MediaPlayer()
    
    # Uji semua lagu
    for i, song in enumerate(songs):
        player.set_media(song)
        if i % 10 == 0:  # Cetak hanya setiap data ke-10 agar output tidak terlalu banyak
            print(f"Playing song {i+1}: {player.play()}")
    
    # Uji semua video
    for i, video in enumerate(videos):
        player.set_media(video)
        if i % 10 == 0:  # Cetak hanya setiap data ke-10 agar output tidak terlalu banyak
            print(f"Playing video {i+1}: {player.play()}")
    
    print("Stress test completed successfully!")
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Python online