java:interface_modification

Μεταβάλλοντας ένα υφιστάμενο Interface

Κάποιες φορές στον προγραμματισμό εμφανίζεται η ανάγκη να μεταβάλλουμε ένα υφιστάμενο interface ή να το επεκτείνουμε. Το πρόβλημα σε αυτές τις περιπτώσεις είναι ότι οι κλάσεις που υλοποιούν το συγκεκριμένο interface με την προσθήκη ή αλλαγή των υφιστάμενων μεθόδων θα πάψουν να το υλοποιούν. Επομένως μία μονομερής αλλαγή του interface δεν είναι εφικτή. Παρόλα αυτά υπάρχουν δύο εναλλακτικές που μπορούν να μας καλύψουν.

1η εναλλακτική: Να υλοποιήσουμε ένα νέο interface με παραπλήσιο όνομα, το οποίο να αποτελέσει τη νέα έκδοση του υφιστάμενου interface.

public interface DoIt {
 
   void doSomething(int i, double x);
   int doSomethingElse(String s);
}
 
public interface DoItPlus extends DoIt {
 
   boolean didItWork(int i, double x, String s);
 
}

2η εναλλακτική: Να υλοποιήσουμε μία ή περισσότερες default μέθοδους (όσες είναι και οι αλλαγές ή οι προσθήκες) μέσα στο υφιστάμενο interface, ώστε ακόμη και εάν οι κλάσεις που υλοποιούν το συγκεκριμένο interface δεν υλοποιούν τις νέες μεθόδους, οι υλοποιήσεις στις κλάσεις αυτές να γίνονται από το ίδιο το interface.

public interface DoIt {
 
   void doSomething(int i, double x);
   int doSomethingElse(String s);
   default boolean didItWork(int i, double x, String s) {
       // Method body 
   }  
}

Default μέθοδοι

Παρατήρηση: Οι default μέθοδοι στην Java υλοποιούνται στην έκδοση 8 της γλώσσας. Μεταγλωττιστές που ανήκουν σε προηγούμενες εκδόσεις αδυνατούν να μεταγλωττίσουν τον παρακάτω κώδικά.

Ας θεωρήσουμε το παρακάτω υποθετικό interface

StringInverter.java
    public interface StringInverter {
        /** inverts a string
         */
        String invert(String str);
    }

Ας υποθέσουμε τώρα ότι η κλάση MyString υλοποιεί το παραπάνω interface.

MyString.java
import java.lang.*;
public class MyString implements StringInverter {
    String invert(String str) {
        StringBuffer strb = new StringBuffer(str);
        return strb.reverse().toString();
    }
}

Αν υποθέσουμε ότι το αρχικό interface αλλάζει στο παρακάτω

StringInverter.java
    public interface StringInverter {
        /** inverts a string
         */
        String invert(String str);
        /** splits a string in half and inverts
         * the two parts.
         */
        String invertHalf(String str);
    }

Τώρα η κλάση MyString δεν υλοποιεί πλέον το αρχικό interface. Αυτό μπορεί να συνεχίσει να υλοποιείται εάν η νέα μέθοδος έχει μία default υλοποίηση μέσα στο interface όπως παρακάτω.

StringInverter.java
    public interface StringInverter {
        /* inverts a string
         */
        String invert(String str);
        /* splits a string in half and inverts
         * the two parts
         */
        default String invertHalf(String str) {
           int len = str.length();
           String str1 = str.substring(0, len/2);
           String str2 = str.substring(len/2, len);
           return str2+str1;
        }
    }

Στατικές μέθοδοι

Εκτός από default μεθόδους ένα interface μπορεί να περιέχει και στατικές (static) μεθόδους. Οι στατικές μέθοδοι ορίζονται σε αναλογία με τις στατικές μεθόδους των κλάσεων και ουσιαστικά ανήκουν στις κλάσεις που θα υλοποιήσουν το interface και όχι στα αντικείμενα. Ένα παράδειγμα μπορείτε να δείτε παρακάτω.

StringInverter.java
    public interface StringInverter {
        /** inverts a string
         */
        String invert(String str);
        /** splits a string in half and inverts
         * the two parts
         */
        default String invertHalf(String str) {
           int len = str.length();
           String str1 = str.substring(0, len/2);
           String str2 = str.substring(len/2, len);
           return str2+str1;
        }
 
        /** removes character at index from String str
         * and returns the new String.
         */
        static String removeChar(String str, int index) {
            if( str.length()-1 < index ) {
                return str;
            }
            String str1 = str.substring(0,index);
            String str2;
            if( str.length() >= index-1 ) {
                str2 = str.substring(index+1);
            }
            else {
                str2 = new String("");
            }
            return str1+str2;
 
        }
    }

Παρατήρηση: Οι static μέθοδοι στην Java υλοποιούνται στην έκδοση 8 της γλώσσας. Μεταγλωττιστές που ανήκουν σε προηγούμενες εκδόσεις αδυνατούν να μεταγλωττίσουν τον παραπάνω κώδικά.

java/interface_modification.txt · Last modified: 2018/03/20 21:24 by gthanos