|
109 | 109 |
|
110 | 110 | با این حال، برخی اشیا پایتون حاوی Attributeهایی هستند که ممکن است توسط تابع ``dir`` نمایش داده نشود. از این Attributeها به عنوان Special Attributes یاد میشود [`اسناد پایتون <https://docs.python.org/3/library/stdtypes.html#special-attributes>`__]. برای مثال صفت ``__definition.__name`` بسته به نوع definition، حاوی نام کلاس، تابع، متد یا غیره میباشد. |
111 | 111 |
|
| 112 | +همانطور که بیان شد subclassها به Attributeهای superclass کلاس خود نیز دسترسی دارند، به نمونه کدی دیگر نیز توجه نمایید: |
112 | 113 |
|
113 | | -Super Class |
114 | | -~~~~~~~~~~~~ |
| 114 | +.. code-block:: python |
| 115 | + :linenos: |
| 116 | +
|
| 117 | + class SuperClass: |
| 118 | + super_class_attr = {'one':1, 'two':2} |
| 119 | + |
| 120 | + def __init__(self, param_1): |
| 121 | + self.super_instance_attr = param_1 |
| 122 | + |
| 123 | +
|
| 124 | + class SubClass(SuperClass): |
| 125 | + sub_class_attr = {'six':6, 'seven':7} |
| 126 | + |
| 127 | + def __init__(self, param_1, param_2): |
| 128 | + super().__init__(param_1) |
| 129 | + self.sub_instance_attr = param_2 |
| 130 | +
|
| 131 | + def sub_instance_method(self): |
| 132 | + print('Called: sub_instance_method') |
| 133 | + print(self.super_instance_attr) |
| 134 | + print(self.sub_instance_attr) |
| 135 | + |
| 136 | + @classmethod |
| 137 | + def sub_class_method(cls): |
| 138 | + print('Called: sub_class_method') |
| 139 | + print(cls.super_class_attr) |
| 140 | + print(cls.sub_class_attr) |
| 141 | + |
| 142 | +
|
| 143 | + sub = SubClass('param_1', 'param_2') |
| 144 | + |
| 145 | + print(sub.super_instance_attr) |
| 146 | + print(sub.sub_instance_attr) |
| 147 | + print('-' * 30) |
| 148 | + print(SubClass.super_class_attr) |
| 149 | + print(SubClass.sub_class_attr) |
| 150 | + print('-' * 30) |
| 151 | + sub.sub_instance_method() |
| 152 | + print('-' * 30) |
| 153 | + SubClass.sub_class_method() |
| 154 | +
|
| 155 | +:: |
| 156 | + |
| 157 | + param_1 |
| 158 | + param_2 |
| 159 | + ------------------------------ |
| 160 | + {'one': 1, 'two': 2} |
| 161 | + {'six': 6, 'seven': 7} |
| 162 | + ------------------------------ |
| 163 | + Called: sub_instance_method |
| 164 | + param_1 |
| 165 | + param_2 |
| 166 | + ------------------------------ |
| 167 | + Called: sub_class_method |
| 168 | + {'one': 1, 'two': 2} |
| 169 | + {'six': 6, 'seven': 7} |
| 170 | + |
| 171 | + |
| 172 | +.. tip:: |
| 173 | + |
| 174 | + از درس پیش مفهوم سازنده (Constructor) در شی گرایی را بیاد داریم. چنانچه در superclass متدهای سازنده (``__new__`` و ``__init__``) پیادهسازی شده باشند، میبایست این متدها در subclassها نیز پیادهسازی شوند، نیازی نیست که سرآیند تعریف این دو متد با superclass یکسان باشد ولی میبایست مقادیر مورد نیاز متد superclass فراهم شود. برای این کار لازم است داخل متد subclassها به superclass دسترسی داشه باشیم، تابع ``super`` [`اسناد پایتون <https://docs.python.org/3/library/functions.html#super>`__] این امکان را فراهم میکند. |
| 175 | + |
| 176 | +خروجی تابع ``super`` [`اسناد پایتون <https://docs.python.org/3/library/functions.html#super>`__] شی است که نقش واسط را بین دو کلاس subclass و superclass دارد. نمونه کد زیر چگونگی فراخوانی انواع متدهای superclass را از subclass نمایش میدهد: |
| 177 | + |
| 178 | + |
| 179 | +.. code-block:: python |
| 180 | + :linenos: |
| 181 | +
|
| 182 | + class SuperClass: |
| 183 | + |
| 184 | + def super_instance_method(self): |
| 185 | + print('Called: super_instance_method') |
| 186 | + print(self) |
| 187 | + |
| 188 | + @classmethod |
| 189 | + def super_class_method(cls): |
| 190 | + print('Called: super_class_method') |
| 191 | + print(cls) |
| 192 | +
|
| 193 | + @staticmethod |
| 194 | + def super_static_method(): |
| 195 | + print('Called: super_static_method') |
| 196 | + |
| 197 | +
|
| 198 | + class SubClass(SuperClass): |
| 199 | + |
| 200 | + def sub_instance_method(self): |
| 201 | + super().super_instance_method() |
| 202 | + super().super_class_method() |
| 203 | + SuperClass.super_static_method() |
| 204 | + |
| 205 | + @classmethod |
| 206 | + def sub_class_method(cls): |
| 207 | + super().super_class_method() |
| 208 | + SuperClass.super_static_method() |
| 209 | +
|
| 210 | + @staticmethod |
| 211 | + def sub_static_method(): |
| 212 | + SuperClass.super_static_method() |
| 213 | + |
| 214 | +
|
| 215 | + sub = SubClass() |
| 216 | + |
| 217 | + sub.sub_instance_method() |
| 218 | + print('-' * 30) |
| 219 | + SubClass.sub_class_method() |
| 220 | + print('-' * 30) |
| 221 | + SubClass.sub_static_method() |
| 222 | +
|
| 223 | +:: |
| 224 | + |
| 225 | + Called: super_instance_method |
| 226 | + <__main__.SubClass object at 0x7f9c77052898> |
| 227 | + Called: super_class_method |
| 228 | + <class '__main__.SubClass'> |
| 229 | + Called: super_static_method |
| 230 | + ------------------------------ |
| 231 | + Called: super_class_method |
| 232 | + <class '__main__.SubClass'> |
| 233 | + Called: super_static_method |
| 234 | + ------------------------------ |
| 235 | + Called: super_static_method |
| 236 | + |
| 237 | +میدانیم که مفسر پایتون به صورت خودکار اطلاعات مربوط به شی فراخوانی کننده یک Instance Method را فراهم میآورد. زمانی که یک Instance Method از subclass فراخوانی میشود، تابع ``super`` میتواند آن شی و از طریق آن شی نیز به کلاس دسترسی داشته باشد بنابراین از داخل Instance Method کلاس subclass میتوان به واسطه تابع ``super`` به هر دو نوع Instance Methodها و Class Methodهای superclass دسترسی پیدا کرد، چرا که تابع ``super`` میتواند مقادیر ``self`` و ``cls`` را به منظور فراخوانی متدهای متناظر superclass به دست آورد. |
| 238 | + |
| 239 | +همچنین میدانیم که در فراخوانی Class Method، تنها اطلاعات مربوط به کلاس فراهم است و نه شی. زمانی که یک Class Method از subclass فراخوانی میشود، تابع ``super`` میتواند به کلاس مرتبط دسترسی داشته باشد بنابراین از داخل Class Method کلاس subclass تنها میتوان به واسطه تابع ``super`` به Class Methodهای superclass دسترسی پیدا کرد، چرا که تابع ``super`` تنها میتواند مقدار ``cls`` را به منظور فراخوانی متدهای متناظر superclass به دست آورد. |
| 240 | + |
| 241 | +در زمان فراخوانی Static Method نیز میدانیم که مفسر پایتون هیچ اطلاعاتی از شی و کلاس مرتبط را فراهم نمیآورد، بنابراین فراخوانی این متد با استفاده از تابع ``super`` انجام نمیپذیرد. در صورت نیاز به فراخوانی Static Methodهای کلاس superclass در کلاس subclass، همواره میتوانید از نام کلاس superclass بهره بگیرید. |
| 242 | + |
| 243 | + |
| 244 | +.. note:: |
| 245 | + |
| 246 | + این برنامهنویس است که تصمیم میگیرد یک کلاس چگونه طراحی شود. اینکه کدام متد باید از کدام نوع باشد مسئلهای است که برنامهنویس باید در زمان طراحی کلاس خود به آن فکر کند و از امکانات زبان برنامهنویسی پایتون به درستی در جهت بهتر و راحتتر به انجام رساندن مسئله خود بهره بگیرد. |
| 247 | + |
| 248 | +وراثت چندگانه (Multiple Inheritance) |
| 249 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
115 | 250 |
|
116 | 251 |
|
117 | 252 |
|
|
0 commit comments