• OOP با مثال چیست. برای Dummies. دوره ویدیویی: مبانی برنامه نویسی شی گرا

    پارادایم های برنامه نویسی

    برنامه نویسی شی گرا (OOP)- یک روش برنامه نویسی مبتنی بر نمایش یک برنامه به عنوان مجموعه ای از اشیا، که هر کدام نمونه ای از یک کلاس خاص هستند و کلاس ها یک سلسله مراتب ارثی را تشکیل می دهند.

    نکات مهم زیر در این تعریف باید مورد توجه قرار گیرد: 1) برنامه نویسی شی گرا از اشیا به جای الگوریتم ها به عنوان بلوک های منطقی اصلی استفاده می کند. 2) هر شی نمونه ای از یک کلاس خاص است. 3) کلاس ها سلسله مراتبی را تشکیل می دهند. یک برنامه فقط در صورتی شی گرا در نظر گرفته می شود که هر سه این الزامات برآورده شوند. به طور خاص، برنامه نویسی که از وراثت استفاده نمی کند، شی گرا نامیده نمی شود، بلکه برنامه نویسی با انواع داده های انتزاعی است.

    یوتیوب دایره المعارفی

      1 / 5

      ✪ برنامه نویسی شی گرا در سال 2019

      ✪ طراحی شی گرا قسمت 1 - نحوه طراحی کلاس ها

      ✪ اصول اولیه برنامه نویسی شی گرا. OOP چیست و چرا به آن نیاز است؟

      ✪ مبانی OOP در C++

      ✪ برنامه نویسی شی گرا. کلاس ها و اشیاء. درس 3

      زیرنویس

    مفاهیم اساسی

    انتزاع داده انتزاع به معنای جداسازی اطلاعات معنادار و حذف اطلاعات بی اهمیت از بررسی است. OOP فقط انتزاع داده ها را در نظر می گیرد (اغلب به سادگی آن را "انتزاع" می نامند)، به معنای مجموعه ای از ویژگی های معنی دار یک شی که برای بقیه برنامه قابل دسترسی است. Encapsulation Encapsulation یک ویژگی سیستمی است که به شما امکان می دهد داده ها و روش هایی را که با آنها کار می کنند در یک کلاس ترکیب کنید. برخی از زبان ها (مانند C++، جاوا یا روبی) کپسولاسیون را با پنهان کردن یکی می دانند، اما برخی دیگر (Smalltalk، Eiffel، OCaml) بین این مفاهیم تفاوت قائل می شوند. وراثت وراثت یک ویژگی سیستمی است که به شما امکان می دهد یک کلاس جدید را بر اساس کلاس موجود با عملکرد جزئی یا کاملاً قرضی توصیف کنید. کلاسی که وراثت از آن مشتق می شود، پایه، والد یا سوپرکلاس نامیده می شود. طبقه جدید یک طبقه اولاد، وارث، فرزند یا مشتق است. چند شکلی زیرگروهی چندشکلی فرعی (در OOP به سادگی "چند شکلی" نامیده می شود) یک ویژگی سیستمی است که به شما امکان می دهد از اشیاء با رابط یکسان بدون اطلاعات در مورد نوع و ساختار داخلی شی استفاده کنید. نوع دیگری از چندشکلی - پارامتریک - در OOP برنامه نویسی تعمیم یافته نامیده می شود. کلاس A یک نوع داده جهانی و پیچیده است که از یک مجموعه یکپارچه موضوعی از "فیلدها" (متغیرهای انواع ابتدایی تر) و "روش ها" (توابع کار با این فیلدها) تشکیل شده است، یعنی مدلی از یک موجودیت اطلاعاتی با رابط های داخلی و خارجی برای عملکرد محتویات آن (مقادیر فیلد). به طور خاص، کلاس ها به طور گسترده از بلوک های خاصی از یک یا چند روش جفتی استفاده می کنند که مسئول عملیات ابتدایی با یک فیلد خاص (رابط اختصاص دادن و خواندن یک مقدار) هستند که دسترسی مستقیم به فیلد را شبیه سازی می کند. این بلوک‌ها «properties» نامیده می‌شوند و تقریباً همان نام خاص فیلد خود را دارند (به عنوان مثال، نام فیلد ممکن است با یک نام کوچک شروع شود و نام ویژگی ممکن است با حرف بزرگ). جلوه دیگر ماهیت رابط یک کلاس این است که هنگام کپی کردن متغیر مربوطه از طریق انتساب، فقط رابط کپی می شود، اما نه خود داده، یعنی کلاس یک نوع داده مرجع است. یک متغیر شی که از نوع مشخص شده توسط یک کلاس است، نمونه ای از آن کلاس نامیده می شود. علاوه بر این، در برخی از سیستم‌های زمان اجرا، یک کلاس نیز می‌تواند توسط برخی شیء در طول اجرای برنامه از طریق شناسایی نوع داده پویا نمایش داده شود. به طور معمول، کلاس ها به گونه ای توسعه می یابند که از یکپارچگی داده های شی، و همچنین یک رابط کاربری راحت و ساده، مطابق با ماهیت شی و کار در حال حل، اطمینان حاصل کنند. به نوبه خود، یکپارچگی حوزه موضوعی اشیا و رابط های آنها و همچنین راحتی طراحی آنها با وراثت تضمین می شود. شی یک موجودیت در فضای آدرس یک سیستم کامپیوتری که هنگام ایجاد نمونه ای از یک کلاس ظاهر می شود (به عنوان مثال، پس از اجرای نتایج کامپایل و پیوند کد منبع برای اجرا).

    طبقه بندی انواع فرعی OOP

    لوکا کاردلیو مارتین آبادی یک منطق نظری برای OOP و یک طبقه بندی بر اساس این منطق ایجاد کردند. آنها خاطرنشان می کنند که مفاهیم و مقوله هایی که آنها شناسایی کرده اند در همه زبان های شی گرا با هم یافت نمی شوند؛ بیشتر زبان ها فقط از زیرمجموعه های این نظریه و حتی گاهی اوقات انحرافات عجیب و غریب از آن را پشتیبانی می کنند.

    قابل توجه ترین تفاوت ها در تجلی شاخص های کیفیت بین زبان های مختلف:

    • در زبان های رایج، اصول اعلام شده با هدف افزایش نرخ استفاده مجدد از کد است که در ابتدا برای برنامه نویسی ضروری کم است. در کاربردهای تایپ چند شکلی، استفاده از مفاهیم OOP، برعکس، به معنای کاهش آشکار آن به دلیل گذار از چندشکلی پارامتری به چندشکلی ad hoc است. زبان‌های تایپ شده پویا (Smalltalk، Python، Ruby) از این اصول برای سازماندهی منطقی یک برنامه استفاده می‌کنند و پیش‌بینی تأثیر آن‌ها بر میزان استفاده مجدد دشوار است - این به شدت به رشته برنامه‌نویس بستگی دارد. به عنوان مثال، در CLOS، چند روش به طور همزمان توابع درجه یک هستند، که به آنها اجازه می دهد به طور همزمان به عنوان مربوط به کمیت، و به صورت تعمیم یافته (چند شکلی واقعی).
    • استفاده از زبان های سنتی OO تایپ اسمی، یعنی مجاز بودن استفاده مشترک از اشیاء کلاس های مختلف تنها در صورتی که روابط مرتبط بین کلاس ها به صراحت نشان داده شده باشد. زبان‌هایی که به‌صورت چند شکلی تایپ می‌شوند با این ویژگی مشخص می‌شوند تایپ سازه اییعنی هماهنگی کلاس ها بین خودشان با همان مکانیزم هماهنگی عدد 5 با نوع int . زبان‌های تایپ پویا نیز در اینجا جایگاه متوسطی را اشغال می‌کنند.

    منطق تعمیم یافته ارسال پویا(شامل چندگانه) توسط جوزپه کاستانیا در اواسط دهه 1990 ساخته شد.

    داستان

    OOP در نتیجه توسعه ایدئولوژی برنامه ریزی رویه ای به وجود آمد، جایی که داده ها و زیر روال ها (رویه ها، توابع) برای پردازش آنها به طور رسمی مرتبط نیستند. برای پیشرفتهای بعدیبرنامه نویسی شی گرا اغلب است پراهمیتدارای مفاهیم رویدادها (به اصطلاح برنامه نویسی رویداد محور) و مؤلفه ها (برنامه نویسی مؤلفه، COP).

    تعامل اشیاء از طریق. نتیجه توسعه بیشتر OOP ظاهراً برنامه نویسی عامل گرا خواهد بود که در آن عوامل- بخش های مستقل کد در سطح اجرا. عامل ها از طریق تغییر با هم تعامل دارند محیط، که در آن قرار دارند.

    ساختارهای زبانی که از نظر ساختاری مستقیماً با اشیا مرتبط نیستند، اما آنها را برای ایمن (موقعیت‌های استثنایی، بررسی‌ها) و عملکرد کارآمد آنها همراهی می‌کنند، از آنها در جنبه‌هایی (در برنامه‌نویسی جنبه‌محور) کپسوله می‌شوند. برنامه نویسی سوژه گرا مفهوم یک شی را با ایجاد تعامل بیشتر و مستقل بین اشیا گسترش می دهد. این ممکن است یک مرحله انتقالی بین برنامه نویسی OOP و عامل از نظر تعامل مستقل آنها باشد.

    اولین زبان برنامه نویسی که مفاهیم اساسی را معرفی کرد که بعداً به یک پارادایم تبدیل شد، Simula بود، اما اصطلاح «شی گرا» در زمینه استفاده از این زبان استفاده نشد. در زمان ظهور خود در سال 1967، ایده های انقلابی را پیشنهاد کرد: اشیا، کلاس ها، روش های مجازی و غیره، اما همه اینها توسط معاصران به عنوان چیزی بزرگ تلقی نمی شد. در واقع، Simula یک «الگول با کلاس‌ها» بود که بیان بسیاری از مفاهیم پیچیده را در برنامه‌نویسی رویه‌ای ساده می‌کرد. مفهوم کلاس در Simula را می توان به طور کامل از طریق ترکیب ساختارهای الگول تعریف کرد (یعنی یک کلاس در Simula چیزی پیچیده است که از طریق اولیه توصیف می شود).

    نگاهی به برنامه نویسی از یک "زاویه جدید" (متفاوت از رویه ای) توسط آلن کی و دن اینگالز در زبان اسمال تاک ارائه شد. در اینجا مفهوم یک کلاس به ایده اساسی برای تمام ساخت‌های دیگر زبان تبدیل شده است (یعنی کلاس در اسمال تاک یک کلاس ابتدایی است که ساختارهای پیچیده‌تری با آن توصیف می‌شوند). او اولین زبان برنامه نویسی شی گرا بود که به طور گسترده مورد استفاده قرار گرفت.

    در حال حاضر، تعداد زبان‌های برنامه‌نویسی کاربردی (فهرست زبان‌ها) که پارادایم شی‌گرا را پیاده‌سازی می‌کنند، در مقایسه با پارادایم‌های دیگر، بیشترین تعداد را دارد. رایج ترین زبان ها در صنعت (C++، دلفی، سی شارپ، جاوا و غیره) مدل شی Simula را در خود جای داده اند. نمونه هایی از زبان های مبتنی بر مدل Smalltalk عبارتند از Objective-C، Python، Ruby.

    تعریف OOP و مفاهیم اساسی آن

    در مرکز OOP مفهوم است هدف - شی.یک شی موجودی است که می توان پیام ها را به آن ارسال کرد و می تواند با استفاده از داده های خود به آنها پاسخ دهد. یک شی نمونه ای از یک کلاس است. داده های شی از بقیه برنامه پنهان است. مخفی کردن داده ها را کپسوله کردن می نامند.

    وجود کپسوله سازی برای عینی بودن یک زبان برنامه نویسی کافی است، اما هنوز به این معنی نیست که شی گرا است - این مستلزم وجود وراثت است.

    اما حتی وجود کپسوله سازی و وراثت، یک زبان برنامه نویسی را از دیدگاه OOP کاملاً مبتنی بر شی نمی سازد. مزایای اصلی OOP تنها زمانی ظاهر می شود که زبان برنامه نویسی چند شکلی زیرگونه را پیاده سازی کند - توانایی پردازش یکنواخت اشیاء با پیاده سازی های مختلف، به شرط وجود یک رابط مشترک.

    دشواری تعریف

    OOP بیش از چهل سال سابقه دارد، اما با وجود این، هنوز تعریف روشن و پذیرفته شده ای از این فناوری وجود ندارد. اصول اساسی که در زبان‌ها و سیستم‌های شیء اول وضع شده‌اند، در بسیاری از زمان‌های بعدی، دستخوش تغییرات (یا تحریف) و افزوده‌هایی شده‌اند. علاوه بر این، از اواسط دهه 1980، اصطلاح "شی گرا" مد شد، در نتیجه همان چیزی که کمی قبل از آن با اصطلاح "ساختاری" (که پس از گسترش برنامه نویسی ساخت یافته مد شد، برای آن اتفاق افتاد. فناوری) - برای اطمینان از جذابیت آنها، به طور مصنوعی به هر پیشرفت جدیدی "پیوست" شد. بیورن استروستروپ در سال 1988 نوشت که توجیه «شی گرا بودن» چیزی، در بیشتر موارد، به یک قیاس نادرست ختم می شود: «X خوب است. شی گرایی خوب است. از این رو"X شی گرا است."

    راجر کینگ استدلال کرد که گربه اش شی گرا است. از دیگر مزایای آن، گربه رفتار مشخصی را نشان می دهد، به پیام ها واکنش نشان می دهد، دارای واکنش های موروثی است و حالت داخلی کاملا مستقل خود را مدیریت می کند.

    با این حال، عمومیت مکانیسم پیام‌رسانی جنبه دیگری نیز دارد - انتقال پیام "کامل" نیاز به سربار اضافی دارد که همیشه قابل قبول نیست. بنابراین، بسیاری از زبان های برنامه نویسی شی گرا مدرن از این مفهوم استفاده می کنند "ارسال پیام به عنوان فراخوانی روش"- اشیاء دارای روشهای قابل دسترسی خارجی هستند که فراخوانی آنها تعامل اشیاء را تضمین می کند. این رویکرد در تعداد زیادی از زبان های برنامه نویسی از جمله C++، Object Pascal، Java، Oberon-2 پیاده سازی شده است. با این حال، این منجر به این واقعیت می شود که پیام ها دیگر اشیاء مستقل نیستند و در نتیجه ویژگی هایی ندارند که امکانات برنامه نویسی را محدود می کند. برخی از زبان ها از یک نمایش ترکیبی استفاده می کنند که مزایای هر دو رویکرد را به طور همزمان نشان می دهد - به عنوان مثال، CLOS، Python.

    مفهوم روش های مجازیکه توسط این زبان‌ها و سایر زبان‌های مدرن پشتیبانی می‌شود، به عنوان ابزاری برای اطمینان از اجرای روش‌های مورد نظر هنگام استفاده از متغیرهای چندشکلی پدیدار شد، یعنی در اصل، به عنوان تلاشی برای گسترش توانایی فراخوانی متدها برای اجرای بخشی از عملکرد ارائه شده توسط مکانیسم پردازش پیام

    ویژگی های پیاده سازی

    همانطور که در بالا ذکر شد، در زبان های برنامه نویسی شی گرا مدرن، هر شی یک مقدار متعلق به یک کلاس خاص است. یک کلاس یک نوع داده ترکیبی است که توسط برنامه نویس اعلام شده است و شامل:

    فیلدهای داده پارامترهای یک شی (البته نه همه، بلکه فقط موارد ضروری در برنامه) که وضعیت آن را مشخص می کند (خواص شی منطقه موضوع). گاهی اوقات فیلدهای داده یک شی را ویژگی های شی می نامند که می تواند منجر به سردرگمی شود. از نظر فیزیکی، فیلدها مقادیر (متغیرها، ثابت ها) را نشان می دهند که به عنوان متعلق به یک کلاس هستند. روش ها رویه ها و توابع مرتبط با یک کلاس. آنها اقداماتی را که می توان روی یک شی از آن نوع انجام داد و خود شی می تواند انجام دهد را تعریف می کنند.

    کلاس ها می توانند از یکدیگر ارث ببرند. کلاس descendant تمام فیلدها و متدهای کلاس والد را دریافت می کند، اما می تواند آنها را با خود تکمیل کند یا موارد موجود را لغو کند. بیشتر زبان‌های برنامه‌نویسی فقط از وراثت تک پشتیبانی می‌کنند (یک کلاس می‌تواند فقط یک کلاس والد داشته باشد)، فقط برخی از آنها اجازه وراثت چندگانه را می‌دهند - تولید یک کلاس از دو یا چند کلاس والد. وراثت چندگانه تعدادی از مشکلات را ایجاد می کند، چه منطقی و چه صرفاً اجرایی، بنابراین پشتیبانی کامل از آن گسترده نیست. در عوض، در دهه 1990، مفهوم رابط ظاهر شد و به طور فعال در زبان های شی گرا معرفی شد. اینترفیس یک کلاس بدون فیلد و بدون پیاده سازی است و فقط شامل هدرهای متد است. اگر کلاسی یک اینترفیس را به ارث می برد (یا به قول خودشان پیاده سازی می کند)، باید تمام متدهای آن را پیاده سازی کند. استفاده از واسط ها جایگزین نسبتا ارزانی برای وراثت چندگانه فراهم می کند.

    تعامل اشیا در اکثریت قریب به اتفاق موارد با فراخوانی روش های یکدیگر تضمین می شود.

    کپسولاسیون با وسایل زیر انجام می شود:

    کنترل دسترسی از آنجایی که متدهای کلاس می توانند صرفاً داخلی باشند، که منطق عملکرد شی را ارائه می دهند، یا خارجی، که به کمک آن اشیاء با هم تعامل دارند، لازم است از محرمانه بودن اولی اطمینان حاصل شود در حالی که دومی از بیرون قابل دسترسی باشد. برای انجام این کار، ساختارهای نحوی خاصی به زبان ها وارد می شوند که به صراحت محدوده هر یک از اعضای کلاس را مشخص می کنند. به طور سنتی، اینها اصلاح‌کننده‌های عمومی، محافظت‌شده و خصوصی هستند که به ترتیب به اعضای عمومی کلاس، اعضای کلاس قابل دسترسی در کلاس و از کلاس‌های نسل، و اعضای پنهانی که فقط در کلاس قابل دسترسی هستند اشاره می‌کنند. نامگذاری خاص اصلاح کننده ها و معنای دقیق آنها در متفاوت است زبانهای مختلف. روش های دسترسی فیلدهای کلاس به طور کلی نباید از بیرون قابل دسترسی باشند، زیرا چنین دسترسی تغییرات دلخواه را در وضعیت داخلی اشیا امکان پذیر می کند. بنابراین، فیلدها معمولاً مخفی اعلام می شوند (یا زبان عموماً اجازه دسترسی به فیلدهای کلاس را از خارج نمی دهد) و از روش های خاصی به نام روش های دسترسی برای دسترسی به داده های موجود در فیلدها استفاده می شود. چنین روش هایی یا مقدار یک فیلد خاص را برمی گرداند و یا مقدار جدیدی را در این فیلد می نویسد. هنگام نوشتن، دسترسی‌دهنده می‌تواند اعتبار مقدار نوشته شده را بررسی کند و در صورت لزوم، دستکاری‌های دیگری را روی داده‌های شی انجام دهد تا درست (از لحاظ داخلی سازگار) باقی بماند. به روش‌های دسترسی دسترسی‌ها (از انگلیسی دسترسی - دسترسی) و به صورت جداگانه - گیرنده (انگلیسی دریافت - خواندن) و تنظیم‌کننده (مجموعه انگلیسی - نوشتن) نیز گفته می‌شود. ویژگی های یک شی Pseudofield قابل خواندن و/یا نوشتن. ویژگی ها شبیه فیلدها هستند و به همان شیوه فیلدهای موجود استفاده می شوند (به استثنای برخی موارد)، اما در واقع وقتی به آنها دسترسی پیدا می شود، متدهای Accessor را فراخوانی می کنند. بنابراین، ویژگی‌ها را می‌توان به‌عنوان فیلدهای داده «هوشمند» در نظر گرفت که دسترسی به داده‌های داخلی یک شی را با برخی اقدامات اضافی همراهی می‌کنند (به عنوان مثال، زمانی که تغییر در مختصات یک شی با ترسیم مجدد آن در یک مکان جدید همراه است). خواص، در واقع چیزی بیش از این نیست قند نحوی، زیرا آنها هیچ ویژگی جدیدی اضافه نمی کنند، بلکه فقط تماس برای دسترسی به روش ها را پنهان می کنند. پیاده سازی زبان خاص خصوصیات ممکن است متفاوت باشد. به عنوان مثال، یک اعلان ویژگی مستقیماً حاوی کد دسترسی است که فقط هنگام کار با ویژگی ها فراخوانی می شود، یعنی نیازی به روش های دسترسی جداگانه ای ندارد که بتوان مستقیماً آن را فراخوانی کرد. در دلفی، یک اعلان ویژگی فقط شامل نام متدهای دسترسی است که باید هنگام دسترسی به فیلد فراخوانی شوند. روش های دسترسی خود روش های معمولی با برخی از الزامات امضای اضافی هستند.

    چند شکلی با وارد کردن قواعدی به زبان پیاده‌سازی می‌شود که براساس آن می‌توان به یک متغیر از نوع "کلاس" یک شی از هر کلاس نزول کلاس خود اختصاص داد.

    طراحی برنامه به طور کلی

    OOP بر توسعه سیستم های نرم افزاری بزرگی که توسط تیمی از برنامه نویسان (احتمالاً بسیار بزرگ) توسعه یافته است، متمرکز است. طراحی سیستم به عنوان یک کل، ایجاد اجزای منفرد و ادغام آنها در محصول نهایی اغلب توسط افراد مختلف انجام می شود و هیچ متخصصی وجود ندارد که همه چیز را در مورد پروژه بداند.

    طراحی شی گرا بر توصیف ساختار سیستم طراحی شده (اولویت در رابطه با توصیف رفتار آن، در مقابل برنامه نویسی عملکردی) متمرکز است، یعنی در واقع در پاسخ به دو سوال اصلی:

    • سیستم از چه بخش هایی تشکیل شده است؟;
    • مسئولیت هر یک از قطعات آن چیست؟.

    تخصیص قطعات به گونه ای انجام می شود که هر یک دارای حداقل حجم و مجموعه ای دقیق از عملکردها (مسئولیت ها) باشد و در عین حال تا حد امکان با سایر قسمت ها تعامل داشته باشد.

    توضیح بیشتر منجر به شناسایی قطعات کوچکتر از توضیحات می شود. همانطور که شرح و تعریف مسئولیت دقیق تر می شود، داده هایی که باید ذخیره شوند و حضور عوامل مشابه در رفتار آشکار می شوند که در قالب کلاس هایی با اجداد مشترک کاندیدای پیاده سازی می شوند. پس از شناسایی مولفه ها و تعریف واسط های بین آنها، پیاده سازی هر یک از اجزاء تقریباً مستقل از سایرین (البته با رعایت انضباط فنی مناسب) قابل انجام است.

    ساخت صحیح سلسله مراتب طبقاتی از اهمیت بالایی برخوردار است. یکی از مشکلات شناخته شده سیستم های بزرگ ساخته شده با استفاده از فناوری OOP به اصطلاح می باشد مشکل شکنندگی کلاس پایه. این در این واقعیت نهفته است که در مراحل بعدی توسعه، زمانی که سلسله مراتب کلاس ساخته می شود و مقدار زیادی کد بر اساس آن توسعه یافته است، ایجاد هر گونه تغییر در کد آن دشوار یا حتی غیرممکن است. کلاس های پایه سلسله مراتب (که همه یا بسیاری از کلاس های کار در سیستم از آن مشتق شده اند). حتی اگر تغییراتی که ایجاد می‌کنید روی رابط کلاس پایه تأثیری نداشته باشد، تغییر رفتار آن می‌تواند بر کلاس‌های نسل به روش‌های غیرقابل پیش‌بینی تأثیر بگذارد. چه زمانی سیستم بزرگتوسعه‌دهنده یک کلاس پایه به سادگی قادر به پیش‌بینی عواقب تغییرات نیست؛ او حتی نمی‌داند که کلاس پایه دقیقا چگونه استفاده می‌شود و عملکرد صحیح کلاس‌های نسل به چه ویژگی‌هایی از رفتار آن بستگی دارد.

    متدولوژی های مختلف OOP

    برنامه نویسی کامپوننت مرحله بعدی در توسعه OOP است. برنامه نویسی نمونه اولیه و کلاس محور رویکردهای متفاوتی برای ایجاد برنامه ای هستند که می توانند با هم ترکیب شوند و مزایا و معایب خاص خود را دارند.

    برنامه نویسی کامپوننت

    برنامه نویسی کامپوننت گرا نوعی "روبنا" بر OOP است، مجموعه ای از قوانین و محدودیت ها با هدف ایجاد سیستم های نرم افزاری در حال توسعه بزرگ با زمان بزرگزندگی یک سیستم نرم افزاری در این متدولوژی مجموعه ای از اجزا با رابط های کاملاً تعریف شده است. تغییر در سیستم موجودبا ایجاد اجزای جدید علاوه بر یا به عنوان جایگزینی برای اجزای قبلی معرفی می شوند. هنگام ایجاد مؤلفه های جدید بر اساس موارد ایجاد شده قبلی، استفاده از وراثت پیاده سازی ممنوع است - جزء جدیدفقط می تواند رابط های پایه یک را به ارث ببرد. به این ترتیب، برنامه نویسی کامپوننت از مشکل شکنندگی کلاس پایه جلوگیری می کند.

    برنامه نویسی نمونه اولیه

    برنامه نویسی نمونه اولیه، در حالی که برخی از ویژگی های OOP را حفظ کرد، مفاهیم اولیه کلاس و ارث را کنار گذاشت.

    • نمونه اولیه یک شی نمونه است که در تصویر و تشبیه آن اشیاء دیگری ایجاد می شود. اشیاء کپی می توانند یک اتصال به شی والد را حفظ کنند و به طور خودکار تغییرات را در نمونه اولیه به ارث ببرند. این ویژگی در یک زبان خاص تعریف شده است.
    • به جای مکانیزمی برای توصیف کلاس‌ها و نمونه‌های تخم‌ریزی، زبان مکانیسمی برای ایجاد یک شی (با مشخص کردن مجموعه‌ای از زمینه‌ها و روش‌هایی که شی باید داشته باشد) و مکانیزمی برای شبیه‌سازی اشیا ارائه می‌کند.
    • هر شی جدید ایجاد شده یک "مثال بدون کلاس" است. هر شی می تواند تبدیل شود نمونه اولیه- برای ایجاد یک شی جدید با استفاده از یک عملیات استفاده شود شبیه سازی. پس از شبیه سازی، شی جدید را می توان تغییر داد، به ویژه، زمینه ها و روش های جدید را می توان اضافه کرد.
    • یک شی کلون شده یا به یک کپی کامل از نمونه اولیه تبدیل می شود، تمام مقادیر فیلدهای خود را ذخیره می کند و روش های آن را کپی می کند، یا ارجاع به نمونه اولیه را بدون در نظر گرفتن فیلدها و روش های شبیه سازی شده تا زمانی که اصلاح شوند حفظ می کند. در مورد دوم، محیط زمان اجرا مکانیزمی را فراهم می کند هیئت نمایندگی- اگر هنگام دسترسی به یک شی، خود شامل روش یا فیلد داده مورد نیاز نباشد، فراخوانی به نمونه اولیه ارسال می شود، در صورت لزوم، در امتداد زنجیره بیشتر از آن.

    برنامه نویسی کلاس گرا

    برنامه نویسی کلاس محور برنامه نویسی متمرکز بر داده است که در آن داده ها و رفتار به طور جدایی ناپذیری به هم مرتبط هستند. داده ها و رفتار با هم یک کلاس را تشکیل می دهند. بر این اساس، در زبان ها بر اساس مفهوم "کلاس"، همه اشیا به دو نوع اصلی تقسیم می شوند - کلاس ها و نمونه ها. یک کلاس ساختار و عملکرد (رفتار) را تعریف می کند که برای همه نمونه های آن کلاس یکسان است. یک نمونه یک حامل داده است - یعنی حالتی دارد که مطابق با رفتار مشخص شده توسط کلاس تغییر می کند. در زبان های کلاس محور، یک نمونه جدید از طریق فراخوانی سازنده کلاس (احتمالا با مجموعه ای از پارامترها) ایجاد می شود. نمونه به دست آمده دارای ساختار و رفتار است که توسط کلاس خود کدگذاری شده است.

    عملکرد برنامه شی

    Gradi Booch به دلایل زیر اشاره می کند که منجر به کاهش عملکرد برنامه به دلیل استفاده از ابزارهای شی گرا می شود:

    پیوند پویا روش ها اطمینان از رفتار چند شکلی اشیا منجر به نیاز به پیوند روش های فراخوانی شده توسط برنامه (یعنی تعیین اینکه کدام روش خاص فراخوانی می شود) نه در مرحله کامپایل، بلکه در حین اجرای برنامه می شود که به زمان بیشتری نیاز دارد. با این حال، اتصال پویا در واقع برای بیش از 20٪ تماس ها مورد نیاز نیست، اما برخی از زبان های OOP همیشه از آن استفاده می کنند. عمق قابل توجه توسعه OOP انتزاعی اغلب منجر به ایجاد برنامه های کاربردی "چند لایه" می شود، جایی که عملکرد یک شی از یک عمل مورد نیاز به تعداد زیادی فراخوانی به اشیاء سطح پایین کاهش می یابد. در چنین برنامه‌ای، فراخوانی‌های متد و بازگشت متدهای زیادی وجود دارد که طبیعتاً بر عملکرد تأثیر می‌گذارد. وراثت کد را «تار» می کند کد مربوط به کلاس های «نهایی» سلسله مراتب وراثت، که معمولاً مستقیماً توسط برنامه استفاده می شود، نه تنها در خود این کلاس ها، بلکه در کلاس های اجداد آنها نیز قرار دارد. روش های متعلق به یک کلاس در واقع در کلاس های مختلف توصیف می شوند. این منجر به دو چیز ناخوشایند می شود:

    • سرعت ترجمه کاهش می یابد، زیرا پیوند دهنده باید توضیحات همه کلاس های سلسله مراتب را بارگذاری کند.
    • عملکرد برنامه در یک سیستم حافظه صفحه‌دار کاهش می‌یابد - زیرا روش‌های یک کلاس به صورت فیزیکی در آن قرار دارند جاهای مختلفکد، دور از یکدیگر، هنگام اجرای قطعات برنامه که به طور فعال به روش‌های ارثی دسترسی دارند، سیستم مجبور به انجام سوئیچ‌های مکرر صفحه می‌شود.
    کپسوله سازی سرعت دسترسی به داده ها را کاهش می دهد ممنوعیت دسترسی مستقیم به فیلدهای کلاس از خارج منجر به نیاز به ایجاد و استفاده از روش های دسترسی می شود. هزینه های اضافی مربوط به نوشتن، کامپایل، و اجرای روش های دسترسی وجود دارد. ایجاد و تخریب دینامیک اشیاء، اشیاء ایجاد شده پویا، به عنوان یک قاعده، بر روی پشته تخصیص داده می شوند، که کارایی کمتری نسبت به قرار دادن آنها در پشته و علاوه بر این، تخصیص استاتیک حافظه برای آنها در مرحله کامپایل دارد.

    با وجود این کاستی ها، بوچ استدلال می کند که مزایای استفاده از OOP بیشتر است. علاوه بر این، افزایش بهره وری به دلیل سازماندهی بهتر کد OOP، به گفته وی، در برخی موارد هزینه های سربار اضافی سازماندهی عملکرد برنامه را جبران می کند. همچنین می توانید توجه داشته باشید که به دلیل بهینه سازی کد با کیفیت بالا توسط کامپایلر، بسیاری از اثرات کاهش عملکرد را می توان هموار کرد یا حتی به طور کامل حذف کرد. به عنوان مثال، اگر کامپایلر به جای فراخوانی متد دسترسی، از جایگزینی درون خطی استفاده کند، کاهش سرعت دسترسی به فیلدهای کلاس به دلیل استفاده از روش های دسترسی حذف می شود (کامپایلرهای مدرن این کار را کاملاً با اطمینان انجام می دهند).

    انتقاد از OOP

    علیرغم برخی انتقادات از OOP، این پارادایم در حال حاضر در اکثریت قریب به اتفاق پروژه های صنعتی استفاده می شود. با این حال، نمی توان فرض کرد که OOP بهترین تکنیک برنامه نویسی در همه موارد است.

    انتقادات به ساف:

    • نشان داده شد که تفاوت معنی داری در بهره وری توسعه وجود ندارد نرم افزاربین OOP و رویکرد رویه ای
    • کریستوفر دیت به عدم امکان مقایسه OOP و سایر فن آوری ها عمدتاً به دلیل عدم وجود یک تعریف دقیق و پذیرفته شده از OOP اشاره می کند.
    • الکساندر استپانوف در یکی از مصاحبه های خود اشاره کرد که OOP "از نظر روش شناختی نادرست" است و "... OOP عملا همان فریب هوش مصنوعی است...".
    • فردریک بروکس خاطرنشان می کند که دشوارترین بخش ایجاد نرم افزار «... مشخصات، طراحی و آزمایش سازه های مفهومی است، نه کار بیان آن سازه های مفهومی...». OOP (همراه با فناوری هایی مانند هوش مصنوعی، تأیید برنامه، برنامه نویسی خودکار، برنامه نویسی گرافیکی، سیستم های خبره، و غیره) به نظر او "گلوله نقره ای" نیست که بتواند پیچیدگی توسعه سیستم های نرم افزاری را با یک دستور کاهش دهد. اندازه. به گفته بروکس، «...OOP فقط پیچیدگی معرفی شده در بیان طراحی را کاهش می دهد. طراحی ذاتاً پیچیده باقی می ماند...”
    • Edsger-Dijkstra خاطرنشان کرد: «... چیزی که جامعه در بیشتر موارد درخواست می کند، اکسیری برای همه بیماری ها است. طبیعتاً "اکسیر" نام های بسیار چشمگیری دارد، در غیر این صورت فروش چیزی بسیار دشوار خواهد بود: "تحلیل و طراحی سازه"، "مهندسی نرم افزار"، "مدل های بلوغ"، "سیستم های اطلاعات مدیریت"، "محیط های یکپارچه" پشتیبانی پروژه "، "شی گرایی"، "مهندسی مجدد فرآیندهای کسب و کار...".
    • Niklaus-Wirth معتقد است که OOP چیزی بیش از یک روبنای پیش پا افتاده بر برنامه نویسی ساخت یافته نیست و اغراق در اهمیت آن، که از جمله در گنجاندن ابزارهای شی گرا در زبان های برنامه نویسی بیان می شود، به کیفیت نرم افزار آسیب می رساند. در حال توسعه.
    • پاتریک کیللیا در کتاب خود با عنوان "تنظیم سرور وب" نوشت: "...OOP راه های زیادی برای کاهش سرعت برنامه ها در اختیار شما قرار می دهد...".
    • یک مقاله مروری معروف در مورد مشکلات برنامه نویسی مدرن OOP برخی از آنها را فهرست می کند مشکلات معمولیاوپ [ ] .
    • در برنامه نویسی فولکلور، نقد رویکرد شی گرا در مقایسه با رویکرد عملکردی با استفاده از استعاره پادشاهی های اسم"از مقاله ای از استیو یگی.

    اگر بخواهیم نقدهای OOP را طبقه بندی کنیم، می توانیم چندین جنبه از انتقاد از این رویکرد برنامه نویسی را برجسته کنیم.

    انتقاد از تبلیغات OOP ایده برنامه نویسی شی به عنوان یک رویکرد قدرتمند که به طور جادویی پیچیدگی برنامه نویسی را از بین می برد، مورد انتقاد قرار می گیرد، چه به صراحت بیان شده است و چه ضمنی در آثار برخی از تبلیغ کنندگان OOP، و همچنین در مطالب تبلیغاتی برای "شی گرا" ابزارهای توسعه همانطور که بسیاری اشاره کردند، از جمله بروکس و دایکسترا که در بالا ذکر شد، "هیچ گلوله نقره ای وجود ندارد" - مهم نیست که توسعه دهنده به چه پارادایم برنامه نویسی پایبند است و یک مجموعه غیر پیش پا افتاده ایجاد می کند. سیستم نرم افزاریهمیشه شامل سرمایه گذاری قابل توجهی از منابع فکری و زمان است. از مجرب ترین متخصصان در زمینه OOP، هیچ یک، به عنوان یک قاعده، اعتبار انتقاد از این نوع را انکار نمی کند. مخالفت با کارایی OOP توسعه منتقدان این ایده که توسعه برنامه های شی گرا به منابع کمتر یا نتایج به نرم افزار با کیفیت بالاتر نیاز دارد. هزینه های توسعه مقایسه می شود روش های مختلف، که بر اساس آن نتیجه گیری می شود که OOP هیچ مزیتی در این راستا ندارد. با توجه به دشواری شدید مقایسه عینی تحولات مختلف، چنین مقایسه‌هایی حداقل بحث‌برانگیز هستند. از سوی دیگر، معلوم می شود که اظهارات در مورد اثربخشی OOP به همان اندازه بحث برانگیز است. عملکرد برنامه های شی گرا اشاره شده است که تعدادی از "ویژگی های ذاتی" فناوری OOP باعث می شود برنامه های ساخته شده بر اساس آن از نظر فنی در مقایسه با برنامه های مشابه غیر شیء کارآمد کمتری داشته باشند. بدون انکار اینکه واقعاً هزینه های سربار اضافی برای سازماندهی عملیات برنامه های OOP وجود دارد (به بخش "عملکرد" ​​در بالا مراجعه کنید)، باید توجه داشت که اهمیت جریمه عملکرد اغلب توسط منتقدان اغراق آمیز می شود. که در شرایط مدرنهنگامی که قابلیت‌های فنی رایانه‌ها بسیار بزرگ است و دائماً در حال رشد است، برای اکثر برنامه‌های کاربردی، کارایی فنی کمتر از عملکرد، سرعت توسعه و قابلیت نگهداری است. فقط برای یک کلاس خاص و بسیار محدود از برنامه ها (نرم افزار سیستم تعبیه شده، درایورهای دستگاه، بخش سطح پایین نرم افزار سیستم، نرم افزار علمی) عملکرد یک عامل مهم باقی می ماند. انتقاد از راه حل های تکنولوژیکی فردی در زبان ها و کتابخانه های OOP. موارد خاصاجرای خاصی از مکانیسم های آن. یکی از موضوعات مورد علاقه انتقاد زبان C++ است که یکی از رایج ترین زبان های صنعتی OOP است.

    زبان های شی گرا

    زیاد زبان های مدرنبه طور خاص برای تسهیل برنامه نویسی شی گرا طراحی شده است. با این حال، باید توجه داشت که می‌توانید تکنیک‌های OOP را روی یک زبان غیر شی گرا اعمال کنید و بالعکس؛ استفاده از زبان شی گرا به این معنا نیست که کد به طور خودکار شی گرا می شود.

    به طور معمول، یک زبان شی گرا (OOL) شامل مجموعه ای از عناصر زیر است:

    • اعلان کلاسها با فیلدها (داده - اعضای کلاس) و متدها (توابع - اعضای کلاس).
    • مکانیسم گسترش کلاس (ارث بری) تولید یک کلاس جدید از کلاس موجود است روشن شدن خودکارتمام ویژگی های اجرای کلاس جد به عنوان بخشی از کلاس نسل. اکثر OOO ها فقط از ارث واحد پشتیبانی می کنند.
    • متغیرهای چند شکلی و پارامترهای توابع (روش ها) که به شما امکان می دهد نمونه هایی از کلاس های مختلف را به یک متغیر اختصاص دهید.
    • رفتار چند شکلی نمونه های کلاس از طریق استفاده از روش های مجازی. در برخی OY ها، تمام متدهای کلاس مجازی هستند.

    برخی از زبان ها به حداقل مجموعه مشخص شده اضافه می کنند وجوه اضافی. از جمله:

    • سازنده ها، تخریب کننده ها، نهایی کننده ها.
    • خواص (لوازم جانبی)؛
    • نمایه سازها
    • ابزارهایی برای کنترل نمایان بودن اجزای کلاس (رابط یا اصلاح کننده های دسترسی، مانند عمومی، خصوصی، محافظت شده، ویژگی و غیره).

    برخی از زبان ها به طور کامل با اصول OOP مطابقت دارند - در آنها همه عناصر اصلی اشیایی هستند که دارای حالت و روش های مرتبط هستند. نمونه هایی از این زبان ها Smalltalk، Eiffel هستند. زبان‌های ترکیبی وجود دارند که زیرسیستم شی را به طور کامل با زیرسیستم‌های پارادایم‌های دیگر به عنوان «دو یا چند زبان در یک» ترکیب می‌کنند و به آن‌ها اجازه می‌دهند در یک برنامه ترکیب شوند. مدل های شیبا دیگران، و محو کردن مرز بین پارادایم های شی گرا و سایر پارادایم ها به دلیل قابلیت های غیر استاندارد ایجاد تعادل بین OOP و پارادایم های دیگر (مانند توزیع چندگانه، کلاس های پارامتریک، توانایی دستکاری روش های کلاس به عنوان اشیاء مستقل و غیره). نمونه هایی از این زبان ها:

    1 سال پیش | 13.4K

    هر کاندیدایی که می خواهد در یک شرکت بزرگ موقعیت برنامه نویسی بگیرد باید به این سوال پاسخ دهد که این نوع برنامه نویسی چیست. اگر برنامه نویس در پاسخگویی مشکل داشته باشد، در بیشتر موارد مصاحبه کننده مودبانه به شما اطلاع می دهد که مصاحبه تمام شده است. برای برنامه نویسان دشوار است که بدون آشنایی با این بخش به یک شغل عادی دست یابند.

    برای دادن پاسخ کافی به این سوال، شما باید نه تنها با ویژگی های اساسی OOP آشنا شوید، بلکه برخی از مفاهیم را نیز درک کنید - به عنوان مثال، چند شکلی، و همچنین کپسولاسیون و وراثت. از ماژول می توانید با مبانی نظری OOP آشنا شوید و دانش را در عمل در ماژول MVC - کل ماژول - اعمال کنید.

    مقدمه ای بر OOP

    OOP یک الگوی برنامه نویسی بسیار محبوب است که جایگزین رویکرد رویه ای منسوخ در برنامه نویسی شده است. برای درک اینکه چگونه برنامه نویسی رویه ای با OOP تفاوت دارد، ارزش دارد به ویژگی های برنامه نویسی رویه ای نگاهی دقیق بیندازید.

    بنابراین، برنامه ای که با استفاده از رویکرد رویه ای برای برنامه نویسی نوشته شده است، یک برنامه یکپارچه است که شامل تعداد معینی از دستورالعمل های مورد نیاز برنامه نویس و همچنین زیر روال ها است.

    برای درک فوری تفاوت بین این روش های برنامه نویسی، باید کد را در چندین نسخه در نظر بگیرید:

    برنامه ریزی رویه ای:

    $value = "سلام!"; echo $value; !}

    OOP:

    class Human ( $words خصوصی؛ تابع عمومی setWords($words) ($this->words = $words; ) تابع عمومی getWords() ( return $this->words; ) تابع عمومی sayIt() ( return $this-> getWords(); ) ) $human = new Human(); $human->setWords("سلام!"); echo $human->sayIt();

    ارزش دارد فوراً تفاوت قابل مشاهده را برجسته کنید - در گزینه اول همه چیز بسیار ساده تر است ، کد کمتری وجود دارد. بسیاری از مردم کد OOP را بسیار پیچیده در نظر می گیرند و اولین گزینه را انتخاب می کنند، اما این فقط یک تصور اولیه گمراه کننده است.

    که در در این موردهنگام انتخاب یک رویکرد، باید ویژگی های وظیفه دریافت شده را در نظر بگیرید. رویکرد رویه ای برای ایجاد کد ساده برای استفاده کوتاه مدت ایده آل است - اگر کد حداکثر از 5 خط تشکیل شده باشد، این رویکرد را انتخاب کنید.

    برای یک کار تکرار شونده که پیچیده تر است، بهتر است OOP را انتخاب کنید.

    CLASS چیست

    همه چیز در اینجا بسیار ساده است - اینها روش ها و همچنین زمینه های برنامه هستند. به عنوان مثال، Human را در نظر بگیرید:

    Class Human ( $words خصوصی؛ تابع عمومی setWords($words) ($this->words = $words; ) تابع عمومی getWords() ( return $this->words; ) تابع عمومی sayIt() ( return $this-> getWords();))

    همه چیز در اینجا بسیار ساده است، Human نام کلاس است، $words یک متغیر (فیلد)، و setWords، getWords()، sayIt() متدهایی هستند.

    چند اصل اساسی OOP

    3 اصل اساسی وجود دارد که اساس OOP را تشکیل می دهد. هر یک از این اصول با جزئیات بیشتری مورد بحث قرار خواهند گرفت تا شما فرصتی برای درک تمام ویژگی های OOP داشته باشید.

    کپسوله سازی

    بیایید چند مثال نشان دهیم که به شما در درک هر یک از اصول ارائه شده کمک می کند. کپسولاسیون نوعی محافظت از اطلاعات در برابر کاربران خارجی است.

    برای اینکه فوراً روشن شود که این چیست، بیایید یک مثال واقعی ارائه دهیم.

    شما می خواهید با استفاده از تلفن خود تماس خاصی برقرار کنید - این نیازی به دانش اضافی از شما در بخش ارتباطات سلولی، قرار دادن برج ها و غیره ندارد. شما فقط به دانش ساده تری نیاز دارید - تعداد مشترک انتخاب شده و وسایلی که به شما امکان می دهد یک تماس برنامه ریزی شده برقرار کنید.

    کپسوله سازی به کاربران خارجی (برنامه نویسان) امکان دسترسی به روش هایی را می دهد که برای کار با برنامه شما نیاز دارند، در حالی که تمام روش های داخلی مهم غیرقابل دسترس باقی می مانند، آنها به سادگی توسط کاربران خارجی مورد نیاز نیستند.

    بیایید موارد زیر را به عنوان نمونه ای از کپسولاسیون در نظر بگیریم:

    Class Human ( $words خصوصی؛ خصوصی $sex؛ تابع عمومی setSex($sex) ( if($sex == "male") ($this->sex = "male"; ) other if($sex == "female ") ($this->sex = $sex; ) else (echo "خطا. تنظیم فقط جنسیت مذکر یا زن"؛ ) ) تابع عمومی setWords($words) ($this->words = $words; ) تابع عمومی getWords () ( return $this->words; ) تابع عمومی sayIt() ( return $this->getWords(); ) ) $human = new Human(); $human->setSex("male"); $human->setWords("سلام!"); echo $human->sayIt();

    انسان در اینجا نشان داده شده است، در این کلاس ما "جنس" (جنسیت) را اضافه کردیم که خصوصی کردیم - این به کاربران خارجی اجازه دسترسی به آن را نمی دهد.

    تلاش برای دسترسی به این فیلد خارج از خود کلاس به این صورت است:

    $human->sex = "11"; خطای مرگبار: دسترسی به اموال خصوصی انسان::$sex امکان پذیر نیست

    کپسولاسیون یک ویژگی بسیار مفید OOP است و اغلب استفاده می شود. کپسولاسیون زمانی بسیار مفید است که یک تیم کامل از متخصصان در ایجاد یک پروژه خاص مشارکت داشته باشند. هر برنامه نویس با یک کلاس و روش های خاص کار می کند، بدون اینکه در کار سایر متخصصان دخالت کند.

    وراثت

    یکی دیگر از ویژگی های بسیار مهم OOP توانایی به ارث بردن عملکرد یک کلاس خاص به کلاس دیگر است.

    و دوباره، یک مثال واقعی که به شما در درک ویژگی های وراثت کمک می کند.

    هر فرد در بدو تولد دارای مجموعه خاصی از عملکردها است، این به اصطلاح مجموعه اساسی است - تنفس، هضم غذا، جیغ زدن.

    شما ترکیبی از تعداد زیادی زنجیره ژنی هستید - از اولین اجداد تا والدین خونی خود. اگر OOP را در نظر بگیریم، در این مورد خاصیت ارث با زندگی ساده تفاوتی ندارد.

    چگونه کار می کند؟ کلاس های والد با عملکرد پایه وجود دارد - هنگام ایجاد یک کلاس جدید، نیازی به ایجاد مهارت های اساسی جدید نخواهید داشت، در ابتدا "پایه" کلاس والد را به ارث می برد. این کار برنامه نویسان را بسیار ساده می کند. یک کلمه "extends" وجود دارد که به معنای ارث است، اکنون یک مثال خاص را به شما نشان می دهیم:

    /* کلاس والد Human */ کلاس Human ($name خصوصی؛ /* سازنده (که در آن فیلد $name را هنگام ایجاد نمونه ای از کلاس تنظیم می کنیم) */ تابع عمومی __construct($name) ($this->name = $name; ) /* روش say() فرض کنید که Human می تواند در ابتدا صحبت کند */ عملکرد عمومی say() ( echo "نام من ".$this->name است." و "; ) ) /* Class Man. با کلمه کلیدی extends، ما والد Human */ class Man extends Human را به ارث می بریم ( عملکرد عمومی beard() ( echo "I'm growing a beard"; ) ) /* Class Woman. با کلمه کلیدی extends، والد Human */ کلاس Women Extends Human را به ارث می‌بریم ( تابع عمومی bearChildren() ( echo "من بچه‌ها را به دنیا می‌آورم"؛ ) ) /* یک نمونه از کلاس Man ایجاد کنید و متدها را فراخوانی کنید. */ $man = مرد جدید ("Sergey"); $man->say(); $man->beard(); /* یک نمونه از کلاس Women و متدهای فراخوانی ایجاد کنید. */ $women = زنان جدید ("ماریا"); $women->say(); $women->bearChildren();

    در نتیجه چه خواهیم دید:

    اسم من سرگئی است و ریش دارم اسم من ماریا است و بچه هایی به دنیا می آوردم.

    اگر کلاس های ایجاد شده را در نظر بگیریم - هر دو دارای مجموعه ای اساسی از مهارت ها هستند ، اما تفاوت هایی وجود دارد - "مرد" ریش می گذارد ، "زن" فرزندی به دنیا می آورد.

    متدی به نام __construct سازنده کلاس است.

    پلی مورفیسم

    روش برنامه یکسان ممکن است رفتار متفاوتی را نشان دهد. درک این موضوع بلافاصله دشوار است، بنابراین به طور سنتی، ما از یک مثال ساده تر استفاده می کنیم تا بتوانید ویژگی های چندشکلی را درک کنید:

    تصور کنید که به یک فروشگاه مواد غذایی می آیید - صندوقدار می تواند هر محصولی را به شما بفروشد، پرداخت را با کارت یا پول نقد بپذیرد.

    خوب چطور؟ آیا اکنون درک رفتار متفاوت یک روش در OOP آسانتر است؟

    مثالی از چندشکلی:

    /* این رابط Say است */ اینترفیس Say ( تابع عمومی say(); ) /* این کلاس انتزاعی Human است که رابط Say را پیاده سازی می کند */ کلاس انتزاعی Human implements Say( خصوصی $name; تابع عمومی __construct($name) ($this-> name = $name; ) تابع عمومی getName() ( return $this->name; ) ) /* کلاس Man از کلاس Human ارث می برد و باید متد say() را پیاده سازی کند */ class Man extends Human ( تابع عمومی __construct($name) (parent::__construct($name); ) تابع عمومی beard() ( echo "من ریش می گذارم"؛ ) تابع عمومی say() ( echo "I'm صدای مردانه، نام من ".$this->getName()." است. و "; ) ) /* کلاس Women کلاس Human را به ارث می برد و باید متد say() */ class Women extensions Human ( تابع عمومی __construct($name) (parent::__construct($name); ) تابع عمومی bearChildren را اجرا کند. () ( echo "من بچه ها به دنیا می آورم"؛ ) عملکرد عمومی say() ( echo "I have صدای زن، نام من ".$this->getName()." است. و "; ) ) $man = مرد جدید ("سرگئی")؛ $man->say(); $man->ریش()؛ $women = new Women("Maria"); $women->say() ; $women->bearChildren(); ?>

    نتیجه:

    من صدایی مردانه دارم، اسمم سرگئی است و ریش بلندی دارم، صدای زنانه دارم، اسم من ماریا است و بچه هایی به دنیا می‌آورم.

    کلاس های ما اصلاح شده اند، مفاهیم جدیدی ظاهر شده اند - رابط، و همچنین برنامه نویسی انتزاعی. کمی بعد به این جنبه خواهیم پرداخت.

    به اجرای متفاوت متد say() در کلاس‌های Man و Women توجه کنید - این چند شکلی نامیده می‌شود.

    ویژگی های رابط

    رابط یک کلاس قالب است، هیچ پیاده سازی وجود ندارد. رابط به شما اجازه می دهد تا روش های خاصی را که نیاز به پیاده سازی بعدی دارند را مشخص کنید.

    بیایید به مثال قبلی نگاه کنیم:

    /* این رابط Say است */ رابط Say ( تابع عمومی say(); )

    این رابط باید در کلاس انتزاعی Human پیاده سازی شود. انجام این کار بسیار ساده است - نام کلاس را پیدا کنید و بلافاصله پس از آن "Implements" را اضافه کنید.

    کلاس انتزاعی

    یک کلاس انتزاعی در OOP یک کلاس الگو است که نمونه ای از کلاس را نمی توان از آن ایجاد کرد.

    نمونه ای از کارهایی که نمی توانیم انجام دهیم:

    $human = انسان جدید ("نام");

    در هر صورت خطا دریافت خواهیم کرد.

    می توان کلاس Abstract را به ارث برد. مثال دیگری از کلاس Abstract:

    /* این یک کلاس انتزاعی Human است که رابط Say را پیاده سازی می کند */ کلاس انتزاعی Human پیاده سازی می کند Say( private $name; public function __construct($name) ($this->name = $name; ) تابع عمومی getName() ( return $this-> name; ))

    نتیجه گیری

    OOP یک روش مدرن فوق العاده راحت است که به شما امکان می دهد ساختارهای برنامه های نسبتاً پیچیده را به درستی سازماندهی کنید. سایر توسعه دهندگان قادر خواهند بود از پروژه ای پشتیبانی کنند که به لطف OOP در حال رشد است. این یک مزیت نسبتاً مهم OOP است.

    در یک راه بزرگ در ماژول ها با مبانی نظری OOP و پیاده سازی عملی در ماژول آشنا خواهید شد.

    ما مثال های نسبتاً ساده ای آورده ایم - این یک فرصت عالی برای هر مبتدی در بخش برنامه نویسی است! امیدواریم به شما در درک ویژگی‌های OOP کمک کرده باشیم، مهم‌ترین اصول را برای بهبود بیشتر مهارت‌های خود بیاموزیم. چندین مقاله آینده با هدف درک موارد مهم خواهد بود کلید واژه هاعمومی، خصوصی، محافظت شده، ایستا. تمام ویژگی ها را با استفاده از مثال های بسیار ساده ببینید.

    مفهوم برنامه نویسی شی گرا (OOP) بیش از چهل سال پیش به عنوان توسعه ایده های برنامه نویسی رویه ای ظاهر شد. ایدئولوژی برنامه‌نویسی رویه‌ای چیز خاصی نیست: همه برنامه‌ها با مجموعه‌ای از رویه‌ها و توابع نشان داده می‌شوند، در حالی که رویه‌ها و توابع خود دنباله‌ای از عبارات هستند که رایانه با اجرای آن‌ها مقادیر متغیرها را در حافظه تغییر می‌دهد. برنامه اصلی در برنامه نویسی رویه ای نیز یک رویه (عملکرد) است که بدنه آن ممکن است شامل فراخوانی به رویه ها و عملکردهای دیگر - زیر روال ها باشد. ماهیت برنامه نویسی رویه ای ساده است: داده ها جدا هستند، رفتار جدا هستند. من سعی کردم یک زبان برنامه نویسی رویه ای از چه چیزی تشکیل شده است (چه ساختارهایی را شامل می شود) در یک بخش جداگانه جمع آوری کنم. تقسیم کد به زیر روال ها، اولاً به شما امکان می دهد قطعات کد قابل استفاده مجدد را برجسته کنید و ثانیاً کد برنامه را ساختارمند می کند.

    ایدئولوژی برنامه نویسی شی گرا، همانطور که از نام آن پیداست، حول مفهوم شی بنا شده است. یک شیء داده ها و رفتار را با هم ترکیب می کند. یک شی هر موجودی است که برنامه با آن سروکار دارد، یعنی: اشیاء دامنه مدل‌سازی شده توسط برنامه. منابع سیستم عامل؛ پروتکل های شبکهو خیلی بیشتر. در اصل، یک شی همان ساختار (نوع مرکب) است، اما با رویه‌ها و عملکردهایی که عناصر این ساختار را مدیریت می‌کنند، تکمیل شده است. به عنوان مثال، برای کار با یک فایل در یک زبان برنامه نویسی رویه ای، یک متغیر به طور جداگانه برای ذخیره نام فایل و جداگانه برای ذخیره توصیفگر آن (شناسه منبع منحصر به فرد در سیستم عامل) و همچنین تعدادی از رویه ها ایجاد می شود. کار با فایل: فایل را باز کنید، داده ها را از فایل بخوانید و فایل را ببندید. تمام این رویه‌ها، علاوه بر پارامترها و متغیرهای معمول برای ذخیره نتیجه، برای اینکه بفهمیم در مورد کدام فایل صحبت می‌کنیم، باید همان توصیفگر را بپذیرند. در یک زبان شی گرا، برای همان هدف، یک شی فایل توصیف می شود، که همچنین یک نام و یک دسته را در خود ذخیره می کند و رویه هایی را برای باز کردن، خواندن و بسته شدن خود در اختیار کاربر قرار می دهد (فایل مرتبط با یک فایل خاص). هدف - شی). تفاوت این است که دسته از بقیه برنامه پنهان می شود، در کد روتین باز فایل ایجاد می شود و فقط به طور ضمنی توسط خود شی مورد استفاده قرار می گیرد. بنابراین، کاربر شی (کد برنامه برنامه خارجی به شی) نیازی به ارسال دسته در پارامترهای رویه هر بار ندارد. یک شی مجموعه ای از داده ها و روش ها برای کار با این داده ها است که ممکن است برخی از آنها از دنیای اطراف پنهان باشد که شامل جزئیات پیاده سازی می شود. اصطلاحات برنامه نویسی شی گرا در ادامه با جزئیات بیشتری مورد بحث قرار خواهند گرفت.

    در یک زبان برنامه نویسی شی گرا، تقریباً همه چیز یک شی است، به استثنای عملگرها: انواع ابتدایی اشیا هستند، توصیف خطا یک شی است، و در نهایت، برنامه اصلی نیز یک شی است. باقی مانده است که بفهمیم یک شی از نقطه نظر خود برنامه چیست، چگونه ایجاد و استفاده می شود. دومین مفهوم اساسی OOP کلاس است. کلاس یک نوع داده جدید در مقایسه با برنامه نویسی رویه ای است که نمونه های آن را اشیاء می نامند. یک کلاس، همانطور که قبلاً ذکر شد، شبیه به یک نوع داده یا ساختار ترکیبی است، اما با رویه‌ها و توابع (روش‌ها) برای کار با داده‌های آن تکمیل شده است. اکنون زمان تشریح شرایط اولیه برنامه نویسی شی گرا است.

    اصطلاحات برنامه نویسی شی گرا

    قبل از حرکت به شرح مزایایی که OOP در فرآیند طراحی، کدگذاری و تست محصولات نرم افزاری به توسعه دهندگان نرم افزار می دهد، لازم است با رایج ترین اصطلاحات در این زمینه آشنا شوید.

    • کلاس- یک نوع داده که ساختار و رفتار اشیاء را توصیف می کند.
    • یک شی- نمونه ای از یک کلاس
    • رشته– عنصر داده کلاس: متغیری از نوع ابتدایی، ساختار یا کلاس دیگری که بخشی از یک کلاس است.
    • وضعیت شی- مجموعه ای از مقادیر فیلد شی فعلی.
    • روش- رویه یا تابعی که در متن شیئی که روی آن فراخوانی شده است اجرا می شود. روش‌ها می‌توانند وضعیت شی فعلی یا وضعیت اشیاء ارسال شده به آنها را به عنوان پارامتر تغییر دهند.
    • ویژگی- نوع خاصی از روش‌هایی که برای اصلاح فیلدهای جداگانه یک شی طراحی شده‌اند. نام خواص معمولاً با نام فیلدهای مربوطه یکسان است. از نظر خارجی، کار با ویژگی ها دقیقاً شبیه کار با فیلدهای یک ساختار یا کلاس است، اما در واقع، قبل از برگرداندن یا تخصیص مقدار جدید به یک فیلد، می توان کد برنامه ای را اجرا کرد که انواع مختلفی از بررسی ها را انجام می دهد، به عنوان مثال، بررسی آیا مقدار جدید معتبر است.
    • عضو کلاس- فیلدها، متدها و خصوصیات کلاس.
    • اصلاح کننده دسترسیویژگی اضافیاعضای کلاس، تعیین اینکه آیا می توان به آنها توسط یک برنامه خارجی دسترسی داشت یا اینکه آیا آنها منحصراً در محدوده کلاس استفاده می شوند و از دنیای خارج پنهان هستند. اصلاح‌کننده‌های دسترسی، همه اعضای یک کلاس را به جزئیات پیاده‌سازی و یک رابط عمومی یا جزئی عمومی جدا می‌کنند.
    • سازنده- یک متد خاص که بلافاصله پس از ایجاد یک نمونه از یک کلاس اجرا می شود. سازنده فیلدهای شیء را مقداردهی اولیه می کند - شی را به حالت اولیه خود می رساند. سازنده ها می توانند با یا بدون پارامتر باشند. سازنده بدون پارامتر، سازنده پیش فرض نامیده می شود که فقط می تواند یک داشته باشد. نام متد سازنده اغلب با نام خود کلاس مطابقت دارد.
    • ویرانگر- یک روش خاص که توسط محیط اجرای برنامه در لحظه حذف یک شی از آن فراخوانی می شود حافظه دسترسی تصادفی. تخریبگر در مواردی استفاده می شود که کلاس شامل منابعی است که نیاز به انتشار صریح دارند (فایل ها، اتصالات پایگاه داده، اتصالات شبکه و غیره)
    • رابط- مجموعه ای از روش ها و ویژگی های یک شی که به صورت عمومی در دسترس هستند و برای حل طیف خاصی از مسائل طراحی شده اند، به عنوان مثال، یک رابط برای تولید یک نمایش گرافیکی از یک شی در صفحه یا یک رابط برای ذخیره وضعیت یک شی. در یک فایل یا پایگاه داده
    • عضو ایستا- هر عنصر از یک کلاس که می تواند بدون ایجاد یک شیء مربوطه استفاده شود. به عنوان مثال، اگر یک متد کلاس از یک فیلد منفرد استفاده نمی کند، اما منحصراً با پارامترهای ارسال شده به آن کار می کند، هیچ چیز مانع از استفاده آن در زمینه کل کلاس، بدون ایجاد نمونه های جداگانه از آن نمی شود. ثابت ها در متن یک کلاس معمولاً همیشه اعضای ثابت کلاس هستند.

    مزایای برنامه نویسی شی گرا

    حال بیایید در مورد ویژگی هایی صحبت کنیم که یک برنامه هنگام استفاده از رویکرد شی گرا برای طراحی و کدگذاری آن به دست می آورد. به نظر من اکثر این خواص از مزایای OOP هستند، اما نظرات دیگری در این مورد وجود دارد ...

    • کپسوله سازیبه معنای پنهان کردن جزئیات پیاده سازی یک کلاس با پاداش دادن به اعضای فردی با اصلاح کننده های دسترسی مناسب است. بنابراین، تمام عملکرد یک شی با هدف تعامل با سایر اشیاء برنامه در یک رابط باز گروه بندی می شود و جزئیات به دقت در داخل پنهان می شوند، که کد منطق تجاری اصلی سیستم اطلاعاتی را از چیزهای غیر ضروری نجات می دهد. کپسوله سازی قابلیت اطمینان عملیاتی را بهبود می بخشد کد برنامه، زیرا تضمین می کند که داده های خاصی را نمی توان خارج از کلاسی که حاوی آن است تغییر داد.
    • وراثت. سنگ بنای OOP. در برنامه نویسی شی گرا، می توان ساختار و رفتار یک کلاس را از کلاس دیگر به ارث برد. کلاسی که از آن به ارث می برند، پایه یا سوپرکلاس و کلاسی که در نتیجه وراثت به دست می آید، مشتق یا به سادگی یک نسل نامیده می شود. هر طبقه ای می تواند هم به عنوان یک سوپرکلاس و هم به عنوان یک نسل عمل کند. روابط وراثت طبقاتی یک سلسله مراتب کلاسی را تشکیل می دهد. وراثت چندگانه تعریف یک کلاس است که از چندین ابر کلاس به طور همزمان مشتق شده است. همه زبان های برنامه نویسی شی گرا از وراثت چندگانه پشتیبانی نمی کنند. وراثت یک راه موثر برای جداسازی قطعات کد قابل استفاده مجدد است، اما معایبی نیز دارد که بعداً مورد بحث قرار خواهد گرفت.
    • انتزاع - مفهوم - برداشت. توانایی ترکیب کلاس‌ها در گروه‌های جداگانه، برجسته کردن ویژگی‌های مشترک که برای همه آنها مهم است (میدان‌های مشترک و رفتار مشترک). در واقع، انتزاع نتیجه وراثت است: کلاس‌های پایه همیشه بر روی اشیاء دنیای واقعی نمایش داده نمی‌شوند، بلکه صرفاً به منظور برجسته کردن ویژگی‌های مشترک یک گروه کامل از اشیاء ایجاد می‌شوند. به عنوان مثال، یک شیء مبلمان یک مفهوم اساسی برای یک میز، صندلی و مبل است، همه آنها با این واقعیت متحد می شوند که آنها دارایی منقول هستند، بخشی از فضای داخلی محل هستند و می توان آنها را برای یک خانه یا محل کار ساخت. ، و همچنین به "اقتصادی" یا "حق بیمه" به کلاس مراجعه کنید. در OOP یک مفهوم جداگانه برای این وجود دارد: یک کلاس انتزاعی - کلاسی که ایجاد اشیاء آن ممنوع است، اما می تواند به عنوان یک کلاس پایه استفاده شود. وراثت و انتزاع، توصیف ساختارهای داده برنامه و روابط بین آنها را دقیقاً به همان شکلی که اشیاء مربوطه در مدل دامنه مورد بررسی به نظر می رسند، ممکن می سازد.

    نمونه ای از نمودار کلاس ساخته شده توسط انتزاع در طول تجزیه و تحلیل انواع وسایل نقلیه موجود در شکل زیر نشان داده شده است. در سطوح بالای سلسله مراتب وراثت، طبقات انتزاعی وجود دارد که وسایل نقلیه را با توجه به مهمترین ویژگی ها متحد می کند.

    نمودار کلاس یا سلسله مراتب وراثت "وسایل نقلیه". مربع های سفید نشان دهنده طبقات انتزاعی هستند.

    • پلی مورفیسم. یکی دیگر از اموالی که از پیامدهای ارث است. واقعیت این است که زبان های برنامه نویسی شی گرا به شما این امکان را می دهند که با مجموعه ای از اشیاء از یک سلسله مراتب کار کنید، به همان شکلی که انگار همه اشیاء کلاس پایه خود هستند. اگر به مثال در مورد مبلمان برگردیم، می‌توانیم فرض کنیم که در زمینه ایجاد یک سیستم اطلاعاتی برای یک فروشگاه مبلمان، منطقی است که یک روش رایج «نمایش ویژگی‌ها» را به کلاس پایه برای همه انواع مبلمان اضافه کنیم. هنگام چاپ مشخصات همه انواع کالاها، برنامه این روش را بدون تفکیک برای همه اشیاء فراخوانی می کند و هر شی خاص خودش تصمیم می گیرد چه اطلاعاتی را ارائه کند. نحوه پیاده سازی: ابتدا، کلاس پایه یک متد مشترک برای همه با رفتار مشترک تعریف می کند. در مورد مثال ما، این روشی است که پارامترهای مشترک برای همه انواع مبلمان را چاپ می کند. ثانیاً، در هر کلاس مشتق شده، در صورت لزوم، آنها متد پایه را مجدداً تعریف می کنند (افزودن روشی با همین نام)، که در آنجا رفتار اصلی را با خود گسترش می دهند، به عنوان مثال، ویژگی هایی را نشان می دهند که فقط مشخصه یک نوع خاص است. محصول مبلمان یک متد در یک کلاس پایه گاهی اوقات نیازی به هیچ کدی ندارد، اما فقط برای تعریف یک نام و مجموعه ای از پارامترها - امضای متد - مورد نیاز است. چنین متدهایی را متدهای انتزاعی می نامند و کلاس های حاوی آنها به طور خودکار به کلاس های انتزاعی تبدیل می شوند. بنابراین، پلی مورفیسم توانایی برقراری ارتباط یکنواخت با اشیاء از طبقات مختلف از طریق یک رابط خاص است. ایدئولوژی چندشکلی بیان می کند که برای برقراری ارتباط با یک شی، نیازی به دانستن نوع آن نیست، بلکه باید بدانید که چه رابطی را پشتیبانی می کند.
    • رابط. در برخی از زبان های برنامه نویسی (C#، جاوا)، مفهوم رابط به وضوح تعریف شده است - این فقط روش ها و ویژگی های عمومی خود کلاس نیست. چنین زبان هایی، به عنوان یک قاعده، از وراثت چندگانه پشتیبانی نمی کنند و با اجازه دادن به هر شیء برای داشتن یک شی پایه و پیاده سازی هر تعداد واسط، آن را جبران می کنند. رابط در تفسیر آنها شباهت است کلاس انتزاعی، فقط حاوی توضیحات (امضا) روش ها و ویژگی های عمومی است. پیاده سازی یک رابط بر دوش هر کلاسی است که قصد پشتیبانی از آن را دارد. همین رابط را می توان توسط کلاس هایی از سلسله مراتب کاملاً متفاوت پیاده سازی کرد که امکان چندشکلی را گسترش می دهد. به عنوان مثال، رابط "ذخیره/بازیابی اطلاعات در پایگاه داده" می تواند توسط هر دو کلاس سلسله مراتب "مبلمان" و کلاس های مرتبط با ثبت سفارش برای ساخت مبلمان پیاده سازی شود، و هنگامی که روی دکمه "ذخیره" کلیک می کنید، برنامه تمام اشیاء را مرور می کند، این رابط را از آنها می خواهد و متد مربوطه را فراخوانی می کند.

    برنامه نویسی شی گرا به طور مداوم در حال تکامل است و پارادایم های جدیدی مانند برنامه نویسی جنبه گرا، موضوع محور و حتی عامل گرا را به وجود می آورد. لازم به ذکر است که دستاوردهای OOP تسخیر نظریه پردازان دیگر است و آنها برای ارائه گزینه های خود برای بهبود و گسترش آن عجله دارند. برنامه نویسی اولیه مفهوم یک کلاس را حذف می کند و آن را با یک نمونه اولیه - نمونه ای از یک شی جایگزین می کند. بنابراین، در یک زبان پروتوتایپ گرا مفهومی از نوع شی وجود ندارد، اما مفهوم الگو یا نمونه اولیه وجود دارد. نمونه اولیه نمونه ای از یک شی است که نمونه های دیگری از آن با کپی (کلونینگ) اعضای آن ایجاد می شود. در جاوا اسکریپت، فیلدها و متدهای یک کلاس را توصیف نمی کنید، بلکه ابتدا یک شی خالی ایجاد می کنید و سپس فیلدها و متدهای لازم را به آن اضافه می کنید (در جاوا اسکریپت می توان یک متد را تعریف کرد و به صورت پویا به یک شی اضافه کرد). به همین ترتیب، نمونه های اولیه ایجاد می شوند، که سپس توسط اشیاء دیگر به عنوان نمونه اولیه خود شناخته می شوند. اگر یک شی دارای متد یا فیلدی نباشد که در مکان فراخوانی مشخص شده است، آنگاه در بین اعضای نمونه اولیه آن جستجو می شود.

    برخی از عناصر برنامه نویسی شی گرا مدرن

    زمان ثابت نمی ماند و زمان زیادی از ظهور OOP گذشته است، بنابراین جای تعجب نیست که امروزه واژگان برنامه نویسی شی گرا به طور قابل توجهی رشد کرده است. بنابراین در اینجا برخی از اصطلاحات و مفاهیم جدید مرتبط با OOP وجود دارد.

    • مناسبت ها. نوع خاصی از اشیاء ایجاد شده برای اطلاع برخی از اشیاء در مورد رویدادهایی که با اشیاء دیگر اتفاق می افتد. در زبان های برنامه نویسی مختلف، مکانیسم رویداد به روش های مختلفی پیاده سازی می شود: گاهی با استفاده از ساختارهای نحوی خاص، و گاهی اوقات با استفاده از ابزارهای اولیه OOP.
    • نوع جهانی. مفهوم انواع عمومی ارتباط مستقیمی با مفهوم OOP ندارد، اما دلیل ظهور عناصری مانند کلاس عمومی است. روش جهانی، رویداد جهانی و غیره نوع عمومی نوعی است که با نوع دیگری (مجموعه ای از انواع) پارامتر می شود. اینکه این نوع پارامتر در زمینه طراحی نوع عمومی چیست، ناشناخته است، اگرچه می توان مقادیر انواع پارامتر را با اجبار آنها به مشتق شدن از یک کلاس خاص یا پیاده سازی رابط های خاص محدود کرد. یک مثال یک کلاس جهانی برای مرتب‌سازی دنباله‌ای از عناصر است که در آن نوع عنصر در دنباله از قبل ناشناخته است. هنگام طراحی چنین کلاسی، مهم است که مشخص کنید نوع پارامتر باید از عملیات مقایسه پشتیبانی کند. هنگام ایجاد اشیاء از انواع عمومی، شما یک پارامتر را به صراحت مشخص می کنید، مانند یک عدد صحیح یا نوع رشته، و خود شی شروع به رفتار می کند که گویی نمونه ای از کلاسی است که به طور خاص برای مرتب سازی اعداد صحیح یا رشته ها ایجاد شده است.
    • استثناها. نوع خاصی از شیء که توسط مکانیزمی برای مدیریت خطاها و استثنائات ساخته شده در یک زبان برنامه نویسی خاص پشتیبانی می شود. استثناها، علاوه بر کد خطا، شامل توضیحات آن، علل احتمالی و مجموعه ای از فراخوانی های متد است که قبل از وقوع استثنا در برنامه رخ داده است.

    معایب برنامه نویسی شی گرا

    قبلاً گفته ام که محبوبیت رویکرد شی گرا برای ایجاد محصولات نرم افزاری بسیار زیاد است. همچنین قبلاً اشاره کرده‌ام که تعداد زیادی از کسانی هستند که به دنبال گسترش این پارادایم هستند. اما راه دیگری برای برجسته شدن در میان جامعه عظیم متخصصان وجود دارد فناوری اطلاعات- این است که اعلام کنیم OOP خود را توجیه نکرده است، که یک دارو نیست، بلکه یک دارونما است. در میان این افراد واقعاً متخصصان بسیار زیادی وجود دارند طبقه بالامانند کریستوفر دیت، الکساندر استپانوف، ادسگر دایکسترا و دیگران، و نظر آنها شایسته توجه است، اما کسانی نیز در مورد آنها می گویند که "همیشه چیزی مانع یک رقصنده بد می شود." در اینجا آنها آشکارترین معایب OOP هستند که کارشناسان به آنها اشاره می کنند:

    1. OOP سلسله مراتب کلاسی عظیمی را ایجاد می کند، که منجر به این واقعیت می شود که عملکرد در پایه و اعضای مشتق شده از کلاس تار شده یا به قول آنها تار می شود و ردیابی منطق عملکرد یک کلاس خاص دشوار می شود. روش.

    2. در برخی از زبان ها، همه داده ها، از جمله انواع ابتدایی، اشیا هستند و این نمی تواند منجر به مصرف اضافی حافظه و زمان CPU شود.

    3. همچنین، سرعت اجرای برنامه ممکن است تحت تأثیر معکوس پیاده‌سازی چندشکلی قرار گیرد که مبتنی بر مکانیسم‌هایی برای اتصال دیرهنگام یک فراخوانی متد با اجرای خاص آن در یکی از کلاس‌های مشتق شده است.

    4. جنبه روانی. بسیاری از مردم فکر می کنند که OOP جالب است و شروع به استفاده از رویکردهای آن همیشه و همه جا و بی رویه می کنند. همه اینها منجر به کاهش عملکرد برنامه به طور خاص و بی اعتبار کردن OOP به طور کلی می شود.

    جاوا یک زبان شی گرا است. این بدان معنی است که شما باید برنامه های جاوا را با استفاده از یک سبک شی گرا بنویسید. و این سبک بر اساس استفاده از آبجکت ها و کلاس ها در برنامه است. بیایید سعی کنیم با کمک مثال ها بفهمیم که کلاس ها و اشیاء چیست و همچنین چگونه اصول اولیه OOP را در عمل اعمال کنیم: انتزاع، وراثت، چندشکلی و کپسوله سازی.

    شی چیست؟

    جهانی که ما در آن زندگی می کنیم از اشیا تشکیل شده است. اگر به اطراف نگاه کنیم، می بینیم که اطرافمان را خانه ها، درختان، ماشین ها، مبلمان، ظرف ها، کامپیوترها احاطه کرده اند. همه این موارد، اشیا هستند و هر یک از آنها دارای مجموعه ای از ویژگی ها، رفتار و هدف خاصی هستند. ما به اشیا عادت داریم و همیشه از آنها برای اهداف بسیار خاص استفاده می کنیم. مثلاً اگر نیاز به سر کار داریم از ماشین استفاده می کنیم، اگر می خواهیم غذا بخوریم از ظروف و اگر نیاز به استراحت داریم به یک مبل راحتی نیاز داریم. انسان عادت دارد برای حل مشکلات زندگی روزمره به طور عینی فکر کند. این یکی از دلایل استفاده از آبجکت ها در برنامه نویسی بود و این رویکرد برای ایجاد برنامه ها را شی گرا می نامیدند. بیایید یک مثال بزنیم. تصور کنید چه چیزی توسعه داده اید مدل جدیدتلفن و می خواهید تولید انبوه را راه اندازی کنید. به عنوان یک طراح تلفن، شما می دانید که برای چه چیزی است، چگونه کار می کند و از چه قطعاتی تشکیل شده است (قاب، میکروفون، بلندگو، سیم ها، دکمه ها و غیره). با این حال، فقط شما می دانید که چگونه این قطعات را به هم وصل کنید. با این حال، شما برنامه ای برای تولید تلفن های شخصی ندارید؛ برای این کار شما یک پرسنل کامل دارید. برای اینکه مجبور نباشید هر بار نحوه اتصال قطعات گوشی را توضیح دهید و همه گوشی های در حال تولید یکسان شوند، قبل از شروع به تولید آنها باید یک نقاشی به شکل یک طراحی کنید. توضیح ساختار گوشی در OOP، چنین توصیف، ترسیم، نمودار یا قالب را یک کلاس می گویند که در هنگام اجرای برنامه یک شی از آن ایجاد می شود.یک کلاس توصیفی از یک شی است که هنوز ایجاد نشده است، مانند یک الگوی کلی که از فیلدها، متدها و یک سازنده تشکیل شده است، و یک شی نمونه ای از یک کلاس است که بر اساس این توضیحات ایجاد شده است.

    انتزاع - مفهوم - برداشت

    بیایید اکنون به این فکر کنیم که چگونه می توانیم از یک شی در دنیای واقعی به یک شی در یک برنامه، با استفاده از تلفن به عنوان مثال، حرکت کنیم. تاریخچه این وسیله ارتباطی بیش از 100 سال است و تلفن مدرن، برخلاف مدل قبلی خود در قرن 19، دستگاه بسیار پیچیده تری است. وقتی از یک تلفن استفاده می کنیم، به ساختار آن و فرآیندهایی که در داخل آن رخ می دهد فکر نمی کنیم. ما به سادگی از عملکردهای ارائه شده توسط توسعه دهندگان تلفن استفاده می کنیم - دکمه ها یا صفحه لمسی برای انتخاب شماره و برقراری تماس. یکی از اولین رابط های تلفن، دستگیره ای بود که برای برقراری تماس می چرخید. البته این خیلی راحت نبود. با این وجود، دسته عملکرد خود را به درستی انجام داد. اگر به مدرن ترین و اولین تلفن نگاه کنید، می توانید بلافاصله مهم ترین جزئیاتی را که هم برای دستگاهی از اواخر قرن نوزدهم و هم برای یک تلفن هوشمند فوق مدرن مهم هستند، شناسایی کنید. این یعنی برقراری تماس (شماره گیری) و دریافت تماس. در اصل، این چیزی است که یک گوشی را به یک گوشی تبدیل می کند و نه چیز دیگری. اکنون ما اصل را در OOP اعمال کرده ایم - بیشترین برجسته سازی ویژگی های مهمو اطلاعات مربوط به شی این اصل را انتزاع می نامند. انتزاع در OOP همچنین می تواند به عنوان راهی برای نمایش عناصر یک مسئله دنیای واقعی به عنوان اشیا در یک برنامه تعریف شود. انتزاع همیشه با تعمیم برخی از اطلاعات در مورد ویژگی های اشیا یا اشیا همراه است، بنابراین نکته اصلی این است که اطلاعات مهم را از اطلاعات ناچیز در زمینه مشکل در حال حل جدا کنیم. در این حالت، چندین سطح از انتزاع می تواند وجود داشته باشد. بیایید سعی کنیم اصل انتزاع را در گوشی های خود اعمال کنیم. ابتدا، بیایید متداول ترین انواع گوشی ها را از ابتدا تا امروز برجسته کنیم. به عنوان مثال، آنها را می توان در قالب یک نمودار نشان داده شده در شکل 1 نشان داد. اکنون، با استفاده از انتزاع، می توانیم اشیاء را در این سلسله مراتب برجسته کنیم. اطلاعات کلی: یک نوع شی انتزاعی کلی - تلفن، ویژگی های عمومیتلفن - سال ایجاد آن و رابط مشترک - همه تلفن ها قادر به دریافت و ارسال تماس هستند. در جاوا اینگونه به نظر می رسد: کلاس انتزاعی عمومی AbstractPhone (سال int خصوصی؛ عمومی AbstractPhone (int سال) (این . سال = سال؛ ) فراخوانی عمومی انتزاعی (int outputNumber)؛ حلقه انتزاعی عمومی (int inputNumber)؛ ) بر اساس این کلاس انتزاعی، ما قادر خواهیم بود انواع جدیدی از تلفن ها را در برنامه با استفاده از سایر اصول اولیه OOP جاوا ایجاد کنیم که در ادامه به آن ها خواهیم پرداخت.

    کپسوله سازی

    با استفاده از انتزاعات برجسته می کنیم عمومی برای همه اشیا با این حال، هر مدل گوشی فردی است و تا حدودی با مدل های دیگر متفاوت است. چگونه می توانیم در برنامه مرزبندی کنیم و این فردیت را مشخص کنیم؟ چگونه می توانیم مطمئن شویم که هیچ یک از کاربران نمی توانند به طور تصادفی یا عمدی گوشی ما را بشکنند یا سعی کنند یک مدل را به مدل دیگر تبدیل کنند؟ برای دنیای اشیاء واقعی، پاسخ واضح است: شما باید تمام قطعات را در بدنه گوشی قرار دهید. از این گذشته، اگر ما این کار را انجام ندهیم و تمام قسمت های داخلی تلفن و سیم های متصل کننده آنها را بیرون بگذاریم، قطعا یک آزمایشگر کنجکاو وجود خواهد داشت که می خواهد عملکرد تلفن ما را "بهبود" دهد. برای حذف چنین تداخلی در طراحی و عملکرد یک شی، OOP از اصل کپسولاسیون استفاده می کند - دیگری اصل اساسی OOP که در آن صفات و رفتار یک شی در یک کلاس ترکیب می شود، پیاده سازی داخلی شی از کاربر پنهان می شود و یک رابط عمومی برای کار با شی ارائه می شود. وظیفه برنامه نویس این است که تعیین کند کدام ویژگی ها و روش ها برای عموم قابل دسترسی هستند و کدام یک پیاده سازی داخلی شی هستند و نباید اصلاح شوند.

    کپسوله سازی و کنترل دسترسی

    بیایید بگوییم که در طول تولید، اطلاعات مربوط به آن در پشت تلفن حک شده است: سال ساخت آن یا آرم شرکت سازنده. این اطلاعات کاملاً مشخص کننده این مدل - شرایط آن است. می توان گفت که توسعه دهنده تلفن از تغییرناپذیری این اطلاعات مراقبت کرده است - بعید است که کسی به فکر حذف حکاکی باشد. در دنیای جاوا، وضعیت اشیاء آینده در یک کلاس با استفاده از فیلدها توصیف می شود و رفتار آنها با استفاده از روش ها توصیف می شود. توانایی تغییر حالت و رفتار با استفاده از اصلاح کننده های دسترسی به فیلدها و روش ها انجام می شود - خصوصی، حفاظت شده، عمومی ، و پیش فرض (دسترسی پیش فرض). به عنوان مثال، ما تصمیم گرفتیم که سال ساخت، نام سازنده گوشی و یکی از متدها متعلق به پیاده سازی داخلی کلاس باشد و توسط سایر آبجکت های برنامه قابل تغییر نباشد. با استفاده از کد، کلاس را می توان به صورت زیر توصیف کرد: کلاس عمومی SomePhone (سال int خصوصی؛ شرکت رشته خصوصی؛ عمومی SomePhone (سال int، شرکت رشته) (این . سال = سال؛ این . شرکت = شرکت؛ ) خلأ خصوصی openConnection ( ) ( / /findComutator //openNewConnection... ) فراخوانی با اعتبار عمومی () (openConnection () ؛ System. out. println ("تماس با شماره") ؛ ) زنگ عمومی خالی () ( System. out. println ("Ding -ding") ؛ )) اصلاح کننده خصوصی فیلدها و متدهای یک کلاس را فقط در آن کلاس در دسترس قرار می دهد. این بدان معنی است که شما می توانید دسترسی داشته باشید خصوصی فیلدها از خارج غیرممکن است، همانطور که هیچ راهی برای فراخوانی وجود ندارد خصوصی مواد و روش ها. مخفی کردن دسترسی به متد openConnection نیز ما را در تغییر پیاده‌سازی داخلی این متد باز می‌گذارد، زیرا این روش تضمین شده است که توسط اشیاء دیگر استفاده نمی‌شود و کار آنها را مختل نمی‌کند. برای کار با شی ما، روش های تماس و زنگ را با استفاده از یک اصلاح کننده باز می گذاریم عمومی . ارائه روش های عمومی برای کار با یک شی نیز بخشی از مکانیسم کپسوله سازی است، زیرا اگر دسترسی به یک شی به طور کامل ممنوع شود، بی فایده خواهد شد.

    وراثت

    بیایید دوباره به نمودار تلفن نگاه کنیم. می‌بینید که نشان‌دهنده سلسله مراتبی است که در آن مدلی که در زیر قرار دارد، تمام ویژگی‌های مدل‌هایی که در بالای شاخه قرار دارند، به علاوه ویژگی‌های خودش را دارد. به عنوان مثال، یک گوشی هوشمند از شبکه تلفن همراه برای ارتباط استفاده می کند (خواص تلفن همراه را دارد)، بی سیم و قابل حمل است (خواص تلفن بی سیم را دارد) و می تواند تماس بگیرد و تماس بگیرد (خواص تلفن را دارد). در این مورد، می توان در مورد وراثت ویژگی های شی صحبت کرد. در برنامه نویسی، وراثت استفاده از کلاس های موجود برای تعریف کلاس های جدید است. بیایید به مثالی از ایجاد کلاس تلفن هوشمند با استفاده از ارث بری نگاه کنیم. تمام تلفن های بی سیم از باتری های قابل شارژ تغذیه می شوند که عمر کاری مشخصی در ساعت دارند. بنابراین بیایید این ویژگی را به کلاس تلفن بی‌سیم اضافه کنیم: کلاس انتزاعی عمومی WirelessPhone، AbstractPhone را گسترش می‌دهد (اینت ساعت خصوصی؛ بی‌سیم عمومی (سال int، ساعت بین‌المللی) (فوق العاده (سال)؛ این . ساعت = ساعت؛) تلفن‌های همراه ویژگی‌ها را به ارث می‌برند. از یک تلفن بی‌سیم، ما همچنین پیاده‌سازی روش‌های تماس و زنگ را به این کلاس اضافه کردیم: کلاس عمومی CellPhone WirelessPhone را گسترش می‌دهد ( تلفن همراه عمومی (سال int، ساعت بین‌المللی) ( super (سال، ساعت)؛ ) @Override public void call ( int outputNumber) ( System. out. println ("شماره تماس" + outputNumber) ؛ ) @Override public void ring (int inputNumber) ( System. out. println ( "یک مشترک با شما تماس می گیرد"+ ورودی شماره)؛ ) ) و در نهایت کلاس گوشی های هوشمند که بر خلاف تلفن های همراه کلاسیک دارای سیستم عامل تمام عیار است. می توانید برنامه های جدیدی را که توسط این دستگاه پشتیبانی می شود به گوشی هوشمند خود اضافه کنید. سیستم عامل، بنابراین عملکرد آن را گسترش می دهد. با استفاده از کد، کلاس را می توان به صورت زیر توصیف کرد: کلاس عمومی تلفن هوشمند، تلفن همراه را گسترش می دهد (سیستم عملیات رشته خصوصی؛ تلفن هوشمند عمومی (سال int، ساعت، ساعت عملیات رشته) (فوق العاده (سال، ساعت)؛ این . OperationSystem = OperationSystem؛ ) خالی عمومی install (String program) ( System. out. println ("I install " + program + "for" + operationSystem) ; ) ) همانطور که می بینید، کد جدید بسیار کمی برای توصیف کلاس Smartphone ایجاد کردیم، اما یک کد جدید دریافت کردیم. کلاس با قابلیت های جدید استفاده از این اصل OOP java می تواند مقدار کد را به میزان قابل توجهی کاهش دهد و در نتیجه کار برنامه نویس را آسان تر کند.

    پلی مورفیسم

    اگر به همه مدل‌های تلفن نگاه کنیم، با وجود تفاوت‌های ظاهری و طراحی مدل‌ها، می‌توانیم برخی از رفتارهای رایج در آنها را شناسایی کنیم - همه آنها می‌توانند تماس بگیرند و تماس بگیرند و مجموعه‌ای از دکمه‌های کنترلی نسبتاً واضح و ساده دارند. با استفاده از یکی از اصول اولیه OOP که قبلاً برای ما شناخته شده است ، انتزاع در اصطلاح برنامه نویسی ، می توان گفت که شی تلفن دارای یک رابط مشترک است. بنابراین، کاربران گوشی می توانند با استفاده از دکمه های کنترلی یکسان (مکانیکی یا لمسی)، بدون پرداختن به جزئیات فنی دستگاه، به راحتی از مدل های مختلف استفاده کنند. بنابراین، شما دائماً از تلفن همراه استفاده می کنید و به راحتی می توانید از تلفن ثابت آن تماس بگیرید. اصل در OOP زمانی که یک برنامه می تواند از اشیاء با یک رابط بدون اطلاعات در مورد ساختار داخلی شی استفاده کند نامیده می شود پلی مورفیسم . بیایید تصور کنیم که در برنامه ما باید کاربری را توصیف کنیم که می تواند از هر مدل تلفنی برای تماس با کاربر دیگر استفاده کند. چگونه می توانید این کار را انجام دهید: کلاس عمومی کاربر ( نام رشته خصوصی؛ کاربر عمومی (نام رشته) (این . نام = نام؛ ) عمومی خالی callAnotherUser (شماره int، تلفن AbstractPhone) ( // این چند شکلی است - با استفاده از نوع انتزاعی AbstractPhone phone در کد!تلفن. شماره تماس) ؛ ) ) ) حالا مدل های مختلف گوشی را شرح می دهیم. یکی از اولین مدل‌های تلفن: کلاس عمومی ThomasEdisonPhone گسترش AbstractPhone ( عمومی ThomasEdisonPhone (int year) ( فوق العاده (سال) ; ) @Override call void public (int outputNumber) ( System. out. println ("Rotate the knob" ) ; System . out .println( "لطفا شماره تلفن خود را بفرمایید قربان") ؛ ) @Override زنگ عمومی خالی (int inputNumber) ( System. out. println ( "تلفن در حال زنگ زدن است" ) ; ) ) تلفن ثابت معمولی: کلاس عمومی تلفن گسترش می یابد AbstractPhone ( تلفن عمومی (int year) ( super (سال) ; ) @Override public void call (int outputNumber) ( System. out. println ("تماس با شماره" + outputNumber) ; ) @Override public void ring (int inputNumber) ( System. out. println ("تلفن در حال زنگ زدن است") ; ) ) و در نهایت، تلفن ویدیویی جالب: کلاس عمومی VideoPhone AbstractPhone را گسترش می دهد ( VideoPhone عمومی (int year) ( super (year) ; ) @Override public void call (int outputNumber) ( System. out. println ( "من در حال اتصال یک کانال ویدئویی برای مشترک هستم"+ خروجی شماره)؛ ) @Override حلقه خالی عمومی (int inputNumber) ( System. out. println ( "شما یک تماس ویدیویی ورودی دارید..."+ ورودی شماره)؛ ) ) بیایید در متد main() اشیاء ایجاد کنیم و متد callAnotherUser را آزمایش کنیم: AbstractPhone firstPhone = new ThomasEdisonPhone (1879) ; چکیده تلفن تلفن = تلفن جدید (1984); AbstractPhone videoPhone= جدید VideoPhone (2018) ; کاربر کاربر = کاربر جدید ("Andrey") ; کاربر. callAnotherUser(224466، firstPhone)؛ // دستگیره را بچرخانید //لطفاً شماره مشترک را قربان بدهیدکاربر. callAnotherUser(224466، phone); //شماره تماس 224466کاربر. callAnotherUser(224466، videoPhone)؛ //اتصال یک کانال ویدیویی برای مشترک 224466با فراخوانی یک روش روی شی کاربر، نتایج متفاوتی گرفتیم. اجرای خاص روش فراخوانی در متد callAnotherUser به صورت پویا بر اساس نوع خاص شیء فراخوان در طول اجرای برنامه انتخاب شد. این مزیت اصلی پلی مورفیسم است - انتخاب پیاده سازی در طول اجرای برنامه. در مثال‌های کلاس تلفن بالا، از روش overriding استفاده کردیم، تکنیکی که پیاده‌سازی متد تعریف‌شده در کلاس پایه را بدون تغییر امضای متد تغییر می‌دهد. این اساساً یک جایگزین متد است و متد جدیدی است که در زیر کلاس تعریف شده است که هنگام اجرای برنامه فراخوانی می شود. به طور معمول، هنگام لغو یک متد، از حاشیه نویسی @Override استفاده می‌شود که به کامپایلر می‌گوید امضای روش‌های لغو و نادیده گرفته شده را بررسی کند. در نهایت برای اطمینان از اینکه سبک برنامه شما با مفهوم OOP و اصول OOP java مطابقت دارد، نکات زیر را دنبال کنید:
    • برجسته کردن ویژگی های اصلی شی.
    • مشخص کردن خصوصیات و رفتار مشترک و استفاده از وراثت هنگام ایجاد اشیا.
    • از انواع انتزاعی برای توصیف اشیا استفاده کنید.
    • سعی کنید همیشه متدها و فیلدهای مربوط به پیاده سازی داخلی کلاس را مخفی کنید.

    احتمالاً نیمی از مشاغل خالی (اگر نه بیشتر) به دانش و درک OOP نیاز دارند. بله، این متدولوژی قطعا برنامه نویسان زیادی را مجذوب خود کرده است! معمولاً درک OOP با تجربه همراه است، زیرا عملاً مواد مناسب و در دسترس در مورد این موضوع وجود ندارد. و حتی اگر وجود داشته باشد، دور از دسترس است که خوانندگان به آنها برخورد کنند. امیدوارم بتوانم اصول این متدولوژی فوق العاده را همانطور که می گویند روی انگشتانم توضیح دهم.

    بنابراین، قبلاً در ابتدای مقاله به اصطلاح "روش شناسی" اشاره کردم. هنگامی که برای برنامه نویسی به کار می رود، این اصطلاح به معنای وجود مجموعه ای از روش ها برای سازماندهی کد، روش های نوشتن آن است که با رعایت آنها، برنامه نویس قادر به نوشتن برنامه های کاملاً قابل استفاده خواهد بود.

    OOP (یا برنامه نویسی شی گرا) روشی برای سازماندهی کد برنامه است که در آن بلوک های سازنده اصلی برنامه اشیا و کلاس ها هستند و منطق برنامه بر اساس تعامل آنها ساخته می شود.


    درباره اشیا و کلاس ها

    کلاس- این یک ساختار داده است که می تواند توسط خود برنامه نویس ایجاد شود. در شرایط OOP، یک کلاس از زمینه های(به عبارت ساده - متغیرها) و مواد و روش ها(به عبارت ساده - توابع). و همانطور که مشخص شد، ترکیب داده ها و عملکردها برای کار بر روی آن در یک ساختار قدرت غیر قابل تصوری می دهد. یک شییک نمونه خاص از یک کلاس است. به دنبال تشبیه یک کلاس با یک ساختار داده، یک شی یک ساختار داده خاص است که مقادیری به فیلدهای خود اختصاص داده است. بگذارید با یک مثال توضیح دهم:

    فرض کنید باید برنامه ای بنویسیم که محیط و مساحت یک مثلث را محاسبه کند که با دو ضلع و زاویه بین آنها به دست می آید. برای نوشتن چنین برنامه ای با استفاده از OOP، باید یک کلاس (یعنی یک ساختار) مثلث ایجاد کنیم. کلاس Triangle سه فیلد (سه متغیر) را ذخیره می کند: سمت A، ضلع B، زاویه بین آنها. و دو روش (دو تابع): محاسبه محیط، محاسبه مساحت. با این کلاس می توانیم هر مثلثی را توصیف کنیم و محیط و مساحت آن را محاسبه کنیم. بنابراین، یک مثلث خاص با اضلاع مشخص و زاویه بین آنها، نمونه ای از کلاس مثلث نامیده می شود. بنابراین، یک کلاس یک الگو است، و یک نمونه یک پیاده سازی مشخص از الگو است. اما نمونه ها اشیا هستند، یعنی عناصر خاصی که مقادیر خاصی را ذخیره می کنند.

    یکی از رایج ترین زبان های برنامه نویسی شی گرا جاوا است. در آنجا شما به سادگی نمی توانید بدون استفاده از اشیاء انجام دهید. کد کلاسی که یک مثلث را در این زبان توصیف می کند به این صورت است:

    /** * کلاس مثلث. */ کلاس مثلث ( /** * روش خاصی به نام سازنده کلاس. * سه پارامتر را به عنوان ورودی می گیرد: * طول ضلع A، طول ضلع B، * زاویه بین این ضلع ها (بر حسب درجه) */ مثلث(دو ضلعA، دو برابر sideB , double angleAB) (this.sideA = sideA; this.sideB = sideB; this.angleAB = angleAB; ) double sideA؛ //فیلد کلاس، مقدار ضلع A را در مثلث توصیف شده double sideB ذخیره می کند؛ //فیلد کلاس ، مقدار ضلع B را در مثلث توصیف شده دو زاویهAB ذخیره می کند؛ //فیلد کلاس زاویه (بر حسب درجه) بین دو ضلع را در مثلث توصیف شده ذخیره می کند /** * روش کلاسی که مساحت مثلث را محاسبه می کند */ double getSquare() ( double square = this.sideA * this .sideB * Math.sin(this.angleAB * Math.PI / 180); return square; ) /** * متد کلاسی که محیط یک مثلث را محاسبه می کند */ double getPerimeter() ( double sideC = Math.sqrt(Math.pow (this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math.cos(this. angleAB * Math.PI / 180))؛ محیط دو برابر = this.sideA + this.sideB + sideC; محیط بازگشت؛ ))

    اگر کد زیر را داخل کلاس اضافه کنیم:

    /** * این جایی است که برنامه اجرا می شود */ public static void main(string args) (//Values ​​5, 17, 35 به سازنده کلاس Triangle می رود Triangle triangle1 = New Triangle(5, 17, 35 System.out .println ("مساحت مثلث1: "+triangle1.getSquare())؛ System.out.println("محیط مثلث1: "+triangle1.getPerimeter()); //مقادیر 6 , 8, 60 به سازنده کلاس Triangle بروید Triangle triangle2 = new Triangle(6, 8, 60)؛ System.out.println("Area of ​​triangle1: "+triangle2.getSquare()); System.out.println ("Perimeter of triangle1: "+triangle2.getPerimeter())؛ )

    سپس برنامه می تواند از قبل برای اجرا راه اندازی شود. این یک ویژگی است زبان جاوا. اگر کلاس چنین متدی داشته باشد

    اصلی خالی استاتیک عمومی (آرگس های رشته ای)

    سپس این کلاس را می توان اجرا کرد. بیایید کد را با جزئیات بیشتری بررسی کنیم. بیایید با خط شروع کنیم

    مثلث مثلث1 = مثلث جدید(5، 17، 35);

    در اینجا نمونه ای از triangle1 از کلاس Triangle ایجاد می کنیم و بلافاصله پارامترهای اضلاع و زاویه بین آنها را به آن می دهیم. در همان زمان، متد خاصی به نام سازنده فراخوانی می شود و فیلدهای شی را با مقادیر ارسال شده به سازنده پر می کند. خوب، در مورد خطوط چطور؟

    System.out.println("مساحت triangle1: "+triangle1.getSquare()); System.out.println("Perimeter of triangle1: "+triangle1.getPerimeter());

    مساحت محاسبه شده مثلث و محیط آن را به کنسول خروجی دهید.

    همین اتفاق برای نمونه دوم کلاس Triangle نیز می افتد.

    درک کلاس ها و طراحی اشیاء خاصاولین قدم مطمئن برای درک روش OOP است.

    بار دیگر مهم ترین چیز:

    OOP- این روشی برای سازماندهی کد برنامه است.

    کلاس- این یک ساختار داده سفارشی است که داده ها و توابع را برای کار با آنها گرد هم می آورد (فیلدهای کلاس و روش های کلاس).

    یک شییک نمونه خاص از یک کلاس است که به فیلدهای آن مقادیر خاصی داده می شود.


    سه کلمه جادویی

    OOP شامل سه رویکرد کلیدی است: وراثت، کپسولاسیون و چندشکلی. برای شروع، من تعاریفی را از ویکی پدیا ارائه می کنم:

    Encapsulation یک ویژگی سیستمی است که به شما امکان می دهد داده ها و روش هایی را که با آنها کار می کنند در یک کلاس ترکیب کنید. برخی از زبان‌ها (مانند C++) کپسولاسیون را با پنهان کردن یکسان می‌دانند، اما بیشتر (Smalltalk، Eiffel، OCaml) بین این مفاهیم تمایز قائل می‌شوند.

    وراثت یک ویژگی سیستمی است که به شما امکان می دهد یک کلاس جدید را بر اساس کلاس موجود با عملکرد جزئی یا کاملاً قرضی توصیف کنید. کلاسی که وراثت از آن مشتق می شود، پایه، والد یا سوپرکلاس نامیده می شود. طبقه جدید یک طبقه اولاد، وارث، فرزند یا مشتق است.

    Polymorphism یک ویژگی سیستمی است که به شما امکان می دهد از اشیاء با رابط یکسان بدون اطلاعات در مورد نوع و ساختار داخلی شی استفاده کنید.

    درک معنای واقعی همه این تعاریف بسیار دشوار است. در کتاب‌های تخصصی که این موضوع را پوشش می‌دهند، هر تعریف اغلب یک فصل کامل، اما حداقل یک پاراگراف را اختصاص می‌دهد. اگرچه، ماهیت چیزی که یک برنامه نویس باید بفهمد و برای همیشه در مغزش حک کند، بسیار کم است.
    و به عنوان مثال برای تجزیه و تحلیل، از ارقام در یک هواپیما استفاده خواهیم کرد. از هندسه مدرسه می دانیم که برای تمام اشکال توصیف شده در یک صفحه، می توان محیط و مساحت را محاسبه کرد. به عنوان مثال، برای یک نقطه، هر دو پارامتر برابر با صفر هستند. برای یک قطعه، ما فقط می توانیم محیط را محاسبه کنیم. و برای یک مربع، مستطیل یا مثلث - هر دو. اکنون این کار را با شرایط OOP توصیف می کنیم. همچنین ایده خوبی است که زنجیره استدلالی را درک کنید که منجر به سلسله مراتب کلاسی می شود که به نوبه خود در کدهای کاری تجسم یافته است. برو:


    بنابراین، نقطه کوچکترین است شکل هندسی، که اساس سایر ساخت ها (شکل ها) است. بنابراین نقطه به عنوان کلاس والد پایه انتخاب شد. بیایید یک کلاس نقطه ای در جاوا بنویسیم:

    /** * کلاس نقطه. کلاس پایه */ کلاس Point ( /** * سازنده خالی */ Point() () /** * روش کلاس که مساحت یک شکل را محاسبه می کند */ double getSquare() ( بازگشت 0; ) /** * متد کلاسی که محیط شکل */ double getPerimeter() را محاسبه می کند ( بازگشت 0; ) /** * متد کلاسی که شرح شکل */ string getDescription() ( بازگشت "نقطه"؛ ))

    کلاس Point حاصل یک سازنده خالی دارد زیرا در این مثالما بدون مختصات خاص کار می کنیم، اما فقط با پارامترها و مقادیر جانبی کار می کنیم. از آنجایی که نقطه هیچ طرفی ندارد، نیازی به ارسال هیچ پارامتری به آن نیست. همچنین توجه داشته باشید که کلاس دارای متدهای Point::getSquare() و Point::getPerimeter() برای محاسبه مساحت و محیط است که هر دو 0 برمی گردند. برای یک نقطه، این منطقی است.


    از آنجایی که نقطه ما اساس همه شکل های دیگر است، کلاس های این فیگورهای دیگر را از کلاس Point به ارث می بریم. اجازه دهید کلاس یک قطعه به ارث برده شده از کلاس یک نقطه را شرح دهیم:

    /** * Class Line Segment */ class LineSegment Point را گسترش می دهد ( LineSegment(Double segmentLength) ( this.segmentLength = segmentLength; ) segmentDoubleLength; // Length of line /** * روش کلاس Overridden که مساحت را محاسبه می کند خط */ double getSquare( ) ( return 0; ) /** * روش کلاس Overridden که محیط یک قطعه را محاسبه می کند */ double getPerimeter() ( return this.segmentLength; ) رشته getDescription() ( بازگشت "طول بخش: " + this.segmentLength; ) )

    Class LineSegment Point را گسترش می دهد

    به این معنی است که کلاس LineSegment از کلاس Point ارث می برد. متدهای LineSegment::getSquare() و LineSegment::getPerimeter() متدهای کلاس پایه مربوطه را نادیده می گیرند. مساحت یک قطعه همیشه صفر است و مساحت محیط برابر با طول این قطعه است.

    اکنون مانند کلاس segment، کلاس مثلث را (که از کلاس نقطه نیز به ارث می برد) را توصیف می کنیم:

    /** * کلاس مثلث. */ کلاس مثلث نقطه را گسترش می دهد ( /** * سازنده کلاس. سه پارامتر را به عنوان ورودی می گیرد: * طول ضلع A، طول ضلع B، * زاویه بین این ضلع ها (بر حسب درجه) */ مثلث(دو ضلعA، دو ضلعB، double angleAB ) ( this.sideA = sideA؛ this. مقدار ضلع B در مثلث توصیف شده دو زاویهAB؛ //فیلد کلاس که زاویه (بر حسب درجه) بین دو ضلع را در مثلث توصیف شده ذخیره می کند /** * روش کلاسی که مساحت یک مثلث را محاسبه می کند */ دو برابر getSquare() ( double Square = (this.sideA * this.sideB * Math.sin(this.angleAB * Math.PI / 180))/2; return square; ) /** * متد کلاسی که محیط یک را محاسبه می کند مثلث */ double getPerimeter() ( double sideC = Math.sqrt(Math. pow(this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math.cos (this.angleAB * Math.PI / 180))؛ محیط دو برابر = this.sideA + this.sideB + sideC; محیط بازگشت؛ ) رشته getDescription() ("مثلث با اضلاع: " + this.sideA + "، " + this.sideB + " و زاویه بین آنها را برمی گرداند: " + this.angleAB; ) )

    اینجا چیز جدیدی نیست همچنین متدهای Triangle::getSquare() و Triangle::getPerimeter() متدهای مربوط به کلاس پایه را نادیده می گیرند.
    خب، در واقع، همان کدی که جادوی چندشکلی را نشان می دهد و قدرت OOP را نشان می دهد:

    Class Main ( /** * اینجا جایی است که برنامه اجرا می شود */ public static void main(string args) ( //ArrayList - این یک ساختار داده ویژه در جاوا // است که به شما امکان می دهد اشیاء از نوع خاصی را در یک ذخیره کنید. آرایه ArrayList figures = ArrayList جدید ()؛ //افزودن سه شی مختلف به ارقام array figures.add(new Point()); figures.add(new LineSegment(133)); figures.add(new Triangle(10, 17، 55))؛ برای (int i = 0;i

    ما یک آرایه از اشیاء کلاس Point ایجاد کرده ایم و از آنجایی که کلاس های LineSegment و Triangle از کلاس Point به ارث می برند، می توانیم آنها را در این آرایه قرار دهیم. به نظر می رسد که می توانیم هر شکلی را که در آرایه فیگور قرار دارد به عنوان یک شی از کلاس Point در نظر بگیریم. چندشکلی این است: معلوم نیست که اشیاء موجود در آرایه فیگور متعلق به کدام کلاس هستند، اما از آنجایی که تمام اشیاء داخل این آرایه متعلق به یک کلاس پایه یکسان هستند، پس همه متدهایی که برای کلاس Point قابل اجرا هستند نیز قابل اجرا هستند. به طبقات نسل آن


    حالا در مورد کپسولاسیون. اینکه ما پارامترهای یک شکل و روش‌های محاسبه مساحت و محیط را در یک کلاس قرار می‌دهیم، کپسوله‌سازی است؛ ما شکل‌ها را در کلاس‌های جداگانه کپسوله کردیم. این واقعیت که ما از روش خاصی در کلاس برای محاسبه محیط استفاده می کنیم، کپسوله سازی است؛ ما محاسبه محیط را در متد getPerimiter() کپسوله کردیم. به عبارت دیگر، کپسوله سازی پنهان کردن اجرا است (شاید کوتاه ترین و در عین حال گنجایش تعریف کپسوله سازی).


    کد نمونه کامل:

    وارد کردن java.util.ArrayList. class Main ( /** * اینجا جایی است که برنامه اجرا می شود */ public static void main(string args) (//ArrayList یک ساختار داده خاص در جاوا // است که به شما امکان می دهد اشیاء از نوع خاصی را در یک آرایه ذخیره کنید. ArrayList figures = ArrayList () 55))؛ برای (int i = 0;i