Menu
CoddyTech

Arayüz Tasarımı

Coddy'nin Python Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 26 / 64.

Bir arayüz, sınıfların uyması gereken bir sözleşme tanımlar. Python'da, tüm metotların soyut olduğu soyut temel sınıfları kullanarak arayüzler oluştururuz.

abc modülünü içe aktarın:

from abc import ABC, abstractmethod

Yalnızca soyut metotlardan oluşan bir arayüz oluşturun:

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

Bir arayüzdeki tüm metotlar soyut olmalıdır; gerçekleştiren sınıfların ne yapması gerektiğini tanımlarlar, bunu nasıl yapacaklarını değil.

Arayüzü somut bir sınıfta uygulayın:

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}"

Aynı arayüzü uygulayan başka bir sınıf oluşturun:

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}"

Arayüzü polimorfik olarak kullanın:

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

Çıktı:

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

Arayüzleri tür ipuçları olarak da kullanabilirsiniz:

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

Çıktı:

Drawing a circle

Temel Nokta: Arayüzler, sınıfların bunu nasıl yapacağını değil, ne yapması gerektiğini tanımlar. Uygulayan sınıfların uyması gereken açık sözleşmeler oluşturmak için yalnızca soyut metotlar içeren soyut temel sınıfları kullanın. Bu, farklı uygulamalar arasında tutarlı davranış sağlar.

challenge icon

Görev

Orta

Bu görevde, arayüzlere sahip bir medya oynatıcı sistemi uygulayacaksınız.

Aşağıdaki dosyaları düzenlemeniz gerekiyor:

  • playable.py - Soyut temel sınıfları (arayüzleri) uygulayın
  • song.py - Song sınıfını uygulayın
  • video.py - Video sınıfını uygulayın
  • mediaplayer.py - MediaPlayer sınıfını uygulayın

Her dosyada, uygulamanıza rehberlik edecek ayrıntılı TODO yorumları bulunur. Uygun kalıtım ve arayüz uygulamasıyla eksiksiz bir medya oynatıcı sistemi oluşturmak için bu yorumları izleyin.

Kendin dene

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

# Kapsamlı test durumu işleyicisi
test_case = input()

if test_case == "default_test":
    # Orijinal problemden varsayılan test durumu
    song = Song("Bohemian Rhapsody", "Queen", 355)
    video = Video("Python Tutorial", "1080p", 1800)
    player = MediaPlayer()

    # Şarkı ile test
    player.set_media(song)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())
    print()  # Okunabilirlik için boş satır

    # Video ile test
    player.set_media(video)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())

elif test_case == "empty_player":
    # Medya ayarlanmamış medya oynatıcıyı test et
    player = MediaPlayer()
    print(player.play())  # Should print "No media set"
    print(player.pause())  # Should print "No media set"
    print(player.stop())  # Should print "No media set"

elif test_case == "time_formatting":
    # get_info() metodundaki zaman biçimlendirmesini test et
    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":
    # Song ve Video'nun arayüzleri düzgün şekilde uyguladığını test et
    song = Song("Test Song", "Test Artist", 180)
    video = Video("Test Video", "480p", 240)
    
    # Arayüz uygulamasını kontrol et
    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)}")
    
    # Tüm arayüz metotlarını test et
    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":
    # Farklı medya türlerinden oluşan bir liste ile polimorfik davranışı test et
    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":
    # Uç durumları test et
    empty_song = Song("", "", 0)
    edge_video = Video("A" * 100, "", -10)  # Çok uzun başlık, boş çözünürlük, negatif süre
    
    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":
    # Birçok medya nesnesiyle bir stres testi uygula
    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()
    
    # Tüm şarkılarla test et
    for i, song in enumerate(songs):
        player.set_media(song)
        if i % 10 == 0:  # Çok fazla çıktıyı önlemek için yalnızca her 10.'yu yazdır
            print(f"Playing song {i+1}: {player.play()}")
    
    # Tüm videolarla test et
    for i, video in enumerate(videos):
        player.set_media(video)
        if i % 10 == 0:  # Çok fazla çıktıyı önlemek için yalnızca her 10.'yu yazdır
            print(f"Playing video {i+1}: {player.play()}")
    
    print("Stress test completed successfully!")
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Python derleyicisi