Anfängerprobleme mit Vererbung

minzee

Bekanntes Mitglied
Hi :)

Ich habe 2 Probleme mit einem Programm.

1) Konstruktor

Ich habe eine Klasse Neuron, die einen Konstruktor hat, dem ein Parameter übergeben wird.

Von dieser Klasse erben die Klassen InputNeuron und LearningNeuron. Von LearningNeuron erben HiddenNeuron und OutputNeuron. All diesen Klassen muss ich scheinbar auch wieder so einen Konstruktor spendieren. Ich erspare mir keine Schreibarbeit. Genauso gut könnte ich auch den Konstruktor in der Klasse Neuron wieder rausnehmen.

Java:
abstract class Neuron
{
   public int id;
   Neuron(int id)
   {
      this.id = id;
   }
}

interface UpdateableNeuron
{
}

class InputNeuron extends Neuron implements UpdateableNeuron
{
   InputNeuron(int id)
   {
      super(id);
   }
}

abstract class LearningNeuron extends Neuron
{
   LearningNeuron(int id)
   {
      super(id);
   }
}
  
class HiddenNeuron extends LearningNeuron implements UpdateableNeuron
{
   HiddenNeuron(int id)
   {
      super(id);
   }
}

class OutputNeuron extends LearningNeuron
{
   OutputNeuron(int id)
   {
      super(id);
   }
}
Kann man das nicht irgendwie schöner programmieren?
 

Khal Drogo

Bekanntes Mitglied
Guten Abend,

sieht für mich nicht unschön aus, wüsste auch nicht, wie man das verkürzen können sollte.
Es mag vielleicht etwas komisch aussehen, wenn in den Klassen außer Konstruktor nichts drin steht, aber spätestens wenn weiterer Code dazukommt, fällt das gar nicht mehr auf (meiner Meinung nach).

Mit freundlichen Grüßen
Xelsarion
 

minzee

Bekanntes Mitglied
Ich kann mir irgendwie nicht vorstellen, dass das im Sinne des Erfinders ist. Vererbung soll helfen, Code zu reduzieren. Statt dessen habe ich jetzt aber gleich ein paar mal genau das Gleiche dort stehen. Ohne dass ich dadurch irgendwie einen Mehrwert hätte.
 

minzee

Bekanntes Mitglied
Nachdem ich damit wohl leben muss, jetzt zum zweiten Problem, was ich leider noch habe.

2) Eigenschaften in Interfaces

Java:
abstract class Neuron
{
}

interface UpdateableNeuron
{
}

class InputNeuron extends Neuron implements UpdateableNeuron
{
   public Neuron[] successors; // TODO: kann man das ev. ins Interface UpdateableNeuron verschieben?
}

abstract class LearningNeuron extends Neuron
{
}
  
class HiddenNeuron extends LearningNeuron implements UpdateableNeuron
{
   public Neuron[] successors; // TODO: kann man das ev. ins Interface UpdateableNeuron verschieben?
}

class OutputNeuron extends LearningNeuron
{
}

class Layers
{
   private static void defineNeuronRelations(double[][] weights, Neuron[] neurons, boolean debug)
   {      
      for(int row = 0; row < weights.length; ++row)
      {
         if(neurons[row] instanceof UpdateableNeuron)
         {
            // Liste mit Nachfolgern:
            ArrayList<Neuron> successors = new ArrayList<Neuron>();
            for(int col = 0; col < weights[row].length; ++col)
            {
               if(weights[row][col] != 0)
               {
                  successors.add(neurons[col]);
               }
            }

            // Liste in Array umwandeln:
            if(neurons[row] instanceof InputNeuron)
            {
               InputNeuron neuron = (InputNeuron)(neurons[row]);
               neuron.successors = successors.toArray(new Neuron[successors.size()]);
            }
            else
            {
               HiddenNeuron neuron = (HiddenNeuron)(neurons[row]);
               neuron.successors = successors.toArray(new Neuron[successors.size()]);
            }
         }
      }
   }
}
Ich hätte gerne die Eigenschaft successors im Interface definiert. Denn ansonst muss ich ständig mit instanceof arbeiten, wie man in der defineNeuronRelations sieht. Diese Unschönheit habe ich auch in einigen anderen Methoden, die ich hier rausgenommen habe, damit es nicht total unübersichtlich wird. Die Sache mit den id´s habe ich hier auch rausgenommen.

Aber das geht auch nicht, oder? Und Mehrfachvererbung klappt mit Java 8 auch nicht, stimmts? Bleiben nur traits übrig?
 
Zuletzt bearbeitet:

minzee

Bekanntes Mitglied
OK, danke für den Eintrag :)

Jetzt habe ich die Problemlösungen zu 1) und 2) zusammengefasst, herausgekommen ist folgendes:
Java:
abstract class Neuron
{
   public int id;
}

interface UpdateableNeuron
{
   public void setSuccessors(Neuron[] successors);
   public Neuron[] getSuccessors();
}

class InputNeuron extends Neuron implements UpdateableNeuron
{
   public Neuron[] successors;
   
   InputNeuron(int id)
   {
      this.id = id;
   }
   public void setSuccessors(Neuron[] successors)
   {
      this.successors = successors;
   }
   public Neuron[] getSuccessors()
   {
      return successors;
   }
}

abstract class LearningNeuron extends Neuron
{
}
  
class HiddenNeuron extends LearningNeuron implements UpdateableNeuron
{
   public Neuron[] successors; 
   
   HiddenNeuron(int id)
   {
      this.id = id;
   }
   public void setSuccessors(Neuron[] successors)
   {
      this.successors = successors;
   }
   public Neuron[] getSuccessors()
   {
      return successors;
   }
}

class OutputNeuron extends LearningNeuron
{
   OutputNeuron(int id)
   {
      this.id = id;
   }
}

class Layers
{
   private static void defineNeuronRelations(double[][] weights, Neuron[] neurons, boolean debug)
   {      
      for(int row = 0; row < weights.length; ++row)
      {
         if(neurons[row] instanceof UpdateableNeuron)
         {
            // Liste mit allen Nachfolgern anlegen:
            ArrayList<Neuron> successors = new ArrayList<Neuron>();
            for(int col = 0; col < weights[row].length; ++col)
            {
               if(weights[row][col] != 0)
               {
                  successors.add(neurons[col]);
               }
            }
            
            // Aus der Liste ein Array machen:
            UpdateableNeuron neuron = (UpdateableNeuron)neurons[row];
            neuron.setSuccessors(successors.toArray(new Neuron[successors.size()]));
         }
      }
   }
}
Die Methode defineNeuronRelations schaut jetzt wesentlich aufgeräumter aus :) Leider habe ich jetzt wieder eine doppelte Programmierung, weil ich setSuccessors und getSuccessors sowohl in InputNeuron als auch in HiddenNeuron implementieren muss. Aber mit diesem Overhead muss ich wohl leben.
 

Thallius

Top Contributor
Nachdem ich damit wohl leben muss...

Du musst nicht unbedingt damit leben. Du kannst der Klasse Neutron auch eine Methode

initWithId(int id)

geben und den Konstruktor weglassen. Dann musst du allerdings bei jedem Erzeugen eines neuen Objektes nicht nur ein new() sondern auch noch ein initWithID() machen.

Gruß

Claus
 

minzee

Bekanntes Mitglied
Daten, die ein Objekt auf jeden Fall benötigt, sollte man jedoch immer im Konstruktor übergeben, und nicht in einer Methode. Ist aber trotzdem eine mögliche Variante. Danke :)
 

tommysenf

Top Contributor
Du kannst eine Klasse AbstractUpdatableNeuron extends Neuron implements UpdateableNeuron erstellen und in ihr die sucessor Eigenschaft implementieren. Alle entsprechenden Neuronen erben dann von dieser. Dabei kann das UpdateableNeuron Interface auch komplett entfallen. Weiterhin solltest du dir angewöhnen Attribute in der Sichtbarkeit einzuschränken.
 

minzee

Bekanntes Mitglied
Das kann doch nur funktionieren, wenn Java Mehrfachvererbung beherrscht, oder? Alle Neuron-Klassen müssen in irgendeiner Weise von der abstrakten Klasse "Neuron" erben. Denn alle Neuron-Klassen haben eine id (und noch andere Sachen). Wenn "HiddenNeuron" von "LearningNeuron" erbt, kann es dann auch noch von deiner neuen Klasse "AbstractUpdateableNeuron" erben?

Java:
                 <<abstract>>
                 Neuron
                 +id
                 #o
                 +getO(): o
                      ^
                      |
             --------------------
             |                  |
       <<abstract>>       <<abstract>>
       UpdatingNeuron     LearningNeuron
       +successors        +predecessors
             ^            #eSig
             |            +setO(c, w)
             |            +getESig(): eSig
             |                  ^
             |                  |
      ---------------   -----------------
      |             |   |               |
InputNeuron      HiddenNeuron       OutputNeuron
+setO(o)         +setESig(c, w)     +setESig(c, e)
      :               :                 :
      :...............:.................:.............> Layers
                                                        +defineNeuronRelations(w, n)
So wäre das natürlich toll. Aber ohne Mehrfachvererbung klappt das nicht, oder?

Nur als Background-Info: damit soll man einen Graphen in Schichten definieren können. Der Graph hat genau 1 Input-Schicht, 1 Output-Schicht und beliebig viele Hidden-Schichten. Also z. B.:
Java:
o      o      o         Input-Schicht mit 3 InputNeuron-Instanzen
|\     |     /
| \    |    /
|  \   |   /
|   \  |  /
|    \ | /
|     \|/
o      o                Hidden-Schicht mit 2 HiddenNeuron-Instanzen
|\    /|\     
| \  / | \    
|  \/  |  \   
|  /\  |   \  
| /  \ |    \ 
|/    \|     \
o      o      o         Output-Schicht mit 3 OutputNeuron-Instanzen
Der Graph ist ein gerichteter Graph. Die Daten fließen von oben nach unten. Die predecessors sind die Vorgänger-Neuronen, die successors sind die Nachfolger-Neuronen eines bestimmten Knotens.

InputNeuron: nur successors, keine predecessors
HiddenNeuron: successors und predecessors
OutputNeuron: nur predecessors, keine successors
 
Zuletzt bearbeitet:

tommysenf

Top Contributor
Okay, die Anforderung von successors und predecessors in einer Klasse war bisher aus deinem Code nicht ersichtlich. Hier ist es wirklich nötig mit Interfaces zu arbeiten und die Code dopplung in Kauf zu nehmen. Sollte der Code komplexer sein ließe sich das durch ein Delegate Aubergine lösen, macht aber bei deinen gettern imho keinen Unterschied.
 

minzee

Bekanntes Mitglied
Ich habe mir jetzt die in Java 8 neu hinzugekommenen virtual extension methods (default-Methoden) angeschaut. Das ist recht interessant. Damit kann man auch direkt im Interface Methoden implementieren.

Das sollte mir ein wenig Code ersparen. Statt Methoden im Interface zu deklarieren und in den Klassen, die dieses Interface implementieren, die Methoden zu implementieren, sollte es mit den default-Methoden reichen, die Methoden direkt gleich im Interface zu implementieren.

Leider bleibt die Restriktion, dass man in Interfaces Eigenschaften nur deklarieren kann, ohne sie auch gleich zu initialisieren.

Ich habe versucht, eine ArrayList in einem Interface zu deklarieren und dort auch gleich eine Instanz davon zu erzeugen. Grundsätzlich geht das. Ich kann der ArrayList dann in Klassen, die das Interface implementieren, Einträge hinzufügen und auslesen. Allerdings hat die ArrayList dann statischen Charakter. Implementieren mehr als 1 Klasse dieses Interface, kommen sie sich also in die Quere, wenn man das statische Verhalten nicht haben möchte.

Bietet Java 8 eine Möglichkeit an, dass man Code in Klassen hineinkopiert? Dass vielleicht der Compiler zuerst einen Code irgendwo hineinkopiert, bevor der eigentlich Kompiliervorgang stattfindet? Dann könnte ich nicht nur Methoden irgendwo einmals implementieren und an unterschiedlichen Stellen verwenden, sondern könnte das Gleiche auch mit Eigenschaft machen (so zumindest meine Hoffnung).
 
Zuletzt bearbeitet:

tommysenf

Top Contributor
Was spricht gegen Delegation, damit vermeidest du eine Code Dopplung. Zu deiner Hoffnung, nein der Java Compiler unterstützt von Haus aus keinen Präprozessor oder Makros. Eine Lösung ließe sich auch noch mit AspectJ erzielen, aber das ist wie mit Kanonen auf Spatzen zu schießen...
 

minzee

Bekanntes Mitglied
Ich versuche verzweifelt, einerseits nichts doppelt programmieren zu müssen, andererseits eine Typbeziehung herzustellen. Also:

InputNeuron ist ein Typ von UpdateableNeuron
HiddenNeuron ist ein Typ von UpdateableNeuron und LearningNeuron
OutputNeuron ist ein Typ von LearningNeuron

Das geht mit Delegation nicht, oder?

AspectJ habe ich schon gehört. Dafür muss man sich wieder was eigenes installieren, weil man dann mit einem anderen Compiler arbeiten muss, richtig? Falls ja, das würde ich gerne vermeiden. Womöglich kennt dieser Compiler dann die neuen Java 8-Features noch nicht.
 
Zuletzt bearbeitet:

tommysenf

Top Contributor
Delegation bedeutet, du implementierst die Funktionaliät in einer separaten Klasse und leitest dann die Methodenaufrufe in den Interfaceimplementierungen an ein Objekt dieser Klasse weiter. Damit bleibst du bei einer Implementierung und hast keine Code Dopplung.
 

tommysenf

Top Contributor
Java:
class HiddenNeuron extends Neuron implements LearningNeuron, UpdateableNeuron {
   private LearningNeuron learningNeuron = new LearningNeuronImpl();
   private UpdateableNeuron updateableNeuron = new UpdateableNeuronImpl();

   public Neuron[] getSuccessors() {
       return learningNeuron.getSuccessors();
   }

...

So würde eine Zwillingsklasse aussehen. Das ist genau das was ich versucht habe dir mit Delegation zu vermitteln...
 
Zuletzt bearbeitet:

minzee

Bekanntes Mitglied
Schaut interessant aus. Hast du eine Quelle für mich, wo ich das im Internet nachlesen könnte? Ich hatte heute Nacht im Internet rumgesucht, aber nirgendwo ein Beispiel gefunden.
 
Zuletzt bearbeitet:

tommysenf

Top Contributor
Ne direkte Quelle hab ich nicht, da ich den Begriff Zwillingsklasse auch noch nicht gehört habe, allerdings ist in dem Wikipedia Artikel ja genau beschrieben wie es gemacht wird. Letztendlich ist es der einfache Einsatz von Komposition und Delegation, also Grundlagen der Objektorientierung.
 

minzee

Bekanntes Mitglied
Ich habe mir jetzt mal dieses "Mixin Inheritance" von Java Multiple Inheritance angeschaut. Mal abgesehen davon, dass das Programm sicher einen Compiler-Fehler liefert, weil ein Konstruktor falsch definiert wurde, habe ich Probleme damit, den Sinn dieses Beispiels zu verstehen.

Wenn das Hauptprogramm eine Child-Instanz erzeugt und dann die func-Methode aufruft, wird das an die func-Methode von Mixin weitergeleitet. Dort wird die getValue-Methode von Parent aufgerufen. Diese getValue-Methode könnte man auch direkt aus dem Hauptprogramm aus aufrufen, weil Child direkt von Parent erbt.

Aber ich glaube, ich habe das Grundprinzip verstanden, worum es hier geht :)
Jetzt schaue ich mir noch den zweiten Teil an.
 

minzee

Bekanntes Mitglied
Noch ein Nachtrag.

Klassen - Vererbung:
Code:
                     Neuron
                       Δ
                       |
     ------------------+------------------
     |                 |                 |
     |                 |                 |
     |                 |                 |
     |                 |                 |
InputNeuron      HiddenNeuron      OutputNeuron

Klassen - Beziehungen (Delegation):
Code:
         UpdateMixin        LearnMixin   
          ^       ^         ^       ^    
          |       |         |       |    
InputNeuron      HiddenNeuron      OutputNeuron

Interfaces - Implementierungen:
Code:
                  «interface»
                    Addable
                       ^
                       :
              .........:.........
              :        :        :
              :      Neuron     :
              :                 :
         «interface»       «interface»
         Updateable         Learnable
              ^                 ^
              :                 :
     .........:.................:.........
     :        :        :        :        :
     :   UpdateMixin   :    LearnMixin   :
     :                 :                 :
     :                 :                 :
InputNeuron      HiddenNeuron      OutputNeuron
Das würde bei mir so aussehen, richtig?

P. S. das Interface Addable habe ich noch hinzugefügt über alles drübergesetzt.
 
Zuletzt bearbeitet:

tommysenf

Top Contributor
Ja sieht gut aus, wobei ich deine XXXNeuron Klassen auch alle von Neuron ableiten würde. Indem Paper ist das zweite Beispiel auch das welches deinem Problem besser entspricht.
 

minzee

Bekanntes Mitglied
Jetzt habe ich auch noch diese erste Variante ausprogrammiert. Das werde ich später auch mit der zweiten Variante versuchen, damit ich dann vergleichen kann.
Java:
import java.util.ArrayList;

interface Addable
{
}

/**
 * Für alle Eingabe-Neuronen und verdeckten Neuronen.
 */
interface Updateable extends Addable
{
   void setSuccessors(ArrayList<Learnable> successors);
   ArrayList<Learnable> getSuccessors();
}

/**
 * Für alle verdeckten Neuronen und Ausgabe-Neuronen.
 */
interface Learnable extends Addable
{
   void setPredecessors(ArrayList<Updateable> predecessors);
   ArrayList<Updateable> getPredecessors();
}

/**
 * Mixin-Klasse für alle Eingabe-Neuronen und verdeckte Neuronen.
 */
class UpdateMixin implements Updateable
{
   ArrayList<Learnable> successors = new ArrayList<Learnable>();
   
   // Methoden von Interface Updateable implementieren:
   public void setSuccessors(ArrayList<Learnable> successors)
   {
      this.successors = successors;
   }
   public ArrayList<Learnable> getSuccessors()
   {
      return successors;
   }
}

/**
 * Mixin-Klasse für alle verdeckten Neuronen und Ausgabe-Neuronen.
 */
class LearnMixin implements Learnable
{
   ArrayList<Updateable> predecessors = new ArrayList<Updateable>();
   
   // Methoden von Interface Learnable implementieren:
   public void setPredecessors(ArrayList<Updateable> predecessors)
   {
      this.predecessors = predecessors;
   }
   public ArrayList<Updateable> getPredecessors()
   {
      return predecessors;
   }
}

/**
 * Abstrakte Klasse für alle Neuronen
 */
abstract class Neuron implements Addable
{
   protected int id;
   
   int getId()
   {
      return id;
   }
}

/**
 * Eingabe-Neuron
 */
class InputNeuron extends Neuron implements Updateable
{
   private final UpdateMixin updateMixin = new UpdateMixin();
   
   InputNeuron(int id)
   {
      this.id = id;
   }
   
   // Delegationen:
   public void setSuccessors(ArrayList<Learnable> successors)
   {
      updateMixin.setSuccessors(successors);
   }
   public ArrayList<Learnable> getSuccessors()
   {
      return updateMixin.getSuccessors();
   }
}

/**
 * Verdecktes Neuron
 */
class HiddenNeuron extends Neuron implements Updateable, Learnable
{
   private final UpdateMixin updateMixin = new UpdateMixin();
   private final LearnMixin learnMixin = new LearnMixin();
   
   HiddenNeuron(int id)
   {
      this.id = id;
   }
   
   // Delegationen:
   public void setSuccessors(ArrayList<Learnable> successors)
   {
      updateMixin.setSuccessors(successors);
   }
   public ArrayList<Learnable> getSuccessors()
   {
      return updateMixin.getSuccessors();
   }
   public void setPredecessors(ArrayList<Updateable> predecessors)
   {
      learnMixin.setPredecessors(predecessors);
   }
   public ArrayList<Updateable> getPredecessors()
   {
      return learnMixin.getPredecessors();
   }
}

/**
 * Ausgabe-Neuron
 */
class OutputNeuron extends Neuron implements Learnable
{
   private final LearnMixin learnMixin = new LearnMixin();;
   
   OutputNeuron(int id)
   {
      this.id = id;
   }
   
   // Delegationen:
   public void setPredecessors(ArrayList<Updateable> predecessors)
   {
      learnMixin.setPredecessors(predecessors);
   }
   public ArrayList<Updateable> getPredecessors()
   {
      return learnMixin.getPredecessors();
   }
}

class Main
{
   private static void dumpSuccessors(ArrayList<Learnable> successors)
   {
      for(int i = 0; i < successors.size(); ++i)
      {
         System.out.println(((Neuron)(successors.get(i))).getId());
      }
   }
   private static void dumpPredecessors(ArrayList<Updateable> predecessors)
   {
      for(int i = 0; i < predecessors.size(); ++i)
      {
         System.out.println(((Neuron)(predecessors.get(i))).getId());
      }
   }
   public static void main(String[] args)
   {
      // Architektur (gerichteter Graph, Datenfluss von oben nach unten):
      //    0             1  Eingabeschicht
      //     \\         //
      //      \ \     / /
      //       \  \ /  /
      //        \  2  /      verdeckte Schicht
      //         \ | /
      //          \|/
      //           3         Ausgabeschicht
      Addable[] neurons = 
      {
         new InputNeuron(0),
         new InputNeuron(1),
         new HiddenNeuron(2),
         new OutputNeuron(3)
      };
      
      // 0 -> 2, 3:
      ArrayList<Learnable> s0  = new ArrayList<Learnable>();
      s0.add((Learnable)neurons[2]);
      s0.add((Learnable)neurons[3]);
      ((Updateable)neurons[0]).setSuccessors(s0);
      
      // 1 -> 2, 3:
      ((Updateable)neurons[1]).setSuccessors(s0);
      
      // 0, 1 -> 2
      ArrayList<Updateable> p0 = new ArrayList<Updateable>();
      p0.add((Updateable)neurons[0]);
      p0.add((Updateable)neurons[1]);
      ((Learnable)neurons[2]).setPredecessors(p0);
           
      // 2 -> 3:
      ArrayList<Learnable> s1  = new ArrayList<Learnable>();
      s1.add((Learnable)neurons[2]);
      ((Updateable)neurons[2]).setSuccessors(s1);
      
      // 0, 1, 2 -> 3
      ArrayList<Updateable> p1 = new ArrayList<Updateable>();
      p1.add((Updateable)neurons[0]);
      p1.add((Updateable)neurons[1]);
      p1.add((Updateable)neurons[2]);
      ((Learnable)neurons[3]).setPredecessors(p1);
      
      // Nachfolger von 0:
      System.out.println("Nachfolger von 0:");
      dumpSuccessors(((Updateable)neurons[0]).getSuccessors()); // 2, 3
      
      // Nachfolger von 1:
      System.out.println("Nachfolger von 1:");
      dumpSuccessors(((Updateable)neurons[1]).getSuccessors()); // 2, 3
      
      // Vorgänger von 2:
      System.out.println("Vorgänger von 2:");
      dumpPredecessors(((Learnable)neurons[2]).getPredecessors()); // 0, 1
      
      // Nachfolger von 2:
      System.out.println("Nachfolger von 2:");
      dumpSuccessors(((Updateable)neurons[2]).getSuccessors()); // 3
      
      // Vorgänger von 3:
      System.out.println("Vorgänger von 3:");
      dumpPredecessors(((Learnable)neurons[3]).getPredecessors()); // 0, 1, 2
   }
}
Das ist viiiiiiiiiiiiel Tipparbeit. Und leider muss ich scheinbar ziemlich oft casten. Aber einfacher geht es nicht mehr bei dieser Variante, oder? Ich hatte noch versucht, statt dumpSuccessors und dumpPredecessors nur eine einzige Methode dump zu programmieren, leiber habe ich das nicht geschafft. Konnte der dump-Methode dann nicht eine Addable-ArrayList übergeben :(

Mir ist jetzt zufällig auch noch ein Fehler in der Grafik der Interface-Implementierungen aufgefallen. Sollte so aussehen:
Java:
                  «interface»
                    Addable
                       ^
                       :
              .........:.........
              :        :        :
              :      Neuron     :
              :                 :
         «interface»       «interface»
         Updateable         Learnable
              ^                 ^
              :                 :
     .........:........  .......:.........
     :        :       :  :      :        :
     :   UpdateMixin  :  :  LearnMixin   :
     :                :  :               :
     :                :  :               :
InputNeuron       HiddenNeuron     OutputNeuron
Da war ein Fehler beim HiddenNeuron
 
Zuletzt bearbeitet:

minzee

Bekanntes Mitglied
Wozu brauche ich denn bei der zweiten Variante von Java Multiple Inheritance ("General Multiple Inheritance") die Klasse "Other"? Darf man nicht das, was in "Other" steht in die Klasse "OtherChild" schreiben?

Es geht doch darum, für "ParentChild" eine Mehrfachvererbung zu programmieren, oder? So wie ich das verstehe, soll "ParentChild" einerseits alles von "Parent" erben, andererseits über Delegation auch auf die Methoden von "OtherChild" zugreifen können. Stimmt das?

EDIT: alles klar, die Antwort steckt hier: :)
If we had the freedom to modify class Other we could avoid the class OtherChild and just have Other implement this new interface.

Also wenn ich "OtherChild" vergesse, bereits in "Other" die Schnittstelle "OtherInterface" implementieren und in "ParentChild" mit einer Instanz von "Other" arbeite (statt mit "OtherChild"), dann ist mein "Other" meine Mixin-Klasse, und es kommt genau das raus, was ich schon programmiert haben, oder?

Die zweite Variante brauche ich nur, wenn die Klasse "Other" gegeben ist, und ich keine Mixin-Klasse daraus machen kann/darf (weil die Klasse nicht OtherInterface implementieren darf?). Dann muss ich neben dem Interface "OtherInterface" auch noch die Klasse "OtherChild" definieren. Stimmt das?
 
Zuletzt bearbeitet:

tommysenf

Top Contributor
1. Das Interface Addable ist sinnlos und sorgt nur für unnötige casts. Mit Neuron besitzt du schon einen einheitlichen Basistyp.

2. Die id gehört in den Konstruktor von Neuron. Subklassen müssen dann den super Aufruf durchführen.

3. Bei getSuccessors und get Precessors gibst du nur die Interfaces zurück, damit verlierst du die Information das Vorgänger und Nachfolger Neuronen sind. Das ist denke ich nicht in deinem Interesse.

4. public static void dump(List<? extends Neuron> list) {
for(Neuron n : list) sysout(n);
}

5. Das viele Casten resultiert daher, das du anfangs alle Informationen durch das Addable Interface wegschmeißt obwohl du sie später wieder benötigst. Arbeite mit dem konkreten Typ dann brauchst du keinen der casts.

6. Zur Tipparbeit: Mindestens 70% davon sind Sachen, welche dir die IDE automatisch generieren kann, nutze das.
 

minzee

Bekanntes Mitglied
Zu 1): Addable hatte ich noch hinzugefügt, weil ich mir dachte, es gäbe sonst keinen Zusammenhang (keine Hierarchie) zwischen der Klasse Neuron und den Interfaces Updateable und Learnable. Ich hatte die Hoffnung, dass dein 3) damit kein Problem mehr wäre.

Das 4) schaut echt interessant aus. Das habe ich noch nie gesehen :)

Letztendlich lege ich die Neuronen dynamisch aus, und zwar aus einer Adjazenzmatrix. Darum landen die Neuronen anfangs in einem Array. Und das kann nur vom Typ Addable, oder wenn ich dieses Interface lösche, vom Typ Neuron sein.

Echt toll, wie du mir weiterhilfst!! :)
 

tommysenf

Top Contributor
Du kannst anfangs auch 3 Arrays nehmen, eines pro Neurontyp. Damit sparst du dir die casts auch.

Zu 3. es sollte eigentlich sysout(n.getId()) heißen...
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Methoden Anfängerprobleme o-o Java Basics - Anfänger-Themen 7
B Anfängerprobleme (Casting,...) Java Basics - Anfänger-Themen 5
kulturfenster UML Anfängerprobleme Java Basics - Anfänger-Themen 2
G GUI: Anfängerprobleme Java Basics - Anfänger-Themen 5
imocode Vererbung Problem mit Vererbung Java Basics - Anfänger-Themen 2
M Vererbung - Polymorphie Java Basics - Anfänger-Themen 37
L Java- Vererbung Java Basics - Anfänger-Themen 4
ineedhelpinjava Vererbung Java Basics - Anfänger-Themen 12
ineedhelpinjava Vererbung Java Basics - Anfänger-Themen 1
I JSON / XML Struktur mit Vererbung / Interfaces Java Basics - Anfänger-Themen 0
M Interface oder Vererbung? Java Basics - Anfänger-Themen 12
M Vererbung Java Basics - Anfänger-Themen 6
M Designentscheidung von Attributen/Methoden im Falle von Vererbung Java Basics - Anfänger-Themen 8
M Generics Vererbung Listen Java Basics - Anfänger-Themen 2
A Methoden Vererbung und Interface Java Basics - Anfänger-Themen 14
D Klassen und Vererbung Java Basics - Anfänger-Themen 2
U Vererbung Java Basics - Anfänger-Themen 7
D Vererbung Java Basics - Anfänger-Themen 3
K Schleife berechnet kein Ergebnis (Vererbung) Java Basics - Anfänger-Themen 6
00111010101 Objektorientiertes Programmieren mit Vererbung (Zahlen in Array verschwinden) Java Basics - Anfänger-Themen 3
W Zur Vererbung: Wann und wie? Java Basics - Anfänger-Themen 35
H Datenkapselung, Vererbung und UML Java Basics - Anfänger-Themen 16
districon Super-Stichwort/ Vererbung Java Basics - Anfänger-Themen 3
YaU Vererbung erstellt NullPointerException? Java Basics - Anfänger-Themen 4
1 Vererbung Klassenattribute Java Basics - Anfänger-Themen 9
TimoN11 Frage zu Java-Vererbung (Cast) Java Basics - Anfänger-Themen 5
N Thema Vererbung Java Basics - Anfänger-Themen 31
A Vererbung Vererbung Übung Java Basics - Anfänger-Themen 5
B Vererbung - Sichtbarkeitsmodifikation - protected Java Basics - Anfänger-Themen 10
B Best Practice Unschlüssig ob Vererbung oder Interface Java Basics - Anfänger-Themen 2
G Java Vererbung Java Basics - Anfänger-Themen 8
Y Vererbung Konto - Anfangsprobleme Java Basics - Anfänger-Themen 7
A Vererbung Klassen im Bezug auf Auto´s Java Basics - Anfänger-Themen 18
A Klassen Vererbung und zusätzliche Unterklassen Java Basics - Anfänger-Themen 23
M Vererbung mit Enums Java Basics - Anfänger-Themen 8
Kirby.exe Vererbung im Detail erklärt? Java Basics - Anfänger-Themen 9
N Modellierung, vererbung, Java Basics - Anfänger-Themen 163
M Fehlendes Verständnis für dynamische Bindung und Vererbung Java Basics - Anfänger-Themen 13
W OOP Vererbung im Computerspiel Java Basics - Anfänger-Themen 7
J Probleme mit Vererbung Java Basics - Anfänger-Themen 4
I Vererbung Java Basics - Anfänger-Themen 13
W OOP Vererbung und Problem bei Zählschleife in einer Methode Java Basics - Anfänger-Themen 10
W Methoden Verständnisfrage Vererbung von Methoden Java Basics - Anfänger-Themen 14
V Vererbung Java Basics - Anfänger-Themen 2
J Frage zur Vererbung Java Basics - Anfänger-Themen 1
J Vererbung Java Basics - Anfänger-Themen 3
U Was löst meine NullPointerException aus? (Vererbung) Java Basics - Anfänger-Themen 12
O Vererbung Ueben mit kleiner Datenstruktur von Räumen Java Basics - Anfänger-Themen 10
O Umgang mit Vererbung verstehen Java Basics - Anfänger-Themen 4
A Vererbung/Interfaces/Generics Java Basics - Anfänger-Themen 12
O Vererbung änderung des Konstruktors Java Basics - Anfänger-Themen 8
L Vererbung Java Basics - Anfänger-Themen 5
E HashMap+Vererbung Java Basics - Anfänger-Themen 11
E Vererbung super-Methoden Aufruf Java Basics - Anfänger-Themen 3
B Java Vererbung Fragen (zu Code Beispiel) Java Basics - Anfänger-Themen 3
A Objekterstellung bei der Vererbung Java Basics - Anfänger-Themen 7
P Vererbung Warum funktioniert die Vererbung hier nicht Java Basics - Anfänger-Themen 14
S Vererbung Java mehrfach Java Basics - Anfänger-Themen 10
B Objekte zählen/ Vererbung/ Kopplung/ Interface/ Abstract Class Java Basics - Anfänger-Themen 5
A Klassen Vererbung privater Methoden und Member Java Basics - Anfänger-Themen 12
A Konstruktoren Vererbung Java Basics - Anfänger-Themen 3
ReinerCoder Vererbung von JFrame in einer Klasse entfernen Java Basics - Anfänger-Themen 5
W Vererbung, abstract und Konstruktoren Java Basics - Anfänger-Themen 30
J Vererbung und Methodenaufruf Java Basics - Anfänger-Themen 11
G Polymorphie, Vererbung, statischer Typ, Laufzeittyp Java Basics - Anfänger-Themen 2
H Vererbung mit private instanzvariablen Java Basics - Anfänger-Themen 9
S Vererbung Funktionsweise Code zur Vererbung Java Basics - Anfänger-Themen 1
C Methoden Vererbung private Attribute/public Methoden Java Basics - Anfänger-Themen 4
S Verständnis Vererbung Java Basics - Anfänger-Themen 3
D JavaFX Vererbung Java Basics - Anfänger-Themen 2
U Vererbung Generizität und Vererbung Java Basics - Anfänger-Themen 4
A Vererbung bei Klassen mit Objekt der Klasse im Konstruktor Java Basics - Anfänger-Themen 4
K Vererbung Octagon von Circle Java Basics - Anfänger-Themen 0
B Hilfe bei Vererbung Java Basics - Anfänger-Themen 2
D Vererbung Frage zum Klassenaufbau mit Vererbung Java Basics - Anfänger-Themen 1
T Vererbung und interface. Java Basics - Anfänger-Themen 1
S Gehaltsberechnung (Vererbung, abstrakte Methoden) Java Basics - Anfänger-Themen 6
S Vererbung Java Basics - Anfänger-Themen 1
F Vererbung in zwei Richtungen? Java Basics - Anfänger-Themen 14
D Vererbung / Polymorphie Java Basics - Anfänger-Themen 5
O Vererbung Java Basics - Anfänger-Themen 5
MiMa Vererbung Theorie OK, Praxis ?? Java Basics - Anfänger-Themen 4
Arif Vererbung Vererbung Variablen überschreiben Java Basics - Anfänger-Themen 1
C Vererbung - Ausgaben bestimmen Java Basics - Anfänger-Themen 6
S Vererbung Java Basics - Anfänger-Themen 10
L Setter und Getter/Vererbung Java Basics - Anfänger-Themen 6
C Konstruktoren und Vererbung Java Basics - Anfänger-Themen 2
J Kleinere Frage zur Vererbung/Objekterzeugung Java Basics - Anfänger-Themen 2
G Vererbung Java Basics - Anfänger-Themen 12
J Vererbung privater Variablen Java Basics - Anfänger-Themen 7
J Vererbung Vererbung von Methoden Java Basics - Anfänger-Themen 6
B Vererbung Java Basics - Anfänger-Themen 12
K Vererbung (super) Java Basics - Anfänger-Themen 2
A ArrayQueue mit Exceptions und Vererbung Java Basics - Anfänger-Themen 3
J Java: static bei Vererbung Java Basics - Anfänger-Themen 5
C Vererbung Java Basics - Anfänger-Themen 4
L Vererbung Java Basics - Anfänger-Themen 3
J Klassenorganisation | Vererbung Java Basics - Anfänger-Themen 1
B Vererbung Vererbung Java Basics - Anfänger-Themen 2
N Generics Vererbung Wildcard Interface Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben