1

Ich versuche, die folgend zu tun:Abstrakte Klasse und Polymorphismus Ausgabe

public abstract class MyBaseFragment extends Fragment { 
    private FloatingActionButton fab; 

    protected void initFab(View contentView, int resourceId) { 
     fab = (FloatingActionButton) contentView.findViewById(resourceId); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       launchDetailsDialogFragment(new Animal()); 
      } 
     }); 
    } 

    private void launchDetailsDialogFragment(Animal animal) { 
     //... 
    } 
} 

Der entscheidende Punkt hier ist, um die Linie darum, ein neues Tier.

Ich habe verschiedene Arten von Tieren - Katze, Hund, etc. Die Seite über Katzen, die Seite über Hunde, etc, sie alle erweitern MyBaseFragment. Wenn Sie auf der Cat-Seite auf den FloatingActionButton klicken, wird eine Funktion ausgeführt, die ein neues Cat() an das DialogFragment übergibt, wo Sie die Details bearbeiten können. Gleiches gilt für Hunde. Aber jedes Detail von DialogFragment ist etwas anders, da Katzen und Hunde unterschiedliche Eigenschaften voneinander haben, obwohl sie beide Tiere sind.

Allerdings kann ich hier nicht Polymorphie anwenden. Im Moment weiß MyBaseFragment, dass es ein neues Tier erstellen wird, aber ich möchte, dass es eine neue Katze oder einen neuen Hund usw. macht, je nachdem, wo ich das Basisfragment ausweite.

Wie mache ich das?

+0

Ich gehe davon aus, dass die ausdehnenden Klassen wissen, welches Tier zu verwenden ist, also, wenn sie initFab() aufrufen, warum geben sie nicht das erforderliche Tier weiter? – Ash

+0

@AshFrench Die Cat-Seite zum Beispiel hat eine Liste von Katzen. Sie klicken auf eine Katze, Sie können ihre Details bearbeiten (initialisiert von einer Datenbank). Wenn Sie jedoch auf die Schaltfläche "Hinzufügen" klicken, wird der gleiche Detaildialog angezeigt, nur mit einem neuen/neuen Cat-Objekt (alle Felder sind leer). Ich versuche, eine abstrakte Klasse zu verwenden, um Features zu implementieren, die allen Seiten gemeinsam sind, aber es muss immer noch in der Lage sein, einzigartige Dinge abhängig von der Situation zu starten. –

+0

Nun haben Sie überlegt, eine abstrakte Methode zu haben, die ein Animal zurückgibt, das jede Klasse implementiert, dann könnten Sie 'launchDetailsDialogFragment (getNewAnimal())' – Ash

Antwort

1

Nur die Methode aufgerufen machen abstrakt ad jede konkrete Klasse in einer eigenen Implementierung ausfüllen

public abstract class MyBaseFragment extends Fragment { 
    private FloatingActionButton fab; 

    protected void initFab(View contentView, int resourceId) { 
     fab = (FloatingActionButton) contentView.findViewById(resourceId); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       launchDetailsDialogFragment(); 
      } 
     }); 
    } 

    protected abstract void launchDetailsDialogFragment(); 
} 
+0

Gibt es einen Unterschied zwischen sagen 'private void launchDetailsDialogFragment()' und 'private abstrakte void launchDetailsDialogFragment();'? –

+0

Wenn Sie abstrakt verwenden, können Sie keine Standardimplementierung haben. Ohne Abstrakt kannst du. –

+0

Aber wenn Sie nur 'private void launchDetailsDialogFragment() eingeben;' der Compiler sagt, es fehlt ein Körper –

0

Make launchDetailsDialogFragment Zusammenfassung:

protected abstract void launchDetailsDialogFragment(); 

Und es in den Unterklassen implementieren, wie Sie wollen.

+0

Gibt es einen Unterschied zwischen 'protected void launchDetailsDialogFragment()' und 'protected abstract void launchDetailsDialogFragment();'? Oder privat statt geschützt? –

+0

@ArukaJ ja. 'abstract' Schlüsselwort bedeutet, dass diese Funktion ihre Implementierung an die Klassen überträgt, die Ihre Basisklasse erweitern. –

+0

'abstract' fordert alle untergeordneten Klassen auf, diese Methode zu implementieren. Ohne "abstrakt" könnten sie es einfach nicht überschreiben und es leer lassen. – m0skit0

0

Sie müssen die MyBaseFragment-spezifischen Implementierungen entscheiden lassen, welches Tier beim Starten des Detailfragments instanziiert wird. Soweit ich das verstehe, weiß die MyBaseFragment-abstrakte Klasse nur, dass es ein Detailfragment geben sollte, das auf Klickereignis von fabbutton gestartet werden sollte. Es ist nicht bekannt, die Art des Fragments, das gestartet werden sollte. Dies würde durch die spezifische Implementierung des Fragments entschieden werden. Markieren Sie also die Methode, die für das Erstellen des Detailfragments als geschütztes Abstrakt verantwortlich ist, und überschreiben Sie sie in den spezifischen Implementierungen, um das spezifische Tier zu erstellen.