2016-08-02 11 views
23

Ich schaute auf den Quellcode von TextWatcher und ich habe das Konzept hier nicht erhalten Welchen Sinn hatte die Erweiterung auf NoCopySpan?Innere Klasse innerhalb einer Schnittstelle, die dieselbe Schnittstelle implementiert, was erreichen wir dadurch?

TextWatcher.java:

public interface TextWatcher extends NoCopySpan { 
    public void beforeTextChanged(CharSequence s, int start, int count, int after); 
    public void onTextChanged(CharSequence s, int start, int before, int count); 
    public void afterTextChanged(Editable s); 
} 

NoCopySpan.java:

package android.text; 

/** 
* This interface should be added to a span object that should not be copied into a new Spanned when performing a slice or copy operation on the original Spanned it was placed in. 
*/ 
public interface NoCopySpan { 
    /** 
    * Convenience equivalent for when you would just want a new Object() for 
    * a span but want it to be no-copy. Use this instead. 
    */ 
    public class Concrete implements NoCopySpan {} 
} 
+1

Ich denke, ist nur eine '' 'helper''' Klasse, die verwendet werden soll, wenn Sie brauchen, um eine Instanz von '' 'NoCopySpan''' übergeben. – danypata

Antwort

12

NoCopySpan ist nur ein marker interface. Laut javadoc wird es verwendet, um das Verhalten der Kopierroutine von Spanned Objekten zu modifizieren (es hängt vom Typ der Komponenten ab). Zum Beispiel verwendet android.text.SpannableStringBuilder solche Vererbungsinformationen, um das Kopieren von Bereichen nach der Konstruktion zu überspringen.

Dieser Ansatz hat einige Nachteile, aber immer noch ziemlich häufig. Der Grund der Concrete Klassenexistenz ist es, eine bequeme Möglichkeit zu bieten, eine On-Op-Dummy (oder Standard) -Realisierung der NoCopySpan Schnittstelle zu konstruieren.

+0

Beliebige Referenz oder Erklärung für: "Verhalten der Kopierroutine von übergreifenden Objekten ändern" UND "bieten eine bequeme Möglichkeit, eine Dummy-Implementierung (oder Standard-Realisierung) der NoCopySpan-Schnittstelle zu erstellen." –

+0

@HishamMuneer Ich bin kein Android-Experte, aber es gibt ein Beispiel, das Sie in Android-Quellcode finden können, dh [android.text.SpannableStringBuilder] (http://grepcode.com/file/repository.grepcode.com/java/ext /com.google.android/android/4.4.4_r1/android/text/SpannableStringBuilder.java#75). Ich werde meine Antwort ändern – vsminkov

+0

@HishamMuneer hm ... Ich kann keine Beispiele für die neuesten 5.1.1 Android finden. Es scheint, dass 'NoCopySpan' immer noch für Abwärtskompatibilität verwendet wird oder bald veraltet sein könnte. – vsminkov

0

Wie für die Spezifikation der Schnittstelle NoCopyScan, die innere Klasse, die die gleiche Schnittstelle implementieren kann als Standardimplementierung/Darstellung der Schnittstelle überall außerhalb verwendet werden.

Ein inner class in an interface wird implizit als statische innere Klasse behandelt. Wir können die innere Klasse der Schnittstelle wie eine statische innere Klasse instanziieren und NoCopyScan verwenden. Hier finden Sie ein einfaches Beispiel die Verwendung von Standard-Implementierung der Schnittstelle mit Hilfe der inneren Klasse zeigt unter:

/* package whatever; // don't place package name! */ 

import java.util.*; 
import java.lang.*; 
import java.io.*; 

/* Name of the class has to be "Main" only if the class is public. */ 
interface NoCopy{ 

public void doStuff(); 

public class Conc {    //Inner Class 
    public int retStuff(){ 
     return 2; 
    } 
    } 




// public void doStuff(){ 
//  System.out.println("Overriding in inner class"); 
// } 
} 


class ConcOut { 

    public int returnStuff(){ 
     return 5; 
    } 


    public void doStuff(){ 
     NoCopy.Conc innerObj = new NoCopy.Conc(); //Instantiating inner class 
     //NoCopy.Conc innerObj = (new ConcOut()).new Conc(); 

     System.out.println("overriding in outside class ConcOut "+ innerObj.retStuff());        // calling the method of inner class 
    } 
} 

class Ideone 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     // your code goes here 
     ConcOut conObj = new ConcOut(); 
     conObj.doStuff(); 
     //ConcOut.Conc concInner = conObj.new Conc(); 

    } 
}