הממשק ב-Java הוא אחד מהעקרונות המרכזיים. ממשק Java הוא חלק מהיבט המכניקה של שפת תכנות Java ומשמש המון לא רק ב-JDK, אלא גם בתכנון התכנה ב-Java. רוב הסביבות משתמשות בממשק Java בצורה נרחבת.
ממשק ב-Java
הממשק ב-Java מספק דרך להשיג הסתרה. הממשק ב-Java משמש גם להגדיר את ההסכם לכיתות המיישם. לדוג, נניח שאנו רוצים ליצור תמונה המורכבת מצורופת של יצורים שונים. כאן ניתן ליצור ממשק בשם
Shape
ולהגדיר את כל השיטות של יצורי סוגים שונים יממשו. למטרות פשטות, נשמור רק שתי שיטות – draw()
לשרטט את הצורה ו- getArea()
שתחזיר את שטח הצורה.
דוגמה לממשק ב-Java
לפי הדרישות שלמעלה, הממשק שלנו ייראה כך. Shape.java
package com.journaldev.design;
public interface Shape {
//ניתן להבין מסוגים של הממשק בג'אווה
public String LABLE="Shape";
//שיטות הממשק הן אוטומטית אבסטרקטיות ופומביות
void draw();
double getArea();
}
נקודות חשובות על ממשק ב-Java
-
ממשק
הוא הקוד שמשמש ליצירת ממשק ב-Java. -
אי אפשר ליצור מופע של ממשק ב-Java.
-
הממשק מספק התחברות מוחלטת, בפוסט הקודם למדנו על מחלקות אבסטרקטיות ב-Java לספק התחברות אבסטרקטית אך יש באפשרות להכיל בהן מימושי שיטות, בעוד בממשק אין.
-
ממשקים לא יכולים לכלול בנאי מכיוון שאי אפשר ליצור מופעים שלהם, וכמו כן לא יכולים לכלול שיטה עם גוף.
-
לפי ברירת המחדל כל תכונה של ממשק היא ציבורית, סטטית ו־סופית, לכן אין צורך לספק מודיפיקטורי גישה לתכונות, אך אם נעשה זאת, המהדר לא יתלונן על כך גם.
-
לפי ברירת המחדל מתודות הממשק הן באופן משולי מופשטות ו־ציבוריות, וזה קובע מובן מאליו מאחר והמתודה אינה מכילה גוף ובכך תתי המחלקות יכולות לספק את המימוש של המתודה.
-
ממשק לא יכול להרחיב כל קבוצה אך הוא יכול להרחיב ממשק אחר.
public interface Shape extends Cloneable{}
הוא דוגמה לממשק המרחיב ממשק אחר. בעצם גם ב־Java מספקת ירושה מרובה בממשקים, המשמעות היא שממשק יכול להרחיב מספר ממשקים. -
מילת המפתח
implements
משמשת על ידי מחלקות ליישום ממשק. -
מחלקה שמיישמת ממשק חייבת לספק מימוש לכל השיטות שלו אלא אם כן זו מחלקה מופשטת. לדוגמה, אנו יכולים ליישם את הממשק למחלקה מופשטת כזו:
ShapeAbs.java
package com.journaldev.design; public abstract class ShapeAbs implements Shape { @Override public double getArea() { // TODO Auto-generated method stub return 0; } }
-
תמיד עלינו לנסות לכתוב תוכניות במונחי ממשקים במקום במונחי מימושים כך שנדע מראש שמחלקות המימוש תמיד יספקו את המימוש ובעתיד אם יגיע מימוש טוב יותר, נוכל להחליף לו בקלות.
דוגמת יישום ממשק ב-Java
כעת נראה כמה דוגמאות ליישום של הממשק שלנו Shape ב-Java. Circle.java
package com.journaldev.design;
public class Circle implements Shape {
private double radius;
public Circle(double r){
this.radius = r;
}
@Override
public void draw() {
System.out.println("Drawing Circle");
}
@Override
public double getArea(){
return Math.PI*this.radius*this.radius;
}
public double getRadius(){
return this.radius;
}
}
שים לב שהכיתה Circle מימשה את כל המתודות שהוגדרו בממשק ויש לה גם מתודות משלה כמו getRadius()
. מימושי הממשק יכולים להכיל סוגים מרובים של בנאים. בואו נראה מימוש נוסף לממשק Shape. Rectangle.java
package com.journaldev.design;
public class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double w, double h){
this.width=w;
this.height=h;
}
@Override
public void draw() {
System.out.println("Drawing Rectangle");
}
@Override
public double getArea() {
return this.height*this.width;
}
}
שים לב לשימוש באנוטציית override, למד על אנוטציות בג'אווה ולמה תמיד כדאי להשתמש באנוטציית override כשמדרסים מתודה בג'אווה. הנה תוכנית בדיקה שמראה איך לתכנת במונחים של ממשקים ולא מימושים. ShapeTest.java
package com.journaldev.design;
public class ShapeTest {
public static void main(String[] args) {
//תכנות עבור ממשקים לא מימושים
Shape shape = new Circle(10);
shape.draw();
System.out.println("Area="+shape.getArea());
//מעבר ממימוש אחד לאחר בקלות
shape=new Rectangle(10,10);
shape.draw();
System.out.println("Area="+shape.getArea());
}
}
פלט של תוכנית הדוגמה של ממשק הג'אווה הנ"ל הוא:
Drawing Circle
Area=314.1592653589793
Drawing Rectangle
Area=100.0
יתרונות ממשק הג'אווה
- הממשק מספק חוזה עבור כל כיתות המימוש, ולכן זה טוב לתכנת במונחים של ממשקים מכיוון שכיתות המימוש לא יכולות להסיר את המתודות שאנו משתמשים בהן.
- הממשקים טובים כנקודת התחלה להגדרת סוג ויצירת היררכיה עליונה בקוד שלנו.
- מאחר וכיתה ב-Java יכולה ליישם מספר רב של ממשקים, כדאי להשתמש בממשקים כמחלקה אב ברוב המקרים.
חסרונות ממשק Java
אף שהממשקים מספקים המון יתרונות, יש להם גם חסרונות.
-
עלינו לבחור בזהירות את שיטות הממשק בעת עיצוב הפרויקט שלנו, מכיוון שאין לנו אפשרות להוסיף או להסיר שיטות מהממשק במועד מאוחר יותר. זה יגרום לשגיאת ההדמיה עבור כל המחלקות המיישמות. לפעמים זה יביא למצב בו יש לנו המון ממשקים המרחיבים את ממשק הבסיס בקוד שלנו, דבר שמקשה על התחזקות.
-
אם לכיתות המימוש יש שיטות משלהן, אין באפשרותנו להשתמש בהן ישירות בקוד שלנו מכיוון שסוג האובייקט הוא ממשק שאין לו את השיטות ההן. לדוגמה, בקוד למעלה נקבל שגיאת קומפילציה עבור קוד
shape.getRadius()
. כדי להתגבר על זאת, ניתן להשתמש ב־המרת סוגים ולהשתמש בשיטה בצורה הבאה:Circle c = (Circle) shape; c.getRadius();
אף על פי שיש להמרת סוגים בין מחלקות את החסרונות שלה.
זהו כל מה שיש לי להציע לך בנושא הממשק בג'אווה. מכיוון שאנו משתמשים בממשק ג'אווה הרבה, חשוב להיות מודעים לתכונותיו. ודאו שאתם משתמשים בממשקים בעיצוב המערכת וכחוזה בין הלקוח לכיתות המימוש שמיישמות את הממשקים. עדכון: ג'אווה 8 שינתה את ההגדרה של ממשקים עם הכנסת שיטות ברירת מחדל ושיטות סטטיות למימוש. לפרטים נוספים, עיינו ב־ממשק ג'אווה 8.
Source:
https://www.digitalocean.com/community/tutorials/interface-in-java