Внутренний класс внутри интерфейса, реализующий тот же интерфейс, что мы достигаем этим?
Мой вопрос:
Я смотрел исходный код TextWatcher, и я не понял эту концепцию.
Какова была цель продления до NoCopySpan?
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
NoCopySpan
- это просто маркерный интерфейс. Согласно javadoc, он используется для изменения поведения процедуры копирования объектов Spanned
(он зависит от типа компонентов). Например, android.text.SpannableStringBuilder
использует такую информацию наследования, чтобы пропускать скобки при построении.
Этот подход имеет некоторые недостатки, но все же довольно распространен. Причина существования класса Concrete
заключается в том, чтобы обеспечить удобный способ построения на основе op-op (или по умолчанию) реализации интерфейса NoCopySpan
.
Ответ 2
Что касается спецификации интерфейса NoCopyScan
, внутренний класс, реализующий один и тот же интерфейс, может использоваться как реализация/представление по умолчанию интерфейса вне его.
Внутренний класс в интерфейсе неявно рассматривается как статический внутренний класс. Мы можем создать экземпляр внутреннего класса интерфейса, как статический внутренний класс, и использовать NoCopyScan
для использования. Пожалуйста, найдите простой пример, иллюстрирующий использование реализации интерфейса по умолчанию с помощью внутреннего класса ниже:
/* 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();
}
}