2016-04-22 10 views
-2

Ich bin mir nicht sicher, wie ich meine Frage beantworten soll. Es geht um Android kann Instantiate Interface. Ich versuche in C# zu tun. Jetzt bin ich mir ziemlich sicher, dass die Regeln sowohl für Java als auch für C# so sind, dass Sie keine Instanz von Abstrakt und Interface erstellen können.C# vs JAVA Instanz der Schnittstelle

Aber ich würde wirklich gerne wissen, wie Android diese Praxis macht.

In Android können Sie dies tun.

public interface Checkme{ 
    void Test(); 
    void Test2(); 
} 


public void myFunc(Checkme my){ 
    //do something 
} 

// Now this is the actual usage. 

public void Start(){ 

    myFunc(new Checkme(){ 
     @Override 
     public void Test() 
     { 


     } 
     @Override 
     public void Test2() 
     { 


     } 
    }); 

} 

Eigentlich, wenn Sie auf new Checkme() Enter drücken, wird automatisch die außer Kraft setzen Methoden der Schnittstelle erhalten. Wie die automatische Implementierungsmethode einer Schnittstelle in C#.

Ich hoffe meine Frage ergibt Sinn.

+0

Ich verstehe nicht, was Sie fragen. Sprechen Sie über eine Code-Vervollständigungsfunktion einer IDE? –

+2

Dies wird eine anonyme Klasse genannt. https://docs.oracle.com/javase/tutorial/java/javaOO/anonymyclasses.html – dharms

+0

Nein, nicht über die Code-Vervollständigung. In android. Dies ist eine sehr übliche Praxis. Zum Beispiel 'swipeRefreshLayout.setOnRefreshListener (new SwipyRefreshLayout.OnRefreshListener() {' Wir haben ein neues Interface.OnRefreshListener instanziiert – Aizen

Antwort

5

C# unterstützt nicht anonym automatisch implementierte Schnittstellen, weil es Delegierten hat:

public void Foo(Func<string> func, Action action) {} 

// call it somewhere: 
instance.Foo(() => "hello world",() => Console.WriteLine("hello world")); 

Mit Delegierten können Sie die Lücke füllen, und es kann noch leistungsfähiger sein als Schnittstellen mit anonymen Klassen implementieren.

Learn more about delegates.

+0

Ich weiß über Delegaten, aber nicht so tief hinein Dies kann ich für einen neuen Strukturansatz für das Codieren verwenden.Es gibt viele Möglichkeiten, wie wir Delegierte erreichen können, aber auf meiner Ebene versuche ich, nach der Verwendung von solchen Begriffen zu suchen, die langweiliger sind, als von Nicht-Delegierten-Ansatz Danke für den Link Matias – Aizen

+1

Ein Delegat entspricht dem Java 8 Lambda-Ausdruck, entspricht aber nicht den anonymen Klassen für Interfaces und abstrakten Klassen mit mehr als einer abstrakten Methode – Andreas

+0

@Andreas Ich habe nie gesagt, dass es das gleiche ist. Meine Antwort sagt dem OP, dass C# dieses Feature nicht unterstützt, aber es stellt Delegierte statt. Ich glaube, dass ich mich nicht irre, oder ?: D –

0

meinst du sowas?

pulic interface Foo{ 
    void DoSomething(); 
} 

public class Bar : Foo { 
    public void DoSomething() { 
     //logic here 
    } 
} 
+0

'override' ??????? –

+0

Umm nein, das ist Vererbung der Vertrag meine Frage ist über das Erstellen einer Instanz davon. Sie müssen virtuell hinzufügen, wenn Sie übrigens übergehen müssen. – Aizen

+0

@Matias: natürlich hast du vollkommen recht. Behoben. Denken Sie daran: Lesen Sie immer zweimal, was Sie geschrieben haben :) – Malte

0
myFunc(new Checkme(){ 
    @Override 
    public void Test() 
    { 


    } 
    @Override 
    public void Test2() 
    { 


    } 
}); 

Sie vorbei in myFunc() etwas, das eine anonyme Klasse genannt wird. Wenn es "new Checkme() {....}" sagt, definiert es eine anonyme Implementierung der Checkme-Schnittstelle. Es ist also keine Instanz der Schnittstelle selbst, sondern nur eine Instanz eines Typs, der sie implementiert.

+1

Ein Lambda ist keine anonyme Klasse oder umgekehrt.Ein Lambda kann als Alternative zu einer anonymen Klasse für jede Klasse/Schnittstelle mit genau einer abstrakten Methode verwendet werden. Lambdas kann nicht verwendet werden, wenn mehr als eine Methode abstrakt ist, wie es hier der Fall ist. – Andreas

+0

Mein Fehler, wird Lambda bearbeiten. Mir war nicht bewusst, dass es einen formalen Unterschied zwischen den beiden gab. –

1

Wenn ich richtig verstehe, definieren Sie eine Klasse, die eine Schnittstelle implementiert, und wenn Sie angeben, dass die Klasse eine Schnittstelle implementiert, möchten Sie, dass sie die Methoden und Eigenschaften der Schnittstelle automatisch hinzufügt.

Wenn Sie habe dies erklärt:

public interface ISomeInterface 
{ 
    void DoSomething(); 
} 

Und dann fügen Sie eine Klasse:

public class MyClass : ISomeInterface // <-- right-click 
{ 
} 

der rechten Maustaste auf die Schnittstelle und Visual Studio wird Ihnen eine Option, um die Schnittstelle zu implementieren und fügt alle Mitglieder der Schnittstelle der Klasse hinzu.

+0

Das ist korrekt Scott Hannen, eigentlich können Sie STRG + verwenden. wenn Sie kurze Abkürzungen wünschen. Aber meine Frage betrifft das Erstellen einer Instanz der Schnittstelle. Auf Ihre Antwort vererben Sie es. Es tut mir sehr leid, wenn meine Frage Sie zu dieser Antwort verführt. – Aizen

4

Dies ist ein Anonymous Class:

public void Start(){ 
    myFunc(new Checkme() { 
     @Override 
     public void Test() { 
     } 
     @Override 
     public void Test2() { 
     } 
    }); 
} 

Eine anonyme Klasse eine unbenannte Klasse inline implementiert ist.

Sie hätten es auch mit einem Local Class tun können, aber diese sind selten in freier Wildbahn zu sehen.

public void Start(){ 
    class LocalCheckme implements Checkme { 
     @Override 
     public void Test() { 
     } 
     @Override 
     public void Test2() { 
     } 
    } 
    myFunc(new LocalCheckme()); 
} 

Diese beide haben den Vorteil, dass sie Verfahren Parameter und Variablen direkt verwenden können, solange sie (effektiv) endgültig.

Als eine dritte Option könnten Sie es mit einem Inner Class tun.

private class InnerCheckme implements Checkme { 
    @Override 
    public void Test() { 
    } 
    @Override 
    public void Test2() { 
    } 
} 
public void Start(){ 
    myFunc(new InnerCheckme()); 
} 

Eine innere Klasse kann nicht Methode Variablen zugreifen (natürlich, weil es außerhalb der Methode ist), kann aber durch verschiedene Methoden verwendet werden.

Alle lokalen Werte aus der Methode können jedoch in den Konstruktor übergeben und als Felder der inneren Klasse gespeichert werden, um das gleiche Verhalten zu erhalten. Benötigt nur ein bisschen mehr Code. Wenn die innere Klasse keinen Zugriff auf Felder der äußeren Klasse benötigt, kann sie mit static deklariert werden.

Also, alle 3 Möglichkeiten über eine sehr ähnliche. Die ersten beiden sind nur Java Shorthands für den dritten, d. H. syntaktischen Zucker, implementiert durch den Compiler.

C# kann die dritte, also tun Sie es nur so für C#.

Natürlich, wenn die Schnittstelle nur eine Methode hat, unter Verwendung eines Java Lambda oder C# Delegierten ist viel einfacher als Anonymous/Local/Innere Klassen.