Kluges Durchgehen aller Kombinationen mit Randbedingungen?

berndoa

Top Contributor
Hallo,im Prinzip geht es immer noch um mein baccaratspiel, aber ich habe dabei mehr ein allgemeines kombinatorisches Problem:
Vereinfacht gesprochen läuft ein Spiel wie folgt:
Wir haben zu Beginn ein leeres 6 Tupel.
Bei index 0,1,3 und 4 soll jeweils eine Zahl aus 0-9 eingefügt werden.
Abhängig von index 0 und 1 wird entweder indexstelle 2 leer gelassen oder es wird auch dort eine Zahl aus 0-9 eingefügt.

Nun wird bei index=5 abhängig von den indexstellen 0-4 und noch komischeren Regeln ebenso entweder frei gelassen oder eine zahl 0-9 reingeschrieben.

Das heißt wiederum, es gibt 6 tupel wo alle 6 stellen befüllt sind, es gibt manche wo index=2 leer ist, index=5 leer ist oder Beides.

Und ich will mir nun eine Liste aller möglichen 6Tupel aufschreiben.


Klar könnte ich nun hingehen und alle 6tupel aufschreiben, bei denen alle 6 stellen mit zahlen 0-9 belegt sind.

Und dann durchgehen und wieder die 6-tupel löschen, die "unmöglich" sind (wo bspw. eine zahl bei index=2 drin steht obwohl die regeln sagen dass für dieses tupel die stelle freizulassen wäre)

Aber, das wird mir vermutlich jeder sagen, ist das aus Informatikersicht eine höchst ineffiziente Vorgehensweise, gerade weil ich ja da erst 10^6 6Tupel in eine Lsite packe nur um dann unzählige davon wieder rauszulöschen.

Ich kriegs aber irgendwie auch gerade nicht auf die Reihe wie ich systematisch nur alle real auch möglichen 6Tupel baue.

Mein Grundvorgehen wäre wie folgt:
Erst mal alle Kombinationen für die Stelle 0,1,3,4 durchgehen;
weil die 4 stellen ja in allen Fällen eine zahl bekommen.
Aber wie dann weiter?


ich müsste sowohl die 6tupel ohne 2. stelle aufschreiben als auch dann für zutreffende kombinationen je 10 6tupel aufschreiben, wo eben die 2. stelle die zahl 0-9 ist.

habe ich das, müsste ich wieder für jedes davon für zutreffende kombis wiederum je 10 6tupel aufschreiben wo die 5. stelle eine der zahlen 0-9 ist.


Ich könnte entweder eine Liste bauen, die immer wieder verändert und erweitert wird.
wo anfangs nur tupel mit den 4 belegten stellen drin sind.
dann wird je nachdem für jedes passende listenelement eine menge an tupeln mit aufgefülltem 2. element reingepackt.

dann wieder über die lsite iteriert und entsprechend für die 5. stelle ebenso tupeln hinzugefügt sowie unvollständige tupels rausgelöscht.

Aber auch da muss man x mal über die liste gehen, tupel löschen und einfügen.


Andere Variante, die ich zwar für gewöhnlich "quick and dirty" machen würde (und die jedem hier einen Herzinfarkt und Wutanfall einjagen würde), wäre, da 6 stellen, ebenm mit einem intelligenten Geflecht aus 6 for-schleifen zu arbeiten, mit if bedinungen dazwischen die gucken ob die für die 2. und 5. indexstelle zugehörige for shcleife überhaupt aufgerufen wird.

Das ist aber natürlich ganz ganz böser schlechter stil und gar nicht flexibel, würde also nicht funktionieren wenn plötzlich die arrays alle 7 stellen lang wären oder so.

Darum die Frage, wie ginge ich da am Besten alle Möglichkeiten durch?

Selbst die hochgefeirtte objektorientierung scheint mir da nur wenig hilreich zu sein weil es mehr um ein strategisches Problem und keine Schöhnheitsvergleiche
geht :-/



PS: wen die Bedingungen interessiert:
die index=2 stelle wird dann mit einer zahl belegt wenn die zahlen bei index=0 und index=1 zusammen einen wert <=5 ergibt.
nur dann wird die index=2. stelle belegt mit einer zahl.

die bedingungen für die index=5. stelle sind komplizierter, aber in einer if bedingung auch formulierbar und hängt halt auch von allen anderen Stellen ab (will sagen, müsste ich erst nachgucken und ist für das grundproblem hier im Detail unwichtig).
 

mihe7

Top Contributor
Ausgangspunkt sind alle vierstelligen Zahlen (deren Ziffern auf das Array verteilt werden), im einfachsten Fall also
Java:
for (int i = 0; i < 10000; i++) {
   
}
Je nach Fall kannst Du in der Schleife fünf- und sechsstellige Zahlen bilden.
 

White_Fox

Top Contributor
Nur mal eine Frage ob ich dich richtig verstehe:
Dein Sextupel soll sechs Indizes enthalten, wobei jeder Index für einen Kartenwert steht?

Klar könnte ich nun hingehen und alle 6tupel aufschreiben, bei denen alle 6 stellen mit zahlen 0-9 belegt sind.

Und dann durchgehen und wieder die 6-tupel löschen, die "unmöglich" sind (wo bspw. eine zahl bei index=2 drin steht obwohl die regeln sagen dass für dieses tupel die stelle freizulassen wäre)

Aber, das wird mir vermutlich jeder sagen, ist das aus Informatikersicht eine höchst ineffiziente Vorgehensweise, gerade weil ich ja da erst 10^6 6Tupel in eine Lsite packe nur um dann unzählige davon wieder rauszulöschen.
Nein...nicht unbedingt. Denn wo ist der Unterschied ob du erst stur die Liste mit evt. überflüssigen Werten erstellst und dann prüfst was da eigentlich reingehört oder ob du eine neue Indexkombination erstellst, prüfst und dann in die Liste einträgst?

Du wirst für die eine Lösung zwischendurch mehr Speicherplatz verbrauchen, aber das dürfte auch bei schwachbrüstigen Rechnern heutzutage kaum ins Gewicht fallen. Eine Million 32-Bit-Zahlen belegen 4Megabyte, das ist lächerlich.


Selbst die hochgefeirtte objektorientierung scheint mir da nur wenig hilreich zu sein weil es mehr um ein strategisches Problem und keine Schöhnheitsvergleiche
geht :-/
Wenn es darum geht, Kartenwerte darzustellen, dann würde ich damit anfangen für die Kartenwerte eine Enumeration aufzumachen. Und dann mit dieser Enumeration anstatt den numerischen Kartenwerten arbeiten.
Und OOP sei dank kannst du jedem Enumerationseintrag u.a. noch ein Integer anhängen, wo du den numerischen Wert immer noch eintragen kannst. Damit kannst du z.B. zehn, Bube, Dame und König haben und dir für alle Werte den numerischen Wert 10 zurückgeben lassen (und immer noch zwischen den Karten unterscheiden).

Im Code sieht das nach viel Text aus, aber den verstehen die meisten Menschen besser als Zahlen. Und du kannst z.B. noch zwischen Buben und Damen unterscheiden, das geht aber schlicht nicht wenn du jedes Mal nur eine 10 hast.
Und der Compiler macht daraus am Ende sowieso einen Zahlenwert draus, sodaß dir nix verloren geht.
 

White_Fox

Top Contributor
Nachtrag: Für den OOP-Muffel mal ein Beispiel:

Java:
public enum Cardvalue{
    SEVEN(7),
    EIGHT(8),
    NINE(9),
    TEN(10),
    JACK(10),
    QUEEN(10),
    KING(10),
    ACE(11);
    
    private final int numericValue;
    
    private Cardvalue(int numericValue){
        this.numericValue = numericValue;
    }
    
    public int getNumericValue(){
        return numericValue;
    }
}

Dasselbe nochmal für Farben:

Java:
public enum Cardcolor{
    HEARTS,
    DIAMOND,
    SPADES,
    CLUBS
}

Das zusammenpappen in:
Java:
public class Card{
    public final Cardvalue = VALUE;
    public final Cardcolor = COLOR;
    
    public Card(Cardvalue value, Cardcolor color){
        this.VALUE = value;
        this.COLOR = color;
    }
}

Und damit könntest du jetzt jedes beliebige Kartendeck sehr komfortabel darstellen, mischen, und alles was du sonst noch so willst oder wollen könntest. Z.B.:

Java:
public class CardDeckFactory{
    
    public ArrayList<Card> newMixedMauMauDeck(){
        var cards = new ArrayList<Card>()
        for(Cardcolor color : Cardcolor.array()){
            for(Cardvalue value : Cardvalues.array()){
                cards.add(new Card(color, value));
            }
        }
        Collections.shuffle(cards); //Karten mischen
        return cards;
    }
}
 

berndoa

Top Contributor
Nur mal eine Frage ob ich dich richtig verstehe:
Dein Sextupel soll sechs Indizes enthalten, wobei jeder Index für einen Kartenwert steht?


Nein...nicht unbedingt. Denn wo ist der Unterschied ob du erst stur die Liste mit evt. überflüssigen Werten erstellst und dann prüfst was da eigentlich reingehört oder ob du eine neue Indexkombination erstellst, prüfst und dann in die Liste einträgst?

Du wirst für die eine Lösung zwischendurch mehr Speicherplatz verbrauchen, aber das dürfte auch bei schwachbrüstigen Rechnern heutzutage kaum ins Gewicht fallen. Eine Million 32-Bit-Zahlen belegen 4Megabyte, das ist lächerlich.



Wenn es darum geht, Kartenwerte darzustellen, dann würde ich damit anfangen für die Kartenwerte eine Enumeration aufzumachen. Und dann mit dieser Enumeration anstatt den numerischen Kartenwerten arbeiten.
Und OOP sei dank kannst du jedem Enumerationseintrag u.a. noch ein Integer anhängen, wo du den numerischen Wert immer noch eintragen kannst. Damit kannst du z.B. zehn, Bube, Dame und König haben und dir für alle Werte den numerischen Wert 10 zurückgeben lassen (und immer noch zwischen den Karten unterscheiden).

Im Code sieht das nach viel Text aus, aber den verstehen die meisten Menschen besser als Zahlen. Und du kannst z.B. noch zwischen Buben und Damen unterscheiden, das geht aber schlicht nicht wenn du jedes Mal nur eine 10 hast.
Und der Compiler macht daraus am Ende sowieso einen Zahlenwert draus, sodaß dir nix verloren geht.
Im Prinzip ein Array der Länge 6, wobei halt erst die stellen mit index 0,1,3,4, befüllt werden und abhängig von diesen 4 Werten werden die anderen beiden Stellen befüllt oder nicht.

In baccarat ziehen in jedem Fall Spieler und Bank je 2 Karten.
Und je nach den Werten kriegen Spieler und/oder bank je noch eine 3. karte dazu.
Zusammengefasst also maximal 6 Karten, kann aber auch 5 oder nur 4 Karten sein.

Und ich will halt jede (im Rahmen des Spiels erlaubte) Kartenkombi in einer Lsite speichern, wobei es halt auch Kombinationen gibt, wo eben keine 5. und 6. gezogen wird.
stelle mir das im Array dann so vor wie [As, Bube, X, König, 10, X]

bzw. da es fürs Rechnen später sinnvoller ist eben sowas wie [1,0,-99,0,0,-99]
zulässige Zahlenwerte sind 0-9 (weil die Karten 2-As eben auf diesne Zahlenraum abgebildet werden).


Frage ist halt wie ich systematisch alle im Rahmen der Regeln möglichen Kombinationen durchgehe, ohne Primitiv alle möglichen 10^6 Tupel zu basteln und dann die darin enthaltenen, unmöglichen wieder zu entfernen.

Codetechnisch könnte ich das Ganze unschön (in Augen der Perfektionisten hier und teilweise auch in meinen Augen) mit ifs unfd forschleifen lösen:

Java:
ArrayList<int[]> liste=new ArrayList<int[]>;

for(int index0=0;index0<=9;i++){
  for(int index1=0;index1<=9;i++){
    for(int index3=0;index3<=9;i++){
      for(int index4=0;index4<=9;i++){

        if(*BedingungDamitIndexstelle=2BelegtWird*){
          for(int index2=0;index2<=9;i++){
            if(*BedingungDamitIndexstelle=5BelegtWird*){
              for(int index5=0;index5<=9;i++){
                int[] eintrag=new int[6];
                eintrag[0]=index0;
                eintrag[1]=index1;
                eintrag[2]=index2;
                eintrag[3]=index3;
                eintrag[4]=index4;
                eintrag[5]=index5;
                liste.add(eintrag);
              }
            }
          }
        }
      }
    }
  }
}


Wie gesagt, sollte funktionieren und am Ende enhält Liste Alles, was ich will, aber nicht schön und ich brauche halt für jede Indexstelle
eine for Schleife. Wobei aber auch nicht in allen Fällen immer die zu index=2 und index?5 zugehörige for Schleife ausgeführt wird, wenn die Bedingungen nicht erfüllt sind.


@mihe7: ja, der Gedanke schwirrte mir auch schon im Kopf rum, die 4stelligen zahlen durchzugehen und wo passend eben noch eine 5. und 6. ziffer anzuhängen.
Würde man sich zumindest 4 der 6 for schleifen sparen.
Den von bedingungen abhängigen kram bräuchte man halt trotzdem

@White_Fox: Vermutlich geht da was mit Enums, wobei ich persönlich noch nie den großen Nutzen hinter typischen Enums gesehen habe.

Wobei ich Enums auch nur so in der Form
Java:
Enum Zahlen{EINS,ZWEI,DREI}
oder so kenne und man dann eben mit Zahlen.EINS die entsprechende konstante benutzt.
Als Laie würde man sichd a dann vermutlich fragen:
Warum nicht einfahc drei Variabeln oder Kosntanten definieren, so wie man auch
Java:
final double Pi=3.14159;
schreiben kann, also wozu die Kosntanten "gruppieren"?

habe mich aber auch noch nicht allzu sehr mit Enums befasst, blicke also erst gar nicht durch was du da genau machst bzw. wie es funktioniert.
 

White_Fox

Top Contributor
Vermutlich geht da was mit Enums, wobei ich persönlich noch nie den großen Nutzen hinter typischen Enums gesehen habe.
Der Nutzen ist zuerst mal, daß du als Mensch damit mehr anfangen kannst. Mit Literalen wie MONTAG, DIENSTAG,...SONNTAG können die meisten Menschen etwas anfangen, der Compiler macht da am Ende einfache Integers draus (zumindest in C macht er das so).
Und MONTAG, DIENSTAG,...SONNTAG haben für dich eine andere Bedeutung als z.B. ROT, GELB, GRÜN, die komplett verloren geht wenn du anstatt solcher Konstanten einfache Integers nimmst. Wertfolgen wie 0, 1,...6 und 0, 1,...6 tragen nicht dieselbe Bedeutung, du siehst dem Integer ja nichts an, was über seinen reinen Zahlenwert hinausgeht.
Aber z.B. in ein Array, wo du MONTAG, DIENSTAG,...SONNTAG parken kannst, kannst du nicht ROT, GELB, GRÜN reinwerfen, da meckert der Compiler.

Ich habe vom programmieren ja eigentlich keine Ahnung (ich bin E-Techniker), aber eines kann man beim Programmieren nicht als wichtig genug erachten: Etwas, z.B. Ausdrücken, Bedeutung zuzuweisen.

Ein kleines Beispiel: Nehmen wir an, du programmierst ein Schachspiel. Es gibt ja zwei Farben, schwarz und weiß. Es kommt durchaus häufig vor daß die Leute auf die Idee kommen die Farbe jetzt in einem Boolean zu codieren. Wenn schwarz, dann true, sonst weiß. False. Sowas stellt sich oft als problematisch heraus, weil "schwarz" eben nicht dasselbe wie "wahr" ist, und so verheddern sich viele sehr schnell in ihrem Code. Die Regel "schwarz entspricht wahr" muß man im Kopf immer mit herumschleppen, sie geht nirgendwo logisch aus dem Code hervor. Du kannst sowas in Kommentaren vermerken, aber letztendlich macht es das nicht besser.

Und spätestens wenn du dein klassisches Schach zum Drei-Personen-Schach aufbläst, ist es so oder so vorbei mit Booleans. Eine logische, in sich schlüssige Herangehensweise sollte aber unabhängig von der Anzahl der Elemente sein, die du verwalten willst. Zumindest innerhalb sinnvoller Grenzen. Sowas wie myColor = Color.BLACK hingegen ist eineindeutig, es macht keine Knoten im Gehirn, es ist selbsterklärend. Und es funktioniert noch, wenn mehr als eine weitere Farbe hinzukommt.


Das ganz große Geheimnis zur Lösung aller komplexen Probleme ist, die Komplexität aufzulösen. An einem großen Brocken verschluckst du dich normalerweise nur, wenn du den im Ganzen runterschlingst. Aber den großen Brocken in viele leichte Happen zerlegen und diese nacheinander abfrühstücken, da ist die Wahrscheinlichkeit hoch daß du das gelöst bekommst.
 

berndoa

Top Contributor
Der Nutzen ist zuerst mal, daß du als Mensch damit mehr anfangen kannst. Mit Literalen wie MONTAG, DIENSTAG,...SONNTAG können die meisten Menschen etwas anfangen, der Compiler macht da am Ende einfache Integers draus (zumindest in C macht er das so).
Und MONTAG, DIENSTAG,...SONNTAG haben für dich eine andere Bedeutung als z.B. ROT, GELB, GRÜN, die komplett verloren geht wenn du anstatt solcher Konstanten einfache Integers nimmst. Wertfolgen wie 0, 1,...6 und 0, 1,...6 tragen nicht dieselbe Bedeutung, du siehst dem Integer ja nichts an, was über seinen reinen Zahlenwert hinausgeht.
Aber z.B. in ein Array, wo du MONTAG, DIENSTAG,...SONNTAG parken kannst, kannst du nicht ROT, GELB, GRÜN reinwerfen, da meckert der Compiler.

Ich habe vom programmieren ja eigentlich keine Ahnung (ich bin E-Techniker), aber eines kann man beim Programmieren nicht als wichtig genug erachten: Etwas, z.B. Ausdrücken, Bedeutung zuzuweisen.

Ein kleines Beispiel: Nehmen wir an, du programmierst ein Schachspiel. Es gibt ja zwei Farben, schwarz und weiß. Es kommt durchaus häufig vor daß die Leute auf die Idee kommen die Farbe jetzt in einem Boolean zu codieren. Wenn schwarz, dann true, sonst weiß. False. Sowas stellt sich oft als problematisch heraus, weil "schwarz" eben nicht dasselbe wie "wahr" ist, und so verheddern sich viele sehr schnell in ihrem Code. Die Regel "schwarz entspricht wahr" muß man im Kopf immer mit herumschleppen, sie geht nirgendwo logisch aus dem Code hervor. Du kannst sowas in Kommentaren vermerken, aber letztendlich macht es das nicht besser.

Und spätestens wenn du dein klassisches Schach zum Drei-Personen-Schach aufbläst, ist es so oder so vorbei mit Booleans. Eine logische, in sich schlüssige Herangehensweise sollte aber unabhängig von der Anzahl der Elemente sein, die du verwalten willst. Zumindest innerhalb sinnvoller Grenzen. Sowas wie myColor = Color.BLACK hingegen ist eineindeutig, es macht keine Knoten im Gehirn, es ist selbsterklärend. Und es funktioniert noch, wenn mehr als eine weitere Farbe hinzukommt.


Das ganz große Geheimnis zur Lösung aller komplexen Probleme ist, die Komplexität aufzulösen. An einem großen Brocken verschluckst du dich normalerweise nur, wenn du den im Ganzen runterschlingst. Aber den großen Brocken in viele leichte Happen zerlegen und diese nacheinander abfrühstücken, da ist die Wahrscheinlichkeit hoch daß du das gelöst bekommst.
Was ich eher meinte:
Warum kann ich dann nicht einfach
Java:
String meineFarbe="ROT";
machen, statt ein Enum mit ROT drin zu machen?


Oder gehts wieder drum dass bspw. ein Australier, der im leben nie meinen Code in die Hand kriegen wird, nicht im hinterkopf behalten musss dass es schwarz und rot gibt, sondern dass bei dem Enum ablesen kann?

Kann man denn Enums , so wie Strings, auch vergleichen?
Also gibts da ein Äquivalent zu "Rot".equals("Schwarz")?
 

fhoffmann

Top Contributor
Warum kann ich dann nicht einfach
Java:
String meineFarbe="ROT";
machen, statt ein Enum mit ROT drin zu machen?
Wenn du etwas schreibst wie
Java:
if (aktuelleFarbe.equals("ROTT")) {
    // tu Was
}
bekommst du keine Compilerfehler (einfach zu korrigieren) sonder dein Programm läuft brav durch - es tut nur nicht, was es tuen soll (sehr schwer zu finden, woran es liegt).
 

Neumi5694

Top Contributor
Wenn du eine begrenzte Wertemenge hast, verwende immer Enums.
Und ja, natürlich kann man Enums auch vergleichen. Die equals-Methode existiert auch dafür, sind sogar noch viel besser einsetzbar als für String.

Java:
Cardcolor val1 = Cardcolor.RED;
Cardcolor val2 = Cardcolor.BLACK;
boolean isSame = val1.equals(val2);
boolean isAlsoSame = val1 == val2;

//Hier wird der Compiler jammern, weil nicht alle Fälle abgedeckt sind. Sehr praktisch.
boolean thatsAString = switch (val1) {
        case Red -> "roterString";
        //case Black -> "schwarzerString"
};

Du kannst der Klasse Cardcolor auch noch Hilfsmethoden hinzufügen, z.B.
Java:
enum Cardcolor {
    boolean isRed() {
        return this == RED;
    }

    boolean isBlack() {
        return this == BLACK;
    }
   
    static Cardcolor getCardColorFor(String key) {
        if (key == null) {
            return null;
        } else {
            return switch (key.trim().toLowerCase()) {
                    "red","rot" -> CardColor.RED;
                    "schwarz","black" -> CardColor.BLACK;
                    //Hier braucht's einen Default, als String kann auch was anderes reinkommen.
                    default -> throw new SomeException("Unsupported: ['" + key + ']" );
            };
        }
    }
}
 

White_Fox

Top Contributor
Oder gehts wieder drum dass bspw. ein Australier, der im leben nie meinen Code in die Hand kriegen wird, nicht im hinterkopf behalten musss dass es schwarz und rot gibt, sondern dass bei dem Enum ablesen kann?

Hast du schonmal an deinem eigenen Code gearbeitet, nachdem z.B. ein Jahr vergangen ist? ;)


Kann man denn Enums , so wie Strings, auch vergleichen?
Also gibts da ein Äquivalent zu "Rot".equals("Schwarz")?
Klar kannst du das. Und noch viel mehr.
 

KonradN

Super-Moderator
Mitarbeiter
Also es ist schon sehr viel gesagt worden was alles Richtig war. Ich möchte es nur Ergänzen.

Eine Enumeration ist in Java eine spezielle Klasse von der es nur eine feste Anzahl Instanzen gibt. Man kann keine weiteren Instanzen erzeugen.

Damit gibt es eine feste Menge an Instanzen.

Jede Instanz hat einen klaren Typ, halt die Enumeration.

Und da es eine Klasse ist, kann es weitere Informationen und Verhalten geben.

Das macht die große Stärke aus. Es ist eben nicht einfach ein Typ, von dem es noch mehr Werte geben kann oder dessen Verhalten wir nicht verändern können.

Kann man denn Enums , so wie Strings, auch vergleichen?
Also gibts da ein Äquivalent zu "Rot".equals("Schwarz")?
Da es nur eine feste Anzahl Instanzen gibt, reicht es, die Referenzen zu vergleichen. Ein equals ist nicht notwendig. Es reicht ein einfaches == aus.
 

temi

Top Contributor
Warum kann ich dann nicht einfach
Java:
String meineFarbe="ROT";
machen, statt ein Enum mit ROT drin zu machen?
Du kannst halt mit einer Enum Typsicherheit erreichen.
Java:
final static int COLOR_RED = 1;

void setColor(int color) {
    // ..
}

Es kann dich niemand daran hindern, dieser Methode ein final static int ANSWER = 42; zu übergeben, obwohl es offensichtlich völliger Quatsch ist.

Im Gegensatz dazu:
Java:
enum Color { RED, GREEN, YELLOW }

void setColor(Color color) {
    // ..
}

Dieser Methode musst du eine der in der Enum definierten Farben übergeben, sonst compiliert der Code nicht.
 
Zuletzt bearbeitet:

White_Fox

Top Contributor
Mal noch ein ganz anderes Beispiel:
Was ich eher meinte:
Warum kann ich dann nicht einfach
Java:
String meineFarbe="ROT";
machen, statt ein Enum mit ROT drin zu machen?

Schau dir mal diese beiden Klassen an:

Java:
public class Animal{
    int age;
    String name;
    
    public int getAge(){return age;}
    public String getName(){return name;}
}

public class Human{
    int age;
    String name;
    
    public int getAge(){return age;}
    public String getName(){return name;}
}

Siehst du den Unterschied? Beide Klassen sind ja eigentlich, vom Namen mal abgesehen, völlig gleich. Eigentlich könnte man ja jetzt hergehen und anstatt diese beiden Klassen zu haben, einfach eine generische Klasse verwenden. Nur eine Klasse anstatt derer zwei.

Ja...könnte man machen. Der Comuter weiß sowieso nicht was eine Klasse ist. Mit age und name kann der Computer auch nix anfangen, da kann jede beliebige Zeichenfolge stehen. Deshalb macht der Compiler da am Ende auch eine Speicheradresse draus. Und die Klasse selbst braucht der Rechner auch nicht, da bleiben am Ende lediglich die Instanzvariablen und die Methoden übrig.

Jetzt kann es aber dennoch sinnvoll sein, genau solche Klassen zu haben. Du kannst z.B. noch eine Klasse "Flock" programmieren. Dieser könntest du z.B. weitere Animal-Objekte hinzufügen, aber keine Humanobjekte. Ein Tier kann bestimmt in eine Herde aufgenommen werden, aber ein Mensch ganz sicher nicht.

Mit dem Erstellen einer Klasse machst du nämlich noch was anderes: Du legst den Verwendungsbereich von int age und String name fest. Indem du diese Variablen in einer Klasse unterbringst, legst du noch weitaus mehr fest als daß es sich um ein Integer handelt, dem du den Namen "age" gegeben hast.

Schau mal:
Java:
public enum PrimaryColor{
    RED,
    GREEN,
    BLUE
}

public enum AlertLevel{
    RED,
    GREEN,
    BLUE
}

Dieselbe Bezeichnung, aber durch die Enumeration in einen wohldefinierten Kontext gezwungen. RED ist in jedem Fall absolut eineindeutig, es gibt keine zweite Interpretationsmöglichkeit. Und damit keinen Spielraum für Mißverständnisse.
Das bekommst du mit Strings so niemals hin.

Das ist ungefähr das, was ich weiter oben mit "Bedeutung zuweisen" gemeint habe.
 

berndoa

Top Contributor
Nachtrag: Für den OOP-Muffel mal ein Beispiel:

Java:
public enum Cardvalue{
    SEVEN(7),
    EIGHT(8),
    NINE(9),
    TEN(10),
    JACK(10),
    QUEEN(10),
    KING(10),
    ACE(11);
   
    private final int numericValue;
   
    private Cardvalue(int numericValue){
        this.numericValue = numericValue;
    }
   
    public int getNumericValue(){
        return numericValue;
    }
}
Huh, vielleicht sollte ich mir Enums doch mal angucken.
Ich verstehe zwar noch nicht wie ich bspw. zu SEVEN die zugehörige 7 kriege (sowas wie Cardvalue.SEVEN.getNumericValue() oder so?)
aber damit könnte ich mir ein paar Maps sparen.

Falls ich mich entscheiden sollte, grundsätzlich mit den Kartennamen an sich zu arbeiten.

@White_Fox: Welches Programm/Problem meinst du?
Ich habe Vieles was ich irgendwnan mal anfing und so vor sich hindümpelt bis ich alle paar Wochen mal wieder reingucke und es weiterschreibe.

Falls es irgendwas mit Roulettebot zu tun hat:
Joa, der ist an sich fertig, wobei ich noch gern die Dauer der Aktionen standardisieren will. Weil es halt einfach Sinn macht.
Aber ansosnten geht er.
Auch wenn der Code hier Jedem der hocheffizienten OOPler vermutlich Augenkrebs geben würde weil nicht schön aber funktional.
Die eine Klasse hat halt auch so um die 20 Methoden und genauso viele Attribute :)

Habe halt auch alle möglichen Teilkonzepte da rein gequetscht und importe wie verrückt :)




Mal so generell gesprochen, gibt es eigentlich einen guten Datentyp, mit dem man das umsetzen kann was man mathematisch eine bijektive Funktion nennt?
Weil bspw. gerade bei der Roulettesachen habe ich eine Map, die Strings ints zuweist.
und eine weitere Map, die die Gegenrichtung macht.
Es funktioniert, aber halt ein Objekt für beide Richtungen zu haben wäre praktisch. :)
 

Staarfightaar

Bekanntes Mitglied
Java:
public enum EXIT_CODE {
    A(104), B(203);

    private int numVal;

    EXIT_CODE(int numVal) {
        this.numVal = numVal;
    }

    public int getNumVal() {
        return numVal;
    }
}
danmit kannst du enum werten direkt werte zuteilen

da in java enum werte auch objekte sind musst du sie als solche auch behandeln... die C familie handelt das anders

Mal so generell gesprochen, gibt es eigentlich einen guten Datentyp, mit dem man das umsetzen kann was man mathematisch eine bijektive Funktion nennt?
Es funktioniert, aber halt ein Objekt für beide Richtungen zu haben wäre praktisch.
dann bau eine klasse?
es dreht sich bei dir immer im kreis
du: "was für ein datentyp"
java forum: "bau ne klasse"
du: "mag keine klassen"
java forum: "ok dann nicht"
du: "wie kann ich dieses und jenes... und was für ein datentyp"...
 

berndoa

Top Contributor
Java:
public enum EXIT_CODE {
    A(104), B(203);

    private int numVal;

    EXIT_CODE(int numVal) {
        this.numVal = numVal;
    }

    public int getNumVal() {
        return numVal;
    }
}
danmit kannst du enum werten direkt werte zuteilen

da in java enum werte auch objekte sind musst du sie als solche auch behandeln... die C familie handelt das anders


dann bau eine klasse?
es dreht sich bei dir immer im kreis
du: "was für ein datentyp"
java forum: "bau ne klasse"
du: "mag keine klassen"
java forum: "ok dann nicht"
du: "wie kann ich dieses und jenes... und was für ein datentyp"...
Klar kann man sich für Alles eine Klasse bauen.
Wenn ich schon so frage, meine ich natürliche einen FERTIGEN Datentyp.

Hier werden doch sosnt auch immer die exotischsten Datentypen erwähnt, da gibts doch bestimmt was Passendes Fertiges? ;-)
 

White_Fox

Top Contributor
Huh, vielleicht sollte ich mir Enums doch mal angucken.
Wer bist du? Und was hast du mit dem echten berndoa gemacht?


@White_Fox: Welches Programm/Problem meinst du?
Ich habe Vieles was ich irgendwnan mal anfing und so vor sich hindümpelt bis ich alle paar Wochen mal wieder reingucke und es weiterschreibe.
Ich meine Folgendes:
Ich schreibe ein kleines Programm, habe an diesem jetzt aber ungefähr ein Jahr nicht mehr gearbeitet. Jetzt will ich wieder mal loslegen.
Wenn ich dieses Programm so geschrieben hätte wie ich irgendwann auch mal programmiert habe, würde ich heute vor einem riesigen Wust an Code sitzen und mich fragen, was zur Hölle ich da eigentlich machen wollte. Der Code hat, keine Ahnung, bestimmt >30,000 Codezeilen in über 100 Dateien.

Ich habe, bevor ich damit angefangen habe, dann auch mal was über OOP gelesen, auch darüber wie man Code strukturiert, und was dabei rauskommt wenn ich einfach die Ärmel hochkremple und mich ohne großen Plan ans Werk mache habe ich in meiner eigenen Profession bereits erfahren. Mit dem Ergebnis, das ich erreiche, wenn ich da strukturierter rangehe, bin ich weitaus zufriedener.
Und heute bin ich heilfroh, daß ich mir über Stil und Strukturen vorher halbwegs Gedanken gemacht habe.
Ich wäre da sonst irgendwann so steckengeblieben und würde es mangels Überblick einfach nie gebacken bekommen.
Tatsächlich war ich schon mehrmals an dem Punkt, mehrere tausend Codezeilen wegzuwerfen und nochmal neu anzufangen, weil es einfach zu viel zu unstrukturiertes zu chaotisches Zeugs gewesen ist. Es ist immer schwer am Anfang, aber letztendlich war das Ergebnis immer besser gewesen, als so weiterzuwurschteln.

Es soll ja Menschen geben, die ein maschinenartiges Gedächtnis haben und sich mühelos in wirklich schlimm chaotischen Codewüsten zurechtfinden und da tolle Sachen zustandebringen. Steve Wozniak hat (angeblich) direkt in Maschinencode (also nur 0 und 1) programmiert. Zuerst mit Bleistift auf Papier, und dann später - wenn er Zugang zu seinem Arbeitsrechner hatte - das Zeug abgetippt. Und das soll (angeblich) auch auf Anhieb funktioniert haben.

Ich will und kann nicht ausschließen, daß du ebenfalls zu diesen Naturgenies gehörst. Die Erfahrung lehrt aber, daß diese Menschen sehr, sehr selten sind, statistisch gesehen einfach nicht vorkommen.
 

Staarfightaar

Bekanntes Mitglied
Tatsächlich war ich schon mehrmals an dem Punkt, mehrere tausend Codezeilen wegzuwerfen und nochmal neu anzufangen, weil es einfach zu viel zu unstrukturiertes zu chaotisches Zeugs gewesen ist. Es ist immer schwer am Anfang, aber letztendlich war das Ergebnis immer besser gewesen, als so weiterzuwurschteln.
gleiche ist mir auch mit meiner javafx lib passiert

hab das ganze ding umgebaut und es ging halt dadurch dass ich nen plan hatte was ich wollte, auch ganz flüßig, bis ich zufrieden war

ohne oop wäre ich gescheitert, es wird sich halt immer als standard raus stellen dass man es beim ersten mal verkackt und dann überarbeitet...
zumindest bei mir so

und oop mit klassen kann man am einfachsten überarbeiten
 

White_Fox

Top Contributor
Hier - ohne Kommentar - mal eine Enumeration aus meinem Projekt von dem ich gesprochen habe. Um mal einen kleinen Einblick zu geben, wie sowas aussehen kann:

Java:
enum ValueType {
    NULL(Arrays.asList(), 0, 0),
    BYTE(Arrays.asList(byte.class, Byte.class), 1, 1),
    SHORT(Arrays.asList(short.class, Short.class), 2, 2),
    INTEGER(Arrays.asList(int.class, Integer.class), 3, 4),
    LONG(Arrays.asList(long.class, Long.class), 4, 8),
    FLOAT(Arrays.asList(float.class, Float.class), 5, 4),
    DOUBLE(Arrays.asList(double.class, Double.class), 6, 8),
    BOOLEAN(Arrays.asList(boolean.class, Boolean.class), 7, 1),
    CHAR(Arrays.asList(char.class, Character.class), 8, 2),
    STRING(Arrays.asList(String.class), 9, 0),
    OBJECT(Arrays.asList(Object.class), 10, 0),
    ARRAY(Arrays.asList(
            byte[].class, Byte[].class,
            short[].class, Short[].class,
            int[].class, Integer[].class,
            long[].class, Long[].class,
            float[].class, Float[].class,
            double[].class, Double[].class,
            boolean[].class, Boolean[].class,
            char[].class, Character[].class,
            String[].class,
            Object[].class
    ), 11, 0),
    ENUMERATION(Arrays.asList(Enum.class), 12, 0);

    private final List<Class> classes;
    private final int order;
    private final int byteWidth;

    private ValueType(List<Class> classes, int order, int byteWidth) {
        this.classes = classes;
        this.order = order;
        this.byteWidth = byteWidth;
    }

    int order() {
        return order;
    }

    int byteWidth() {
        return byteWidth;
    }

    /**
     * This method returns the according ValueType enumeration from an
     * object.
     *
     * @param o is the object.
     * @return the according ValueType enumeration.
     */
    static ValueType getMemberTypeFromObject(Object o) {
        if (o == null) {
            return NULL;
        }
        if (o.getClass().isArray()) {
            return ARRAY;
        }
        if (o.getClass().isEnum()) {
            return ENUMERATION;
        }

        return getMemberTypeFromClass(o.getClass());
    }

    /**
     * This method returns the according ValueType enumeration from an
     * Class object.
     *
     * @param cls is the class object.
     * @return the according ValueType enumeration.
     */
    static ValueType getMemberTypeFromClass(Class cls) {
        if (cls == null) {
            return NULL;
        }
        if (cls.isArray()) {
            return ARRAY;
        }
        if (cls.isEnum()) {
            return ENUMERATION;
        }

        for (ValueType type : values()) {
            if (!(type == NULL
                    || type == ARRAY
                    || type == ENUMERATION
                    || type == OBJECT)) {
                if (type.classes.contains(cls)) {
                    return type;
                }
            }
        }
        return OBJECT;
    }

    /**
     * This method returns the according ValueType enumeration from an
     * integer.
     *
     * @param order is the integer.
     * @return the according ValueType enumeration.
     */
    static ValueType getMemberTypeFromOrder(int order) {
        switch (order) {
            case 0:
                return NULL;
            case 1:
                return BYTE;
            case 2:
                return SHORT;
            case 3:
                return INTEGER;
            case 4:
                return LONG;
            case 5:
                return FLOAT;
            case 6:
                return DOUBLE;
            case 7:
                return BOOLEAN;
            case 8:
                return CHAR;
            case 9:
                return STRING;
            case 10:
                return OBJECT;
            case 11:
                return ARRAY;
            case 12:
                return ENUMERATION;
            default:
                return null;
        }
    }

    /**
     * Returns a ValueType enumeration from the canonical classname of
     * an object.
     *
     * @param classname is the canonical class name.
     * @return an according ValueType enumeration.
     */
    static ValueType getMemberTypeFromClassname(String classname) {
        if (classname.equals("")) {
            return NULL;
        }

        if (classname.startsWith("[")) {
            return ARRAY;
        }

        try {
            Class<?> cls = Class.forName(classname);
            if (cls.isEnum()) {
                return ENUMERATION;
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        for (ValueType type : values()) {
            for (Class cls : type.classes) {
                if (cls.getName().equals(classname)) {
                    return type;
                }
            }
        }
        return OBJECT;
    }
}
 

mihe7

Top Contributor
Tatsächlich war ich schon mehrmals an dem Punkt, mehrere tausend Codezeilen wegzuwerfen und nochmal neu anzufangen, weil es einfach zu viel zu unstrukturiertes zu chaotisches Zeugs gewesen ist. Es ist immer schwer am Anfang, aber letztendlich war das Ergebnis immer besser gewesen, als so weiterzuwurschteln.
Exploratives Programmieren :cool:

Steve Wozniak hat (angeblich) direkt in Maschinencode (also nur 0 und 1) programmiert. Zuerst mit Bleistift auf Papier, und dann später - wenn er Zugang zu seinem Arbeitsrechner hatte - das Zeug abgetippt. Und das soll (angeblich) auch auf Anhieb funktioniert haben.
Tatsächlich finde ich das nicht besonders, zumindest nicht bei den damaligen Prozessoren. Ein MOS 6502 ist eine 8-Bit CPU, es gibt nur eine Hand voll Register und die Opcodes sind halbwegs systematisch aufgebaut. Da merkt man sich statt INX eben E8. Nicht, dass ich mir das angetan hätte aber z. B. wusste ich seinerzeit auch die meisten Belegungen der Speicheradressen auswendig, das ergibt sich einfach.
 

berndoa

Top Contributor
Was mich ja mal interessieren würde:
Wenn ich, wie ich es schon hatte, bspw. eine großes int[][] Array habe.
Was ist da performancemässig und so besser:

Eben direkt dieses zweidimensionale Array zu haben und zu bearbeiten?

Oder irgendwie eine Klasse A benutzen, die intern ein int[] Array hat.
Und dann eine Klasse B, die wieder ein A[] Array als Attribut hat,
natürlich Beides mit Methoden, konstruktor, etc. pp. Gettern, Settern, etc.

Was ist da performancemässig besser?

Weil wenn ich so über den OOP Ansatz nachdenke:
Es muss für jedes Objekt A ja das zugehörige int[] Array hinterlegt werden, die ganze Struktur gespeichert werden;
gleiches nochmal für das Objekt B.

Will sagenb, da braucht es massig objekte, Referenzen und so, das braucht doch gut Performance und Speicher, oder?

Wobei es beim primitiven int[][] ohne OOP ziemlich genau Dimensionslänge1+Dimensionslänge1*Dimensionslänge1 Memory Einträge braucht.

Was ist da effizienter performance und memory mässig?

Ich weiß, bei üblichem Gebrauch merkt man wenig davon.
Aber wenn es bspw. um ein int[10000000][10000000], würde man vermutlciuh schon einen untershcied merken (bei meinen verkorksten lottoproblemen kommen ja mal recht große zahlen zusammen, wo int bald nicht mal ausreicht)
 

berndoa

Top Contributor
Wer bist du? Und was hast du mit dem echten berndoa gemacht?



Ich meine Folgendes:
Ich schreibe ein kleines Programm, habe an diesem jetzt aber ungefähr ein Jahr nicht mehr gearbeitet. Jetzt will ich wieder mal loslegen.
Wenn ich dieses Programm so geschrieben hätte wie ich irgendwann auch mal programmiert habe, würde ich heute vor einem riesigen Wust an Code sitzen und mich fragen, was zur Hölle ich da eigentlich machen wollte. Der Code hat, keine Ahnung, bestimmt >30,000 Codezeilen in über 100 Dateien.

Ich habe, bevor ich damit angefangen habe, dann auch mal was über OOP gelesen, auch darüber wie man Code strukturiert, und was dabei rauskommt wenn ich einfach die Ärmel hochkremple und mich ohne großen Plan ans Werk mache habe ich in meiner eigenen Profession bereits erfahren. Mit dem Ergebnis, das ich erreiche, wenn ich da strukturierter rangehe, bin ich weitaus zufriedener.
Und heute bin ich heilfroh, daß ich mir über Stil und Strukturen vorher halbwegs Gedanken gemacht habe.
Ich wäre da sonst irgendwann so steckengeblieben und würde es mangels Überblick einfach nie gebacken bekommen.
Tatsächlich war ich schon mehrmals an dem Punkt, mehrere tausend Codezeilen wegzuwerfen und nochmal neu anzufangen, weil es einfach zu viel zu unstrukturiertes zu chaotisches Zeugs gewesen ist. Es ist immer schwer am Anfang, aber letztendlich war das Ergebnis immer besser gewesen, als so weiterzuwurschteln.

Es soll ja Menschen geben, die ein maschinenartiges Gedächtnis haben und sich mühelos in wirklich schlimm chaotischen Codewüsten zurechtfinden und da tolle Sachen zustandebringen. Steve Wozniak hat (angeblich) direkt in Maschinencode (also nur 0 und 1) programmiert. Zuerst mit Bleistift auf Papier, und dann später - wenn er Zugang zu seinem Arbeitsrechner hatte - das Zeug abgetippt. Und das soll (angeblich) auch auf Anhieb funktioniert haben.

Ich will und kann nicht ausschließen, daß du ebenfalls zu diesen Naturgenies gehörst. Die Erfahrung lehrt aber, daß diese Menschen sehr, sehr selten sind, statistisch gesehen einfach nicht vorkommen.
Also, das bin vermutlich nur ich, aber ich blicke eher noch 7zumindest in meinem Code) durch wenn ich sehe "Ah, die Methode nimmt ein int[] , macht das, wird einen String raus.

oder ruft hier die Methode XY auf, deren Signatur ich mit strg+f schnell finde.

Ich frage mich eher wie Leute Sachen auf github, die sie nicht selbst programmiert haben , verstehen.

Ich meine, ich komme da hin, es heißt "Yo, hier ist mein kleines Skript zum invertieren der Buchstaben eines Strings" oder so.
Und dann guckt man und da sieht man 20 Ordner mit kryptischen Namen a la "bin" "dat" "src" etc.
klickt man drauf, findet man darin weitere kryptische unterordner, 5 jar files, 4 dlls, etc. pp.

Und selsbt im klassencode durchblickt man nicht wirklich was da passiert.

Da gucke ich dann rein, die Klasse hat womöglich eine einzige 4 Zeiler methode, in der 3 Befehle oder Codearten vorkommen, die ich so im leben noch nie gesehen habe.
(und die Klasse erstellt dann mit 5 random Argumenten ein Objekt einer anderen klasse.
gucke ich in die andere klasse, sind da 20 methoden, wobei in jeder wieder objekte anderer klassen erzeugt und benutzt werden.
Da hat man dann 20 Klassen auf, die irgendwelche objekte voneinander erzeugen und verwenden.
Und ich nur so "wie zur Hölle will man denn da durchblicken was das überhaupt tut, so zerstückelt wie das ist?"
und ich hock mich bestimmt nicht hin und zeichne Tafelweise Objektdiagramme wie welche Methoden welcher klasse wovon benutzt und aufgerufen werden. Wenn man nicht selbst diese 20 klassen programmiert hat, wie soll man da als Aussenstehender durchblicken wie dieses Geflecht zusammenhängt und was das Teil eigentlich insgesamt gesehen tut?

Ich mache github auf, sehe diesen Wust aus Klassen und Ordnern und machst wieder zu mit einem "Nope, not happening!" und suche anderswo nach einem vielzeiler, der das Gewünschte auch tut.)

Ich weiß nicht, ich finde sowas wie man es bei github findet einfach nur undruchsichtig wie nochwas.
Oder ich weiß einfach nicht, wwie man Github "richtig liest" wenn man mit so einem ordnerungetüm konfrontiert wird.


Was mich alleine an OOP schon nervt, ist halt dass man immer überlegen muss wie erreiche ich überhaupt welche Objekt einer Klasse und kriege oder manipuliere deren Attribute?

Wenn Alles in einer Klasse ist, kann ich "dauerhafte" Sachen einfach als Attribut aufführen, jede Methode in der Klasse kann drauf zugreifen und gut.

Aber strukturiert ist das halt vermutlich nicht :)
 
Y

yfons123

Gast
Also, das bin vermutlich nur ich, aber ich blicke eher noch 7zumindest in meinem Code) durch wenn ich sehe "Ah, die Methode nimmt ein int[] , macht das, wird einen String raus.

oder ruft hier die Methode XY auf, deren Signatur ich mit strg+f schnell finde.

Ich frage mich eher wie Leute Sachen auf github, die sie nicht selbst programmiert haben , verstehen.

Ich meine, ich komme da hin, es heißt "Yo, hier ist mein kleines Skript zum invertieren der Buchstaben eines Strings" oder so.
Und dann guckt man und da sieht man 20 Ordner mit kryptischen Namen a la "bin" "dat" "src" etc.
klickt man drauf, findet man darin weitere kryptische unterordner, 5 jar files, 4 dlls, etc. pp.
du weist dass dein code genauso kryptisch für außenstehende erscheint?
Da gucke ich dann rein, die Klasse hat womöglich eine einzige 4 Zeiler methode, in der 3 Befehle oder Codearten vorkommen, die ich so im leben noch nie gesehen habe.
(und die Klasse erstellt dann mit 5 random Argumenten ein Objekt einer anderen klasse.
gucke ich in die andere klasse, sind da 20 methoden, wobei in jeder wieder objekte anderer klassen erzeugt und benutzt werden.
Da hat man dann 20 Klassen auf, die irgendwelche objekte voneinander erzeugen und verwenden.
du hast schlechtes design entdeckt... level up :D

Wenn man nicht selbst diese 20 klassen programmiert hat, wie soll man da als Aussenstehender durchblicken wie dieses Geflecht zusammenhängt und was das Teil eigentlich insgesamt gesehen tut?
wenn man sich mühe gibt hat man mini schnittstellen, wo man alles benutzen kann.. schreib ich später noch was dazu

Ich mache github auf, sehe diesen Wust aus Klassen und Ordnern und machst wieder zu mit einem "Nope, not happening!" und suche anderswo nach einem vielzeiler, der das Gewünschte auch tut.)

Ich weiß nicht, ich finde sowas wie man es bei github findet einfach nur undruchsichtig wie nochwas.
Oder ich weiß einfach nicht, wwie man Github "richtig liest" wenn man mit so einem ordnerungetüm konfrontiert wird.
ja ... es gibt halt hobby programmierer die ziemlich daneben langen... und das in einer unvorstellbaren art und weise

möchte dir mal zwei beispiele nennen
1. in unity hab ich ein projekt mit 27 klassen gedownloaded das hashmaps im editor serialisiert und hashmaps für unity spezifisch verändert
um das "gewust zu nutzen" extendest du von 1er einzigen klasse, alle anderen sind unwichtig
diese schnittstelle ist so deppen einfach zu nutzen dass es mich begeistert hat wie derjenige das gebacken gekriegt hat
2. meine rapidfx lib hat ka ... 30 klassen? brauchen tust du ansich nur den ordner mit den simple klassen, das sind 5 - 7 , wo nur ein mini unterschied ist ansich ... eig braucht man für alles nur 2 simple klassen und von denen 1e methode die überschrieben wird

in der überschriebenen methode ruft man methoden aus einer anderen klasse auf ... die hat 2 methoden... also 2 klassen + 2 methoden um das framework zu nutzen


wenn man sich mühe gibt kriegt mans gebacken eine api hinzukriegen die nutzbar ist...aber jeder dödel kann auf github posten ...
wenn du mal zeit hast , geh auf twitch und auf software und spieleentwicklung und schau dann mal den leuten beim coden zu...
es ist faszinierend wie die mit dem code umgehen können wenn die so ein gewust hinballern

du bist halt bei den mini projekten wo es um mathematik geht und nicht um klassen design hauptsächlich... rate mal warum python so beliebt ist für mathematische probleme ???
oder powershell für einfache probleme ?

und jetzt rate warum diese nicht geeignet sind für große probleme..
Was mich alleine an OOP schon nervt, ist halt dass man immer überlegen muss wie erreiche ich überhaupt welche Objekt einer Klasse und kriege oder manipuliere deren Attribute?
getter und setter sollten bekannt sein ?
Wenn Alles in einer Klasse ist, kann ich "dauerhafte" Sachen einfach als Attribut aufführen, jede Methode in der Klasse kann drauf zugreifen und gut.
du kannst auch alles in eine zeile schreiben :)
seit über 20 jahre gibts protected private und public in java , denkst du nicht dass sich das als sinnvoll heraus gestellt hat?
PS ich bin staarfightaar auf anderem acc... weil firefox das account verwalten nicht gebacken gekriegt hat...
 

mihe7

Top Contributor
Ich meine, ich komme da hin, es heißt "Yo, hier ist mein kleines Skript zum invertieren der Buchstaben eines Strings" oder so.
Und dann guckt man und da sieht man 20 Ordner mit kryptischen Namen a la "bin" "dat" "src" etc.
klickt man drauf, findet man darin weitere kryptische unterordner, 5 jar files, 4 dlls, etc. pp.
LOL. Ja, das kommt dann daher, weil mancher meint, z. B. Apache Commons einbinden zu müssen, nur um zu prüfen, ob ein String leer ist. Dann ist der Java-eigene Logger natürlich zu gering, da braucht man schon was anständiges: ein Logging-Framework muss her und damit man sich später noch umentscheiden kann, haut man noch eine Fassade davor.

Da hat man dann 20 Klassen auf, die irgendwelche objekte voneinander erzeugen und verwenden.
Und ich nur so "wie zur Hölle will man denn da durchblicken was das überhaupt tut, so zerstückelt wie das ist?"
Das kann man pauschal nicht sagen. Natürlich kann man auch mit fünf Klassen völlig undurchblickbaren Mist programmieren, das ist aber nicht das Ziel. Man will möglichst gute Abstraktionen haben, um Code zu schreiben, der selbsterklärend ist.

Du verwendest ja auch problemlos zig Klassen und Typen, die Java mitbringt, ohne in den Quelltext schauen zu müssen.

Um nochmal auf Deinen Eingangspost zurückzukommen:
Selbst die hochgefeirtte objektorientierung scheint mir da nur wenig hilreich zu sein weil es mehr um ein strategisches Problem und keine Schöhnheitsvergleiche
geht :-/
OO ist nicht die Lösung für alles und auch nicht immer die beste Lösung. Beispielsweise habe ich Dir oben nur eine for-Schleife hingeklatscht - das hat nichts mit OO zu tun sondern zielte nur auf den Punkt "alle sinnvollen Kombinationen durchgehen" ab. Wenn man das Problem generalisieren will, lässt sich das natürlich objekt-orientiert angehen.
 

White_Fox

Top Contributor
Was ist da effizienter performance und memory mässig?

Schwer zu sagen. Das fängt schon damit an, daß der Schwerpunkt in Java (und vielen anderen modernen Programmiersprachen) nicht auf effizientem Code liegt.

Und dann stellt sich schon die Frage, was effizient heißt: Wenig Rechenleistung benötigen, oder wenig Speicher benötigen? Beides sind oft schonmal gegensätzliche Anforderungen. Du kannst dein Programm stark beschleunigen, wenn du dich auf viel Speicher austoben kannst, du kannst aber viel Rechenzeit investieren und dafür wenig Speicher benötigen.

Wie dein Code am schnellsten oder speicherärmsten auf deiner Hardware läuft, hängt ganz wesentlich von zwei Dingen ab:
  • von deiner Hardware
  • davon, was der Compiler (und evt. Unterbau wie der JVM in Java) daraus macht.
Eine ganz wesentliche Funktion von Hochsprachen ist, von der Hardware wegzuabstrahieren. Das gilt für alle Hochsprachen, auch für sowas Primitives wie C (auch wenn C gelegentlich als Assembler mit syntaktischem Zucker bezeichnet wird).
Es gibt hin und wieder Leute, die behaupten, daß ein Programm schneller läuft, wenn man auf bestimmte Konstrukte verzichtet oder bestimmte Konstrukte bevorzugt benutzt. Z.B. lieber negierte UND-Operationen anstelle von ODER-Operationen oder dergleichen.
Aber das ist durch die Bank weg Blödsinn. Selbst wenn man seinen Compiler so genau studiert hat daß man seinen Quellcode derart optimieren könnte: Schon mit der nächsten Compilerversion (oder gar einem anderen Compiler) kann (oder wird) das alles wieder anders sein. Und dann ist ja immer noch die Frage, auf was für Hardware denn das Programm läuft: ist das irgendein alter schwachbrüstiger Pentium von vor 20 Jahren mit einem einzigen Rechenkern, oder eine moderne Multicore-CPU mit hunderten von Arbeitsregistern, die gleich mehrere Rechenoperationen im selben Takt ausführt, über eine Pipeline und noch zig weiteren Rafinessen verfügt?

Meiner Meinung nach optimiert man, wenn man mehr Effizienz haben will, auf genau zwei Weisen:
  • in Assembler
  • oder gar nicht
Denn wie gesagt, du kannst aus Hochsprachenebene heraus nicht sagen, was die Maschine genau macht. Du kannst z.B. eine Schleife formulieren, aber das bedeutet nicht daß der Prozessor tatsächlich eine Schleife ausführen wird.
Und um zu deiner Frage zurückzukommen: Ich würde mich nichtmal darauf verlassen, daß das Array, daß du in Java formulierst, in der Hardware tatsächlich ein klassisches Array (=zusammenhängender Speicherbereich) ist. Selbst wenn es für dein Programm wie ein zusammenhängender Speicherbereich aussieht ist damit immer noch nicht gesagt, daß dir die Speicherverwaltung deines Betriebssystems einen zusammenhängenden Speicherbereich zugewiesen hat.

Und letztendlich merkst du es ja selber:
Ich weiß, bei üblichem Gebrauch merkt man wenig davon.




Ich mache github auf, sehe diesen Wust aus Klassen und Ordnern und machst wieder zu mit einem "Nope, not happening!" und suche anderswo nach einem vielzeiler, der das Gewünschte auch tut.)

Ich weiß nicht, ich finde sowas wie man es bei github findet einfach nur undruchsichtig wie nochwas.
Oder ich weiß einfach nicht, wwie man Github "richtig liest" wenn man mit so einem ordnerungetüm konfrontiert wird.


Was mich alleine an OOP schon nervt, ist halt dass man immer überlegen muss wie erreiche ich überhaupt welche Objekt einer Klasse und kriege oder manipuliere deren Attribute?
Ich sag mal so: Du kannst jemandem das geilste und beste Werkzeug in die Hand drücken – wenn dieser Jemand zwei linke Hände hat und/oder einfach zu doof ist damit umzugehen, dann kommt da trotzdem nur Mist heraus.

Oder anders gesagt: Auch mit OOP muß man den Umgang lernen. Ich selber habe eine Vorlesung über Java im Studium gehabt, habe da aber nicht verstanden was OOP eigentlich ist. Das lag aber weniger an der Vorlesung, weil eine Vorlesung dafür einfach nicht reicht wenn du die Sprache selber erstmal noch lernen mußt. Mein Prof war schon froh, wenn wenigstens ein paar von uns den Unterschied zwischen der Klasse und einem Objekt verstanden haben. Aber was man damit jetzt Schönes machen kann? Keine Ahnung.
Mein Prof hat allerdings, als Beispiel dafür daß das vielleicht doch eine tolle Sache ist und um uns zu motivieren, mal von einem eigenen Projekt erzählt. Ein Programm das er zunächst rein prozedural (also nix mit OOP) geschrieben hat, war über 30.000 Codezeilen lang. Dann hat er es mal, auch um das Thema selber zu lernen, nochmal geschrieben, aber konsequent objektorientiert. Und dann waren es insgesamt nur noch 5.000 Codezeilen.

Ich selber habe OOP so halbwegs verstanden, während ich das Buch "Entwurfsmuster von Kopf bis Fuß" durchgearbeitet habe. Da habe ich überhaupt das erste Mal so den Hauch einer Ahnung bekommen, was Informatiker und speziell Softwarearchitekten so den ganzen Tag treiben (wie gesagt, ich komme aus der E-Technik).
 

berndoa

Top Contributor
du weist dass dein code genauso kryptisch für außenstehende erscheint?

du hast schlechtes design entdeckt... level up :D


wenn man sich mühe gibt hat man mini schnittstellen, wo man alles benutzen kann.. schreib ich später noch was dazu


ja ... es gibt halt hobby programmierer die ziemlich daneben langen... und das in einer unvorstellbaren art und weise

möchte dir mal zwei beispiele nennen
1. in unity hab ich ein projekt mit 27 klassen gedownloaded das hashmaps im editor serialisiert und hashmaps für unity spezifisch verändert
um das "gewust zu nutzen" extendest du von 1er einzigen klasse, alle anderen sind unwichtig
diese schnittstelle ist so deppen einfach zu nutzen dass es mich begeistert hat wie derjenige das gebacken gekriegt hat
2. meine rapidfx lib hat ka ... 30 klassen? brauchen tust du ansich nur den ordner mit den simple klassen, das sind 5 - 7 , wo nur ein mini unterschied ist ansich ... eig braucht man für alles nur 2 simple klassen und von denen 1e methode die überschrieben wird

in der überschriebenen methode ruft man methoden aus einer anderen klasse auf ... die hat 2 methoden... also 2 klassen + 2 methoden um das framework zu nutzen


wenn man sich mühe gibt kriegt mans gebacken eine api hinzukriegen die nutzbar ist...aber jeder dödel kann auf github posten ...
wenn du mal zeit hast , geh auf twitch und auf software und spieleentwicklung und schau dann mal den leuten beim coden zu...
es ist faszinierend wie die mit dem code umgehen können wenn die so ein gewust hinballern

du bist halt bei den mini projekten wo es um mathematik geht und nicht um klassen design hauptsächlich... rate mal warum python so beliebt ist für mathematische probleme ???
oder powershell für einfache probleme ?

und jetzt rate warum diese nicht geeignet sind für große probleme..

getter und setter sollten bekannt sein ?

du kannst auch alles in eine zeile schreiben :)
seit über 20 jahre gibts protected private und public in java , denkst du nicht dass sich das als sinnvoll heraus gestellt hat?
PS ich bin staarfightaar auf anderem acc... weil firefox das account verwalten nicht gebacken gekriegt hat...
Dass mein Code auf deutsch gesagt scheiße ist, wurde mir hier ja schon mehr oder minder eindeutig "durch die Blume" mitgeteilt, ist mir klar.

mein Fokus liegt halt auf den grundlegendsten, meist in Java shcon implementierten Datentypen wie String Java, Arrays, Schleifen, etc.
Weil ich da wenigstens weiß was ich tue (meistens) wenn ich sie benutze.
Klar sieht mein rein "prozedualer" Code wild aus.

Aber ich habe bspw. schon folgendes Problem:
in guter Informatikmanier soll man ja Aufgaben in Teilaufgaben und die immer weiter iN Teilaufgaben zerlegen.

Heißt, ich habe Aufgaben 1,2,3,4,5.
Jede davon zerlegt gibt mir Unteraufgaben 1.1,1.2,1.3, 2.1,2.2., usw.
Und, weil teils umständlich, jede davon nochmal zerlegt gibt Unterunteraufgaben 1.1.3 und Ähnliches.

Tja, im Endeffekt muss für jede dieser (Teil) aufgaben eine eigene Methode geschrieben sein.
heißt, es gibt eine Methode für Aufgabe 1,2,3,4,5.
Dann für jede Unteraufgabe eine.
Und nochmal für jede untetunteraufgabe eine.
Macht schon um die 20+ methoden für dieses Beispiel.

und java code kann man halt nur untereinander schreiben.

Da stellt sich dann shcon die Frage:
schreibe ich erst die (methoden der) aufgaben 1,2,3,4,5 hin und danach erst die unteraufgaben?
Oder erst aufgabe 1, dann unteraufgabe 1.1, dann unterunteraufgabe 1.1.1., usw.
so wie man es in einem inhaltsverzeichnis machen würde?

so oder so habe ich dann 20 methoden untereinander und wenn man wie ich als schreiberling nicht weiß wie diese methoden im aufgabe-unteraufgabe bezug stehen, sieht man nur mäassig Code, den der böse OOPP Verweigerer doch easy mittels Klassen lösen könnte -.-



Mein Wissen besteht zu 90% auch nur aus Uni Java Anfängerkursen, da streams und so zu kenne n ist shcon viel :)

Wie gesagt, man kann selbst eine Aufgabe wie "Speichere die zahlen 1-100 und deren zugehörige Quadratzahl in einem 2d Array" ausser direktauch mit Klassen lösen.
Eine Oberklasse "A" die die Gesamtliste an paaren enthält.
jedes Paar ist natürlich auch eine eigene Klasse, also enthält A insofern ein Paar[] Array.

Hier nicht zwingend, aber generell müsste man dann sowohl der A als auch der Paar Klasse getter Methoden, setter, Methoden, womöglich noch einejn oder mehrere Konstruktoren, etc. geben.

Kann man, klar, aber ganz ehrlich:
sieht sowas wie
Java:
System.out.println(werteliste[i][j]);
nicht besser aus als
System.out.println(A.get(i).get(j).asString);
oder Ähnliches?

Ich kenne halt üblicherweise auch nur sehr einfache Beispiele, die man in einer Vorlesungsübung machen würe und kein 100 Klassen projekt oder Ähnliches :-/

Ja, protected private und public gibts.
Schön für die die eine Bank App bauen.
Mich als Programmierer zwingt es aber nur, noch mehr getter methoden zu bauen und mir nun gedanken zu machen warum diese Klasse nicht auf die in er main methode der anderen klasse verwendete Methode der inneren Klasse zugreifen kann oder auch nicht.
Mich nervt shcon dass Java mich zwingt für Alles mögliche mit try catch Exceptions abzufangen wenn ich nicht hinter JAVA methode ein throws Exception schreiben will.

Aber sinnvoll ist der kram, keine Frage. Nur halt gutes Futter für viele Fehler und errors, derer ich so schon genug produziere :)
 

berndoa

Top Contributor
Schwer zu sagen. Das fängt schon damit an, daß der Schwerpunkt in Java (und vielen anderen modernen Programmiersprachen) nicht auf effizientem Code liegt.

Und dann stellt sich schon die Frage, was effizient heißt: Wenig Rechenleistung benötigen, oder wenig Speicher benötigen? Beides sind oft schonmal gegensätzliche Anforderungen. Du kannst dein Programm stark beschleunigen, wenn du dich auf viel Speicher austoben kannst, du kannst aber viel Rechenzeit investieren und dafür wenig Speicher benötigen.

Wie dein Code am schnellsten oder speicherärmsten auf deiner Hardware läuft, hängt ganz wesentlich von zwei Dingen ab:
  • von deiner Hardware
  • davon, was der Compiler (und evt. Unterbau wie der JVM in Java) daraus macht.
Eine ganz wesentliche Funktion von Hochsprachen ist, von der Hardware wegzuabstrahieren. Das gilt für alle Hochsprachen, auch für sowas Primitives wie C (auch wenn C gelegentlich als Assembler mit syntaktischem Zucker bezeichnet wird).
Es gibt hin und wieder Leute, die behaupten, daß ein Programm schneller läuft, wenn man auf bestimmte Konstrukte verzichtet oder bestimmte Konstrukte bevorzugt benutzt. Z.B. lieber negierte UND-Operationen anstelle von ODER-Operationen oder dergleichen.
Aber das ist durch die Bank weg Blödsinn. Selbst wenn man seinen Compiler so genau studiert hat daß man seinen Quellcode derart optimieren könnte: Schon mit der nächsten Compilerversion (oder gar einem anderen Compiler) kann (oder wird) das alles wieder anders sein. Und dann ist ja immer noch die Frage, auf was für Hardware denn das Programm läuft: ist das irgendein alter schwachbrüstiger Pentium von vor 20 Jahren mit einem einzigen Rechenkern, oder eine moderne Multicore-CPU mit hunderten von Arbeitsregistern, die gleich mehrere Rechenoperationen im selben Takt ausführt, über eine Pipeline und noch zig weiteren Rafinessen verfügt?

Meiner Meinung nach optimiert man, wenn man mehr Effizienz haben will, auf genau zwei Weisen:
  • in Assembler
  • oder gar nicht
Denn wie gesagt, du kannst aus Hochsprachenebene heraus nicht sagen, was die Maschine genau macht. Du kannst z.B. eine Schleife formulieren, aber das bedeutet nicht daß der Prozessor tatsächlich eine Schleife ausführen wird.
Und um zu deiner Frage zurückzukommen: Ich würde mich nichtmal darauf verlassen, daß das Array, daß du in Java formulierst, in der Hardware tatsächlich ein klassisches Array (=zusammenhängender Speicherbereich) ist. Selbst wenn es für dein Programm wie ein zusammenhängender Speicherbereich aussieht ist damit immer noch nicht gesagt, daß dir die Speicherverwaltung deines Betriebssystems einen zusammenhängenden Speicherbereich zugewiesen hat.

Und letztendlich merkst du es ja selber:






Ich sag mal so: Du kannst jemandem das geilste und beste Werkzeug in die Hand drücken – wenn dieser Jemand zwei linke Hände hat und/oder einfach zu doof ist damit umzugehen, dann kommt da trotzdem nur Mist heraus.

Oder anders gesagt: Auch mit OOP muß man den Umgang lernen. Ich selber habe eine Vorlesung über Java im Studium gehabt, habe da aber nicht verstanden was OOP eigentlich ist. Das lag aber weniger an der Vorlesung, weil eine Vorlesung dafür einfach nicht reicht wenn du die Sprache selber erstmal noch lernen mußt. Mein Prof war schon froh, wenn wenigstens ein paar von uns den Unterschied zwischen der Klasse und einem Objekt verstanden haben. Aber was man damit jetzt Schönes machen kann? Keine Ahnung.
Mein Prof hat allerdings, als Beispiel dafür daß das vielleicht doch eine tolle Sache ist und um uns zu motivieren, mal von einem eigenen Projekt erzählt. Ein Programm das er zunächst rein prozedural (also nix mit OOP) geschrieben hat, war über 30.000 Codezeilen lang. Dann hat er es mal, auch um das Thema selber zu lernen, nochmal geschrieben, aber konsequent objektorientiert. Und dann waren es insgesamt nur noch 5.000 Codezeilen.
Effizient im Sinne von "brennt mir nicht das Notebook durch" (leider auch wörtlich gemeint, mit 16 gb ram nicht unmöglich wenn man noch anderes auf hat und der Lüfter dreht wie nix. Hab leider noch kein modernes 19 zoll Notebook gefunden was mir preislich, praktishc und optisch zusagen würde als Nachfolger meines Toshibas. )
und "braucht keine Tage um eine Lsite mit 10^8 oder mehr Einträgen abzuarbeiten, halt Arbeitszeit minimieren pro Eintrag."

Ich selber habe OOP so halbwegs verstanden, während ich das Buch "Entwurfsmuster von Kopf bis Fuß" durchgearbeitet habe. Da habe ich überhaupt das erste Mal so den Hauch einer Ahnung bekommen, was Informatiker und speziell Softwarearchitekten so den ganzen Tag treiben (wie gesagt, ich komme aus der E-Technik).
Kenn ich jetzt nicht das Buch, was aber gar nicht sagen muss.
Da ich mich bis heute auch noch nicht dazu durchringen konnte, überhaupt mal das Inselbuch zu lesen .-)

Kenne OOP bloss aus der Vorlesung wo ich die meisten Anwendungen für overkill halte weil es direkt ohne Zwischenklassen für Alles direkter geht.
Wobei man da dann halt bspw. im Hinterkopf wissen muss wofür welche Tiefe eines mehrdimensionalen Arrays steht oder auch nicht :)
 

KonradN

Super-Moderator
Mitarbeiter
Da stellt sich dann shcon die Frage:
schreibe ich erst die (methoden der) aufgaben 1,2,3,4,5 hin und danach erst die unteraufgaben?
Oder erst aufgabe 1, dann unteraufgabe 1.1, dann unterunteraufgabe 1.1.1., usw.
so wie man es in einem inhaltsverzeichnis machen würde?
Das ist nicht festgelegt. Du kannst beides machen.

Das eine nennt sich Top-Down - Also Du fängst an mit einer Methode, in der Du dann weitere Methoden aufrufst, die dann im Anschluss geschrieben werden. Das geht ganz gut aber führt dann nach meiner Erfahrung leichter zu nicht testbarem Code.

Das Andere wäre Bottom-Up. Du überlegst also, was für grundlegende Dinge Du brauchst und fängst damit an. Darauf baust Du dann weiter auf. Das liegt mir deutlich besser aber setzt natürlich voraus, dass du wirklich erst einen Plan gemacht hast, was Du brauchst.

Daher wird es in der Praxis etwas auf eine Mischung hinaus laufen. Die erste Planung ist aber dann aber vermutlich kein Code sondern die Erfassung von Tasks zu User Stories Du hast also die Aufgabe A, B und C zu machen. Und das brichst Du dann auf in A1, A2, A3, ... B1, B2, ...... u.s.w.
Und das gehst Du dann bei der Entwicklung an.

Den nächsten Punkt, den ich sehe:
System.out.println(werteliste[i][j]);
vs.
System.out.println(A.get(i).get(j).asString());

Das Problem mit der ersten Variante ist, dass Du ein Implementationsdetail nach außen geben könntest. Ist es wirklich ein Array?

Bei der zweiten Variante sehe ich die Chance, dass Du zu tief Wissen brauchst: Du kennst A, was da das get liefert ... dann was darauf das get liefert und dann, dass es da ein asString geben muss.

Du solltest immer ein direktes Interface haben, das Du ansprichst. Du machst etwas mit dem Auto. Du greifst nicht direkt auf irgendwas zu a.la. getMotor().getZylinderKopfDichtung(3).getWhatever()
Im Auto machst Du etwas mit dem Motor. Implementierungsdetails interessieren Dich nicht!

Und bei Methoden hast Du die Kapselung. Also ein A.get(i,j) kann ja durchaus angeboten werden.

Und der Dtaentyp mus ja stimmen - wieso gibst Du das einmal einfach aus und einmal wird ein asString() notwendig? Meinte ggf. eine toString()? Ist also ggf. nicht direkt vergleichbar.

Ja, protected private und public gibts.
Schön für die die eine Bank App bauen.
Mich als Programmierer zwingt es aber nur, noch mehr getter methoden zu bauen und mir nun gedanken zu machen warum diese Klasse nicht auf die in er main methode der anderen klasse verwendete Methode der inneren Klasse zugreifen kann oder auch nicht.
Es geht hier nicht um Sicherheit vor Dritten wie bei einer Bank. Es geht um eine Ordnung, damit du klar kommst. Da geht es um Kapselung, also es Dir einfacher zu machen, Deine Code zu verstehen und zu nutzen.

Und viel Code ist "Boilerplate". Ganz klar. Den schreibst Du aber auch nicht mehr selbst:
Option 1) Du sagst der IDE: Ich will Getter und Setter für die und die Felder. Ich will ein hashCode und equals, ich will eine toString Methode und zack: fertig :)
Option 2) Du nutzt z.B. Lombok. Dann sagst Du nur noch, was Du willst. Dann sind das einfache kleine Annotations.
Option 3) Aktuelles Java bietet evtl. noch weitere Optionen. "Records" wäre hier dann ein Stichwort.

Der Kritikpunkt ist aber valide. Da bin ich gaz bei Dir. Aber die Optionen 1, 2 und 3 sind schon nicht schlecht. Es entwickelt sich halt weiter.

Aber ja - gerade bei kleineren Programmen sind dann evtl. andere Sprachen besser. So wurde ja auch schon python vor kurzem erwähnt, das halt dann gewisse Dinge nicht mehr braucht. Wobei ich da vieles nicht als Vorteil sehe. Aber schau Dir z.B. moderne Sprachen an. Die jüngste, moderne Sprache, die ich kenne, ist z.B. dart. Zusammen mit flutter ist das genial. Backend, Web, (Mobil und Desktop) Apps ... alles was man will. Da hat Google durhaus was vernünftiges auf die Beine gestellt mit vielen gut durchdachten Konstrukten (Die sich aber natürlich auch erst einmal bewähren müssen!). Wenn es auf der JVM bleiben soll, dann ist Kotlin ggf. scon eine gute Alternative.

Also ganz klar: Java ist ein Dinosaurier und der bewegt sich langsam ... aber die Bewegung ist da - also ggf. vom Java 8 mal etwas Richtung Java 17 bewegen :)
 
Y

yfons123

Gast
Ich kenne halt üblicherweise auch nur sehr einfache Beispiele, die man in einer Vorlesungsübung machen würe und kein 100 Klassen projekt oder Ähnliches :-/
wie kannst du dann ein design beurteilen das du nicht kennst und nie genutzt hast?
Ja, protected private und public gibts.
Schön für die die eine Bank App bauen.
das hat absolut nix mit sicherheit zu tun
Mich nervt shcon dass Java mich zwingt für Alles mögliche mit try catch Exceptions abzufangen wenn ich nicht hinter JAVA methode ein throws Exception schreiben will.
weil du nicht weist was eine runitme exception ist, dh du kennst weder das klassen design noch tiefere kenntnisse und willst es trotzdem beurteilen .. fragwürdig
Aber sinnvoll ist der kram, keine Frage. Nur halt gutes Futter für viele Fehler und errors, derer ich so schon genug produziere :)
warum glaubst du ist oop seit über 20 jahren nicht ausgestorben ? sicher nicht weil sich jeder denkt "haha so viele fehler und errors challenge accepted!"

zusätzlich
generics brauchst du gar nicht?
vererbung brauchst du auch nicht? stell mir mal ein modell vor das aussagt
ein blümchen hat eine farbe, rose und tulpe sind eine blume aber die rose hat ne länge und die tulpe hat erde, aber nicht umgekehrt... darauf bin ich gespannt
ahja und wenn du das hast verlgeiche diese miteinander
 

mrBrown

Super-Moderator
Mitarbeiter
so oder so habe ich dann 20 methoden untereinander und wenn man wie ich als schreiberling nicht weiß wie diese methoden im aufgabe-unteraufgabe bezug stehen, sieht man nur mäassig Code, den der böse OOPP Verweigerer doch easy mittels Klassen lösen könnte -.-
Genau das ist das Problem, was man durch sinnvolle Struktur (und zB OOP) lösen möchte. Du selbst bist irgendwann in der gleichen Position, dass du nicht mehr weißt, warum du welchen Code wie und warum geschrieben hast.

All die Dinge, die du als störend und fehleranfällig ansiehst, helfen dabei, Dinge zu strukturieren und dir als Entwickler Gedanken zu machen:
Aufteilen in Klassen und Methode > du musst dir Gedanken machen, wie Dinge zusammen arbeiten, wie sie zusammen gehören, ...
private vs public -> du musst dir Gedanken machen, wer worauf zugreifen darf. Wenn alles von überall verändert werden darf, blickst du irgendwann nicht mehr durch
Checked Exceptions -> Du musst dir Gedanken über Fehler, die du nicht aktiv vermeiden kannst, machen, und dir überlegen, wie du damit umgehst




(Denk ich mir bei deinen Beiträgen manchmal auch. Versuch doch mal, ein bisschen auf verständliche Texte zu achten.)
 

White_Fox

Top Contributor
Dass mein Code auf deutsch gesagt scheiße ist, wurde mir hier ja schon mehr oder minder eindeutig "durch die Blume" mitgeteilt, ist mir klar.
Nanana...soweit ich weiß, haben wir zu wenig Code bisher gesehen um das beurteilen zu können. Nur deine Einstellung zu so guten Konzepten...die erlauben wir uns kommentieren. ;)

Tja, im Endeffekt muss für jede dieser (Teil) aufgaben eine eigene Methode geschrieben sein.
Eher schreibt man für jedes Teilproblem eine Klasse. ;)

Kenn ich jetzt nicht das Buch, was aber gar nicht sagen muss.
Da ich mich bis heute auch noch nicht dazu durchringen konnte, überhaupt mal das Inselbuch zu lesen .-)
Die Insel braucht man auch nicht zu lesen. Die ist als Nachschlagewerk gut, ist aber als Lehrbuch unbrauchbar.

Kenne OOP bloss aus der Vorlesung wo ich die meisten Anwendungen für overkill halte weil es direkt ohne Zwischenklassen für Alles direkter geht.
Ein Fehler, der in prozeduralen Sprachen wie C oft für Ärger sorgt, sind globale Variablen. Irgendwie braucht man einen bestimmten Wert an zig verschiedenen Stellen, und irgendwann schreibt man von zig verschiedenen Stellen auf dieser Variable. Sowas führt eigentlich immer dazu, daß früher oder später niemand mehr durch diesen Codewust durchsieht. Irgendwann schafft das auch der nicht mehr, der den Kram mal geschrieben hat.

Die Idee hinter einer Klasse ist es nun, das Wesentliche unsichtbar zu machen. Beim Auto drückst ja auch nur das Gaspedal, und mußt glücklicherweise nicht kontinuierlich die Lambdasonde ablesen und die Luft-Kraftstoffmischung danach anpassen und den Zündzeitpunkt umstellen.
Der Grundgedanke bei Klassen ist derselbe: Du kannst einem Objekt von außen sagen was es tun soll, aber wie es das tut soll nicht deine Sorge sein. Das hilft ungemein, sowas zu unterbinden:
Wobei man da dann halt bspw. im Hinterkopf wissen muss wofür welche Tiefe eines mehrdimensionalen Arrays steht oder auch nicht :)
 

temi

Top Contributor
Es wurde in diesem Thema schon genannt und hier im Forum schon sehr oft: "Entwurfsmuster von Kopf bis Fuß" ist ein Buch, das absolut zu empfehlen ist. Ich habe erst durch diese Lektüre richtig verstanden, worum es bei OOP überhaupt geht.

Ebenfalls sehr empfehlenswert ist: "Effective Java" von Joshua Bloch. Da wird in vielen kleinen Themen erläutert, wie man etwas tun oder warum man es nicht tun sollte.

Diese beiden Bücher in Kombination und man kennt fast alles, was man braucht.
 

Neumi5694

Top Contributor
Da stellt sich dann shcon die Frage:
schreibe ich erst die (methoden der) aufgaben 1,2,3,4,5 hin und danach erst die unteraufgaben?
Oder erst aufgabe 1, dann unteraufgabe 1.1, dann unterunteraufgabe 1.1.1., usw.
so wie man es in einem inhaltsverzeichnis machen würde?
Wenn du beim Kleinen anfängst (Baukasten), dann hast du den Vorteil, dass du sofort testen kannst. Die Unteraufgaben haben weniger Abhängigkeiten.
Wenn du beim großen anfängst (Bildhauer), kannst du den Ablauf sofort in den Code schreiben, aber er funktioniert halt nicht, bis die Unteraufgaben implementiert sind.

Wenn ich einen Algorithmus für eine Problem im Kopf hab, dann geh ich her und schreib das Ganze erst mal auf Papier auf, zumindest in einer groben Struktur, spiele sie durch, um zu sehen, ob die Idee gut genug ist, um damit zum Ziel zu kommen.
Wenn's grundsätzlich passt oder es so trivial war, dass ich den Schritt gleich übersprungen habe (das Wort "faul" wird hier nicht erwähnt, ok?), dann kommt das Ganze in Pseudocode in die Datei. Hier schreib ich in Kommentaren alles Schritte auf, es kommt jeweils ein TODO davor.
Als nächstes wird Zeile für Zeile in groben Code umgesetzt, mit Platzhaltern. Da kann dann mal so was stehen wie
Java:
while(stehenNochLeuteInDerWarteSchlange() && istNochKaffeeDa()) {
    //...
    gibPersonKaffee(erstePersonInDerWarteSchlange);
    schickPersonNachHause(erstePersonInDerWarteSchlange);
}
if(stehenNochLeuteInDerWarteSchlange()) {
    trösteKaffeesüchtige(warteschlange);
    schickAllePersonNachHause(erstePersonInDerWarteSchlange);
}
Natürlich lässt sich der Unsinn nicht kompilieren (und ich schreib's im Normalfall gleich in Englisch).
Im nächsten Schritt werden die Methodenheader für die Platzhalter definiert und anschließend implementiert.
Hin und wieder - wenn eine Pseudomethode nur eine triviale Zeile beinhalten würde, wird der Aufruf auch durch diese Zeile ersetzt. Hinterher kann man das immer noch so kürzen. Umgekehrt ist der Aufwand deutlich höher und fehleranfällig.

Was für dich am Besten klappt, wirst du noch rausfinden. Versuch halt nur nicht, das gesamte Universum auf einmal zu programmieren, da kommt nur Mist dabei raus.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Collections Liste schnell/nebenläufig durchgehen Allgemeine Java-Themen 2
P Verzeichnis in JAR-Datei durchgehen Allgemeine Java-Themen 2
R Stream Byte für Byte durchgehen Allgemeine Java-Themen 5
L (Sub)Matches von Regex durchgehen Allgemeine Java-Themen 11
B Liste aller Kombintionen mit Einschränkungen Allgemeine Java-Themen 8
D Kgv aller Paare aus einem Array mit n integer berechnen Allgemeine Java-Themen 5
H Summe aller Vielfachen von 3 oder 5 unter 1000. Allgemeine Java-Themen 7
J Liste aller Com-Ports - zweistellige Ports? Allgemeine Java-Themen 15
S Char-index aller Buchstaben..? Allgemeine Java-Themen 3
S AWT Wie bekomme ich eine Liste aller chars in einem Font? Allgemeine Java-Themen 3
K Liste aller implementierenden Klassen einer Oberklasse anzeigen Allgemeine Java-Themen 4
S Mappen aller Paramater der gleichen klasse Allgemeine Java-Themen 3
S Auslesen aller verfügbaren Drucker-Schächte Allgemeine Java-Themen 3
G Methoden auf Arrays aller primitiver Typen zusammenfassen? Allgemeine Java-Themen 8
L Auflistung aller Methoden einer Klasse Allgemeine Java-Themen 9
S Datei aller möglich encodings generieren Allgemeine Java-Themen 2
A String schrittweise aller 3 Zeichen zerteilen Allgemeine Java-Themen 24
N Inhalte aller Txts in einem Ordner Addieren Allgemeine Java-Themen 5
I Liste aller bekannten Packages Allgemeine Java-Themen 6
B dynamisches Laden aller Klassen in einem Ordner ?? Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben