در برنامه نویسی شی گرا، کلاس ها عمدتاً هدفشان کپسوله کردن داده ها و رفتارها است. با استفاده از این ایده، اگر یک مدل و شئی جایگزین همان رفتارها را ارائه دهد، بدون در نظر گرفتن اینکه این جایگزین چیست، میتوانید با ابجکت اصلی جایگزین شود. کدی که از رفتارها استفاده می کند صرف نظر از اینکه چه شی ای آن را ارائه می دهد، کار خواهد کرد. این اصل اساس یک سیستم نوع شناخته شده به نام اردک تایپ است.
اما در اصل این نوع سیستم چه تفاوتی با وراثت و Interface در زبانهایی مثل جاوا دارد؟
در جاوا و زبانهای مشابه زمانی که شما تابع را پیاده سازی میکنید نوع ورودی و خروجی را به صورت دقیق مشخص میکنید. بنابر این نه تنها یک ورودی باید از نوع تعیین شده باشد بلکه در نتیجه آن باید رفتاری کاملا مشابه به آن نشان دهد.
اما در زبان برنامه نویسی پایتون نیازی به تعیین کردن نوع ورودی نیست. بنابر این اگر هر شئی ورودی تابع از هر نوعی رفتار مشابهای با انچه در تابع انتظار میرود را داشته باشد، کار تمام است.
مثل فرض کنید در یک تابع شما انتظار دارید اشیا ورودی دو تابع swim و fly را داشته باشند. در این حالت اگر ما اشیا زیر را داشته باشیم:
class Duck:
def swim(self):
print("The duck is swimming")
def fly(self):
print("The duck is flying")
class Swan:
def swim(self):
print("The swan is swimming")
def fly(self):
print("The swan is flying")
class Albatross:
def swim(self):
print("The albatross is swimming")
def fly(self):
print("The albatross is flying")
میتوانیم همه آنها را (با وجود اینکه از هم ارث بری ندارند) را به عنوان ورودی به متد ارسال کنیم:
>>> from birds_v1 import Duck, Swan, Albatross
>>> birds = [Duck(), Swan(), Albatross()]
>>> for bird in birds:
... bird.fly()
... bird.swim()
...
The duck is flying
The duck is swimming
The swan is flying
The swan is swimming
The albatross is flying
The albatross is swimming
به این اصل میگن داک تایپ یا تایپ اردک.