خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
SHOW FULL COLUMNS FROM `wp_options`

خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category', 'post_tag', 'post_format', 'hashtags') AND tr.object_id IN (2775) ORDER BY t.name ASC

آموزش قدم به قدم جاوا - قسمت هجدهم - Hive | مجله توسعه‌دهندگان وب
  • شاخه: دسته‌بندی نشده    ::    بازدید: ۷۲۷
  • ۳

آموزش قدم به قدم جاوا – قسمت هجدهم

اینترفیس (Interface)

اینترفیس‌ها را می‌توان به دو صورت تعریف کرد:

  1. اینترفیس یک نوع قرارداد است. هر کلاس می‌تواند یک یا چند اینترفیس را به‌کار گیرد و پیاده‌سازی (implement) کند. کلاسی که یک اینترفیس را پیاده‌سازی کند باید قواعد تعریف شده در آن را رعایت کند.
    در عمل اینترفیس ساختاری مانند کلاس دارد که تعدادی متد در آن تعریف می‌شوند اما این متدها بدنه ندارند و فقط امضای آن‌ها تعریف شده است. کلاسی که یک اینترفیس را پیاده‌سازی می‌کند باید تمام متدهای موجود در آن اینترفیس را Override کند.
    متدهای موجود در یک اینترفیس بدنه‌ای ندارند و بنابراین مشخص نیست که چه کاری انجام می‌دهند. هر کلاسی که اینترفیس را پیاده‌سازی می‌کند می‌تواند به شکل دلخواه خود بدنه آن متد را تعریف کنند.
  2. دومین تعریف و شاید تعریف بهتر این است ‌که اینترفیس راهی برای توصیف مجموعه‌ای از کلاس‌ها است. فرض کنید اینترفیسی داریم که متدهای مربوط به کار با شبکه در آن تعریف شده‌‌اند. حال می‌توانیم کلاس‌هایی که این اینترفیس را پیاده‌سازی می‌کنند به عنوان کلاس‌هایی که با شبکه کار می‌کنند گروه‌بندی و توصیف کنیم.

ایجاد و تعریف یک اینترفیس

اینترفیس‌ها به شکل کلی زیر در فایلی با فرمت .java ذخیره می‌شوند:

interface نام اینترفیس {

}

اینترفیس می‌تواند دارای تعیین‌کننده دسترسی public و یا بدون تعیین‌کننده دسترسی باشد.

می‌خواهیم اینترفیسی به نام Animal با دو متد تعریف کنیم. فایلی با فرمت .java ایجاد کرده و کدهای زیر را درون آن می‌نویسیم (در ایکلیپس می‌توانید با راست کلیک روی پکیج و از منوی New گزینه Interface را انتخاب کنید):

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

نکته دیگر این‌که این دو متد هیچ‌‌کدام تعیین‌کننده دسترسی ندارند. به طور پیش‌فرض تمام متدهای موجود در یک اینترفیس public هستند. البته اگر برای این دو متد تعیین‌کننده دسترسی public هم بنویسیم مشکلی پیش نمی‌آید اما نیازی به این کار نیست.

حال کلاسی به نام Dog ساخته و به شکل زیر اینترفیس Animal را در آن پیاده‌سازی می‌کنیم:

عبارت implements Animal به این معناست که این کلاس اینترفیس Animal را پیاده‌سازی می‌کند. اگر از ایکلیپس یا هر IDE دیگر استفاده می‌کنید با خطایی مبنی بر این‌که باید متدهای اینترفیس Animal را پیاده‌سازی کنید مواجه خواهید شد.

در ایکلیپس با کلیک بر روی ناحیه قرمز مشخص شده در تصویر زیر منویی باز می‌شود. با کلیک بر روی گزینه Add unimplemented methods متدهای اینترفیس Animal به این کلاس اضافه می‌شوند:

ji1

درون متدهای اضافه شده به کلاس یک دستور چاپ متناسب با آن نوشتیم و حال کلاس ما به صورت زیر است:

همانطور که دیدید متدهای eat و walk که در اینترفیس Animal بودند را متناسب با نوع کلاس (سگ) تعریف کردیم. کلاس دیگری به نام Horse می‌نویسیم و اینترفیس Animal را در آن پیاده‌سازی می‌کنیم:

وقتی ایکلیپس متدهای اینترفیس Animal را به کلاسی که نوشتیم اضافه کرد بالای این متدها عبارت @Override را هم قرار داد.

به عباراتی از این قبیل که با @ شروع می‌شوند Annotation گفته می‌شود (که در آینده با آن آشنا خواهید شد)

عبارت @Override به این معنی است که این دو متد Override شده‌اند. با مفهوم Override در قسمت وراثت آشنا شدید. وقتی از اینترفیس متدی را در کلاسی پیاده‌سازی می‌کنید در واقع آن را Override کرده‌اید. البته وجود عبارت @Override الزامی نیست و همین که امضای متد نوشته شده در کلاس با امضای متد موجود در اینترفیس برابر باشد به این معنی است که آن متد Override شده است اما اگر متدی را به قصد Override کردن بنویسید و اشتباها امضای آن متد با امضای متد اصلی تفاوت داشته باشد هیچ اخطاری به شما داده نمی‌شود اما اگر این عبارت را بالای متدی که می‌خواهید Override کنید بنویسید با این کار به کامپایلر می‌گویید که این متد را از یک اینترفیس یا یک کلاس پدر Override کرده‌اید و اگر اشتباها خطایی در نوشتن متد رخ دهد و متد Override شده با متد اصلی هم‌خوانی نداشته باشد کامپایلر به شما اطلاع می‌دهد.

پیاده‌سازی چند اینترفیس

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

به عنوان مثال کلاس زیر دو اینترفیس را پیاده سازی می‌کند:

همانطور که دیدید نام اینترفیس‌هایی که کلاس پیاده‌سازی می‌کند با علامت کاما از هم جدا شده است.

متغیرها در اینترفیس

اینترفیس‌ها علاوه بر متدها می‌توانند شامل متغیرها نیز باشند. متغیرهایی که در یک اینترفیس تعریف می‌شوند همگی public و static و final هستند حتی اگر هنگام تعریف صراحتا این موارد را ذکر نکنیم.

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

مثال: در اینترفیس زیر متغیری به نام PI با مقدار 3.14 داریم. هر کلاسی که این اینترفیس را پیاده‌سازی کند می‌تواند مستقیما به این متغیر دسترسی داشته باشد:

نکته: توجه داشته باشید که متغیرهایی که در یک اینترفیس تعریف می‌کنید با آن اینترفیس مرتبط باشند و مورد استفاده متدهای موجود در آن اینترفیس قرار گیرند.

وراثت در اینترفیس

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

برای فهم بهتر این مطلب به مثال زیر توجه کنید:

سه اینترفیس با نام‌های A و B و C داریم که اینترفیس C از B و اینترفیس B از A ارث بری دارد (البته این اینترفیس‌ها هر کدام در فایل‌های جدا نوشته می‌شوند):

حال اگر کلاسی اینترفیس C را پیاده‌سازی کند باید علاوه بر متدهای اینترفیس C متدهای اینترفیس‌های B و A را نیز Override کند. اگر کلاسی اینترفیس B را پیاده سازی کند فقط باید متدهای اینترفیس B و A را Override کند و دیگر نیازی به Override کردن متدهای اینترفیس C نیست چون C جزو اینترفیس‌های پدر اینترفیس B نمی‌باشد.

متدهای default در اینترفیس

در ابتدا گفتیم که متدهای موجود در یک اینترفیس فاقد بدنه هستند و پیاده‌سازی و تفسیر آن‌ها به عهده کلاسی است که آن اینترفیس را پیاده‌سازی می‌کند اما در نسخه 8 جاوا قابلیت جدیدی به اینترفیس‌ها اضافه شد که به وسیله آن می‌توان در یک اینترفیس متدی داشت که پیاده‌سازی شده باشد. این متدها باید با کلمه کلیدی default تعریف شوند.

نکته مهم این است که اگر یک اینترفیس شامل یک یا چند متد default باشد آنگاه کلاسی که آن اینترفیس را پیاده‌سازی می‌کند مجبور به Override کردن متدهای default آن نیست.

مثال: اینترفیسی به شکل زیر داریم که یک متد default در آن نوشته شده است:

حال کلاسی می‌سازیم که این اینترفیس را پیاده‌سازی کند:

همانطور که گفتیم کلاس A مجبور به Override کردن متد msg نیست اما Override نکردن متد msg به این معنا نیست که این متد در کلاس A وجود ندارد. اگر شیئی از کلاس A ایجاد کنید می‌توانید متد msg را از آن فراخوانی کنید:

نتیجه فراخوانی این متد چاپ عبارت Hello است.

اگر بخواهید یک متد default را Override کنید باید آن را با تعیین‌کننده دسترسی public در کلاس خود بنویسید. مثلا اگر بخواهیم متد msg را Override کنیم به صورت زیر عمل می‌کنیم:

در قسمت وراثت گفتیم که متد Override شده می‌تواند متدی که از آن Override شده را با کلمه super فراخوانی کند. اگر در یک متد default که از یک اینترفیس Override کرده باشیم بخواهیم متد اصلی را فراخوانی کنیم به صورت زیر عمل می‌کنیم:

همانطور که می‌دانید نام اینترفیسی که متد msg در آن قرار دارد Test است.

متدهای استاتیک در اینترفیس

قابلیت دیگری که در نسخه 8 جاوا به اینترفیس‌ها اضافه شد امکان تعریف متدهای استاتیک در اینترفیس است. متدهای استاتیک موجود در یک اینترفیس می‌توانند مستقیما فراخوانی شوند بدون اینکه نیاز به پیاده‌سازی آن اینترفیس باشد.

مثال:

مانند متدهای استاتیکی که در کلاس‌ها تعریف می‌شوند، متدهای استاتیک اینترفیس‌ها را نیز تنها با استفاده از نام اینترفیس و نوشتن نام متد استاتیک فراخوانی می‌کنیم:

هرجا که بخواهید می‌توانید با این روش متد sayHello را فراخوانی کنید بدون نیاز به پیاده‌سازی اینترفیس Test

استفاده از اینترفیس به عنوان نوع داده

می‌توانید متغیری از نوع یک اینترفیس تعریف کنید. مثلا متغیری از نوع اینترفیس Test که قبلا نوشتیم تعریف می‌کنیم:

این متغیر فعلا فقط تعریف شده و مقداری به آن نسبت نداده‌ایم. اما چه چیزی می‌توان در این متغیر قرار داد؟ واضح است که نمی‌توانیم به صورت زیر عمل کنیم:

چون Test یک اینترفیس است نه کلاس که بخواهیم از آن شی بسازیم.

اشیائی را می‌توانیم به این اینترفیس نسبت دهیم که از کلاس‌هایی ساخته شده باشند که این اینترفیس را پیاده‌سازی کرده باشند.

مثال: اینترفیسی به نام Animal با یک متد داریم:

کلاسی به نام Cat می‌سازیم که اینترفیس Animal را پیاده‌سازی می‌کند. این کلاس دو متد دارد که یکی از آن‌ها متد eat از اینترفیس Animal است که آن را Override می‌کنیم:

حال در کلاسی که متد main ما در آن قرار دارد یک متغیر از نوع اینترفیس Animal تعریف می‌کنیم و یک شی از جنس کلاس Cat به آن نسبت می‌دهیم:

حال می‌توانید متد eat که در اینترفیس Animal داشتیم را از متغیر animal فراخوانی کنید:

توجه داشته باشید که چون متغیر animal حاوی آدرس یک شی از جنس Cat است بنابراین متد eat که در کلاس Cat آن را Override کردیم فراخوانی می‌شود.

توجه داشته باشید که اگرچه متغیر animal اکنون به یک شی از کلاس Cat اشاره دارد اما نمی‌توان متد sayHello که در کلاس Cat داشتیم را نمی‌توانیم از متغیر animal فراخوانی کنیم چون متغیر animal از نوع اینترفیس Animal است و در اینترفیس Animal فقط متد eat وجود دارد.

نکته جالب اینجاست که اگرچه نوع متغیر animal تغییر نمی‌کند و همیشه از نوع اینترفیس Animal است اما رفتار آن می‌تواند با توجه به شیئی که به آن نسبت دادیم متفاوت باشد و یکی از مصادیق اصل چندریختی که در ابتدای بحث شی‌گرایی به آن اشاره کردیم همین است.

مثال: کلاسی به نام Dog ایجاد کردیم که اینترفیس Animal را پیاده‌سازی می‌کند:

حال کدهای زیر را در متد main خود می‌نویسیم:

در این کد ابتدا یک شی از کلاس Cat به متغیر animal نسبت داده شده و متد eat فراخوانی شده است. سپس یک شی از کلاس Dog به همان متغیر animal نسبت دادیم و دوباره متد eat را فراخوانی کردیم. نتیجه اجرای برنامه چاپ عبارات زیر است:

Eating fish…

Eating meat…

پس همانطور که دیدید نوع متغیر animal هیچ وقت تغییر نکرد و فقط شیئی که به آن نسبت داده شده بود را تغییر دادیم و به این وسیله شاهد تغییر رفتار این متغیر بودیم.

مصطفی نصیری

دانشجوی نرم افزار هستم و علاقه شدیدی به برنامه نویسی مخصوصا با زبان جاوا دارم! در حال حاضر تمرکزم روی اندرویده. دوست دارم چیزایی که یاد میگیرم رو با بقیه به اشتراک بگذارم :)

همچنین ممکن است دوست داشته باشید ...

خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (1200) ORDER BY t.name ASC

خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('post_tag') AND tr.object_id IN (1200) ORDER BY t.name ASC

خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('hashtags') AND tr.object_id IN (1200) ORDER BY t.name ASC

class="post-1200 post type-post status-publish format-standard has-post-thumbnail hentry">
۲
  • خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('post_format') AND tr.object_id IN (76) ORDER BY t.name ASC

  • خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (76) ORDER BY t.name ASC

    خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('post_tag') AND tr.object_id IN (76) ORDER BY t.name ASC

    خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('hashtags') AND tr.object_id IN (76) ORDER BY t.name ASC

    class="post-76 post type-post status-publish format-standard has-post-thumbnail hentry">
    ۳
  • خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('post_format') AND tr.object_id IN (211) ORDER BY t.name ASC

  • خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (211) ORDER BY t.name ASC

    خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('post_tag') AND tr.object_id IN (211) ORDER BY t.name ASC

    خطای پایگاه‌داده وردپرس: [Got error 28 from storage engine]
    SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('hashtags') AND tr.object_id IN (211) ORDER BY t.name ASC

    class="post-211 post type-post status-publish format-standard has-post-thumbnail hentry">
    ۲

    ۳ واکنش

    1. user گفت:

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

    2. amir گفت:

      عالی بود بخصوص بخش جاوای ۸٫ تشکر

    3. رضا گفت:

      خیلی ممنون مختصر و مفید

    پاسخ دهید

    نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *