У чым розніца паміж інтэрфейсам і прамым доступам ад класа?


адказ 1:

Ідэя інтэрфейсу заключаецца ў тым, што мноства розных класаў патрабуюць сумяшчальнасці з чымсьці.

Добра, гэта неяк расплывіста, паглядзім на прыклад:

Выкажам здагадку, у вас працяглы працэс (напрыклад, рэзервовае капіраванне на працягу ночы ці нешта іншае), і вы хочаце апавясціць людзей аб працэсе. Для гэтага я ствараю інтэрфейс пад назвай "INotifyTaskCompleted".

публічны інтэрфейс INotifyTaskCompleted {void notifyTaskCompleted (); }}

Добра, таму ў нас ёсць інтэрфейс з метадам пад назвай "notifyTaskCompleted".

Цяпер я магу зрабіць такі клас:

public class NotifyViaSMS рэалізуе INotifyTaskCompleted {public void notifyTaskCompleted () {// Blah-код для адпраўкі SMS. }}

Добра, у мяне ёсць клас, які можа паведамляць карыстальнікаў праз SMS, і я ўказаў, што клас рэалізуе INotifyTaskCompleted.

Калі вы ўказваеце, што клас рэалізуе інтэрфейс, вы павінны рэалізаваць усе метады ў інтэрфейсе. Гэта дамова для класа сказаць: "Я рэалізую гэты інтэрфейс". Калі вы не рэалізуеце метады (пры жаданні яны могуць быць пустымі), код не будзе кампілявацца.

Добра, што, калі карыстальнікі больш не хочуць атрымліваць SMS, а замест гэтага Slack? Цяпер мы рэалізуем яшчэ адзін клас накшталт гэтага:

public class NotifyViaSlack рэалізуе INotifyTaskCompleted {public void notifyTaskCompleted () {// Blah-код для адпраўкі слабых паведамленняў. }}

Такім чынам, клас SMS і Slack маюць вельмі розную рэалізацыю, але абодва рэалізуюць адзін і той жа інтэрфейс. Праз інтэрфейс яны, па сутнасці, заяўляюць, што могуць зрабіць працу INotifyTaskComplete, але наколькі дакладна яны робяць гэтую працу, не важна.

Ідэя заключаецца ў тым, што:

  1. Вы можаце стварыць інтэрфейс, даць яго распрацоўніку і сказаць: "Калі ласка, рэалізавайце гэта для мяне". Гэта выдатны спосаб падзяліць буйныя праекты. У вас няма беспарадак класаў з узаемазалежнасцямі, вы дакладна вызначылі інтэрфейсы, і пакуль класы рэалізуюць гэтыя інтэрфейсы, усё працуе правільна. Гэта дазваляе лёгка рэарганізаваць код, а не глядзець на масавы клас і думаць, што я мушу напісаць яго яшчэ раз. Вы паглядзіце інтэрфейс, які вам трэба рэалізаваць, які, як правіла, будзе значна меншым, і вам зразумела, што вам трэба рэалізаваць, а што вам не трэба.

Вярнуцца да прыкладу SMS / Slack: Ідэя заключаецца ў тым, што ў нас ёсць даўно выкананая задача рэзервовага капіявання. Гэтая задача можа мець такі метад, як:

public void setTaskNotifier (INotifyTaskCompleted taskComplete);

Каб клас бяспекі можна было перадаць у клас SMS або клас Slack і не ведае розніцы, ён проста выклікае метад notifyTaskCompleted () класа, які быў перададзены яму.

Гэта азначае, што праз некалькі гадоў ніхто больш не будзе карыстацца SMS або Slack. Вы можаце рэалізаваць іншы клас для іншай сістэмы абмену паведамленнямі. Пакуль вы рэалізуеце INotifyTaskCompleted, вы можаце перадаць яго ў клас абароны, і ён не будзе ведаць розніцы.

Інтэрфейсы выдатна падыходзяць для выкарыстання кода для шматразовага выкарыстання і менш узаемазвязанага.


адказ 2:

Каб цытаваць дакументацыю на Java:

"Інтэрфейсы складаюць кантракт паміж класам і знешнім светам, і гэты кантракт выконваецца кампілятарам пры яго стварэнні."

Калі клас аб'яўляецца інтэрфейсам, ён павінен утрымліваць усе метады, абяцаныя вызначаным інтэрфейсам, напрыклад.

Налада інтэрфейсу:

Монстар інтэрфейса {// магчыма метад нацэльвання гульцоў на несапраўдны targetPlayer (int playerId); // Усе монстры ў вашай гульні могуць мець метад лячэння. void healSelf (int newValue); // Магчыма, вашы монстры напалоханы і запусцяць пустую ўцёку (); }}

Цяпер вы вызначаеце клас монстраў, які вы:

Клас SpookyGhost рэалізуе Monster {int health = 100; // таму што гэта рэалізуе інтэрфейс (монстар) // ваш код не будзе скампіляваны без абвешчаных там метадаў // (вы ўсё яшчэ можаце дадаць метады, якія не абяцаны вашым інтэрфейсам) void targetPlayer (int playerId) {// code рэчы} void healSelf (int newValue) {// код, каб вылечыць вакол newValue} void runAway () {// метад, каб монстры ўцякалі}}

Перавагай з'яўляецца тое, што вы можаце ўсталяваць інтэрфейс, каб пераканацца, што кожны клас, які рэалізуе яго, імкнецца да паказаных вамі метадаў. Гэта можа забяспечыць паслядоўнасць і надзейнасць.

Для таго, каб пачаць, з цытаты з дакументаў Java:

"Калі ваш клас прэтэндуе на рэалізацыю інтэрфейсу, усе метады, вызначаныя гэтым інтэрфейсам, павінны з'явіцца ў зыходным кодзе, перш чым клас можа быць паспяхова скапіляваны."