static non-static

Hallo,

ich werde heute Nacht weitermachen, jetzt gehe ich erstmal zu den Kindern.
Static gilt für die ganze Klasse , beispiel Anzahl der Menschen in der Klasse Mensch, diese Anzahl ist ja für alle Menschen der Klasse gleich.
non static: gilt für Eigenschaft eines Menschen. Beispiel: Ein Mensch hat eine Haarfarbe, die ist bei jedem unterschiedlich.

Grüße
Norman
 
SO, nachdem ich jetzt mal einen Moment bei meiner Familie gesessen habe werde ich erstmal weiter programmieren.

static: Methode, die für die ganze Klasse gilt bzw. sich nicht ändert, wie zum Beispiel in der KLasse Menschen die Bevölkerungszahl aller Menschen, die ist für alle gleich.
Die Eigenschaft HAarfarbe ist jedoch nicht für alle gleich, also non-static

Wie ist es allerdings mit Essen (eine Handlung die alle Menschen machen aber halt jeder anders?

Grüße
Norman
 
Du schreibst die Antwort ja eigentlich schon selbst. Wie ein einzelner Mensch isst hängt von seinen individuellen Attributen ab...
 
beispiel Anzahl der Menschen in der Klasse Mensch, diese Anzahl ist ja für alle Menschen der Klasse gleich.
Kann man machen, muss man aber nicht. Eine gute Empfehlung ist häufig vom wirklichen Leben auszugehen: Weiß ein einzelner Mensch, wieviele Menschen existieren und wann genau ein neuer dazu kommt? Oder, anderes Beispiel, weiß ein einzelnes Buch, wieviele davon in der Bücherei stehen? Eine Klasse sollte nur das tun, was sie unmittelbar betrifft, d.h. wenn du eine Klasse Mensch hast, dann hat sie z.B. Geschlecht, Größe, Gewicht, Haarfarbe, ...

Brauchst du mehrere Menschen, dann steck die einzelnen Menschen in die Klasse "Menschenmenge" oder "Erde".

Wie schon geschrieben wurde: Es ist eine gute Empfehlung, außer bei der Methode "main()" erst mal auf static zu verzichten. Es gibt Situationen, wo es gebraucht wird, die sind aber eher seltener.
 
Also,

beim ersten Compile Versuch war alles richtig außer:
12412

Das Hauptproblem ist nach wie vor erstmal, wo erstelle ich beim erstes Blatt, also alle KArten. Und wie mache ich das hier mit dem static-non-static
Anbei alle Klassen:
Javascript:
public class Karte {

    private String farbe;
    private String wert;
    private int kontrollnummer;
    private final String [] farben = {"Kreuz", "Pik", "Herz","Karo"};
    private final String [] werte = {"7", "8", "9", "10", "Bube", "Dame", "König", "As"};
    
    public void Karte (String farbe, String wert, int kontrollnummer) {
        this.farbe=farbe;
        this.wert=wert;
        this.kontrollnummer= kontrollnummer;
    }
    
        
    public void setFarbe ( int i) {
        farbe= farben[i];   
    }
    
    public String getFarbe () {
        return this.farbe;
    }

    public void setWert ( int i) {
        wert= werte[i];   
    }
    
    public String getWert () {
        return wert;
    }

    public void setKontrollnummer ( int kontrollnummer) {
        this.kontrollnummer= kontrollnummer;   
    }
    
    public int getKontrollnummer () {
        return this.kontrollnummer;
    }
    
    public void zeigen () {
        System.out.println("" + farbe + "  " + wert) ;
    }
}

import java.util.Random;

public class Stapel extends Karte{
    
    private int anzahl;
    private  Karte [] karten = new Karte  [31];
    
    public void Stapel (int anzahl, Karte [] karten ) {
        this.anzahl = anzahl;
        this.karten = karten;
    }
    
    public  Stapel BlattErstellen( ) {
        Stapel Blatt = new Stapel();
        int k = 0;
        for (int i =0; i<4; i++) {
            for (int j=0; j < 8; j++) {
                karten[k] = new Karte();
                karten[k].setKontrollnummer (k);
                karten[k].setFarbe (i);
                karten[k].setWert(j);
            }
        }
        return Blatt;   
    }
    
    public   void StapelFüllen (int anzahl) {
        this.anzahl = anzahl;
        for (int i = 0 ;i<anzahl;i++) {
            this.karten[i]=Blatt.getObersteKarte();
        }
    }
            
    public void Mischen () {
        Karte zwischenSpeicher;
        int zufallsZahl;
        Random random = new Random();
        for (int i=0; i<anzahl-1;i++) {
            zufallsZahl= random.nextInt(anzahl);
            zwischenSpeicher = karten [i];
            karten [i]= karten [zufallsZahl];
            karten [zufallsZahl] = zwischenSpeicher;
        }
    }
    
    
    public int getAnzahl () {
        return anzahl;
    }
    
    public String [] farbeUndWertOberste () {
        String[] farbeUndWert = new String [2];
        farbeUndWert[1]=karten[anzahl-1].getFarbe();
        farbeUndWert[2]=karten[anzahl-1].getWert();
        return farbeUndWert;
        
    }
    
        
    
    public void zeigeKarten () {
        for (int i =0; i<= anzahl-1; i++) {
            System.out.print("Karte :  " +i);
            karten[i].zeigen();
        }
    }
    
    public Karte  getObersteKarte () {
        Karte obersteKarte= karten[(anzahl-1)];
        karten[anzahl-1] = null;
        anzahl = anzahl-1;
        return obersteKarte;
    }
    
    public Karte  KarteAnPositionNehmen (int p) {
        Karte gewählteKarte= karten[p];
        for (int i = p; i<(anzahl-1);i++) {
            karten [i]=karten[i+1];
        }
        karten[anzahl-1] = null;
        anzahl = anzahl-1;
        return gewählteKarte;
    }
    
    public void KarteHinzufügen (Karte karte) {
        karten[anzahl]=karte;
        anzahl= anzahl+1;
    }

    public void zeigeObersteKarte() {
        karten[anzahl-1].zeigen();
    }
    
}
import java.util.Scanner;

public class Spieler extends Stapel {
    
    private String name;
    private Stapel handkarten;
    private int anzahlKarten;
    
    
    public Spieler(int anzahlStarthandKarten) {
        Scanner Eingabe = new Scanner (System.in);       
        this.handkarten = new Stapel();
        handkarten.StapelFüllen(anzahlStarthandKarten);
        this.anzahlKarten = anzahlStarthandKarten;
    }

    
    public void setName (int i) {
        System.out.println("Name des " +(i+1) + "ten Spielers?");
        Scanner Eingabe = new Scanner (System.in);
        String Name =  Eingabe.nextLine();
        name = Name;
    }
    
    public String getName () {
        return name;
    }
    
    public int anzahlHandkarten () {
        return handkarten.getAnzahl();
    }
    
    public Karte spieleKarte (int position) {
        return handkarten.KarteAnPositionNehmen(position);       
    }
    
    public void zieheKarte (Karte karte) {
        handkarten.KarteHinzufügen(karte);
    }
    
    public void zeigeHandKarten () {
        handkarten.zeigeKarten();
    }
    
    
}
import java.util.Scanner;

public class Konfiguration extends Spieler{
    public  Stapel Blatt;
    public static int anzahlSpieler;
    public static int anzahlStarthandKarten;
    private static Spieler [] spielerrunde = new Spieler [anzahlSpieler];
    public static int indexAktiverSpieler;
    public static int gewinner = -1;
    static Stapel  NachZiehStapel = new Stapel() ;
    static Stapel  AblageStapel = new Stapel ();
    static int [] konfig;
    
    
    static int ZahlEinlesen (int Minimum, int Maximum){
        Scanner Eingabe = new Scanner (System.in);
        int z =-1;
        boolean error=true;
        do{
            do{
                System.out.printf("Bitte geben Sie eine ganze Zahl ein zwischen %d und %d ein: /n", Minimum, Maximum);
                try{
                    z = Integer.parseInt(Eingabe.nextLine());
                    error=false;
                }
                catch (NumberFormatException e)    {
                    System.out.println("Nur Integer Zahlen eingeben!");
                    error=true;
                }
            }while ( error );
            if (z>Maximum || z < Minimum){
                System.out.println("Nur ganze Zahlen zwischen " + Minimum + " und " + Maximum + "  eingeben!");
            }
        }while (z>Maximum || z < Minimum);
            //System.out.println ( "Danke, Ihre Eingabe lautet : " + z );
            
            return z;
        }

    public void Konfiguration (){
        System.out.println("Bitte geben Sie an, mit wie vielen Spielern Sie spielen wollen:");
        anzahlSpieler = ZahlEinlesen (2,6);
        //Damit genug Karten zum Spielen da sind, wird jetzt berechnet, wie viele Karten jeder bekommen soll.
        int z =(int) Math.floor(32/(anzahlSpieler+2));
        anzahlStarthandKarten = Math.min(6,z);
        for (int i = 0 ;i< anzahlSpieler ; i++) {
            spielerrunde [i]  = new Spieler (anzahlStarthandKarten);
        }
        int []konfig_a = {anzahlSpieler, anzahlStarthandKarten};
        NachZiehStapel = Blatt;
        AblageStapel.KarteHinzufügen(NachZiehStapel.getObersteKarte ());
        
    }
    
    public int  KartenAuswählen (int indexAktiverSpieler ) {
        System.out.println("Spieler " + spielerrunde[indexAktiverSpieler].getName() + " , Sie sind dran. /n Ihre Karten:");
        spielerrunde[indexAktiverSpieler].zeigeHandKarten();
        System.out.println("Biite wählen Sie die Karte aus, die Sie ausspielen wollen:/ Mit -1 ziehen Sie eine Karte vom NAchziehstapel.");
        int auswahl = ZahlEinlesen (-1,(spielerrunde [indexAktiverSpieler].anzahlHandkarten()-1));
        return auswahl;
    }
    
    public void KartevomNachziehstapelGeben(int indexAktiveSpieler) {
        spielerrunde[indexAktiverSpieler].KarteHinzufügen(NachZiehStapel.getObersteKarte());
        System.out.println("In dieser Variante ist dann jetzt der Nächste dran, Sorry");
    }
    
    public boolean kartePrüfen (int auswahl) {
        boolean kartePasst;
        String [ ]prüfKarte = {spielerrunde [indexAktiverSpieler].spieleKarte(auswahl).getFarbe(), spielerrunde [indexAktiverSpieler].spieleKarte(auswahl).getWert()};
        String [] oberAblage = AblageStapel.farbeUndWertOberste();
        if (prüfKarte[0].equals(oberAblage[0]) || prüfKarte[1].equals(oberAblage[1])) {kartePasst = true;}
        else {kartePasst = false;
            System.out.println("Ihre Karte hat nicht gepasst. Sie wird Ihnen zurückgegeben und der nächste Spieler ist dran.");
        }
        return kartePasst;
    }
    
        
    public int Spielzug (Spieler [] spielerrunde,  int anzahlSpieler) {   
        indexAktiverSpieler = 0;
        while(spielerrunde[indexAktiverSpieler].anzahlHandkarten() !=0) {       
            boolean kannAblegen;
            System.out.println("Die oberste Karte auf dem Stapel ist");
            NachZiehStapel.zeigeObersteKarte();
            int auswahl = KartenAuswählen(indexAktiverSpieler);
            if (auswahl == -1) {
                KartevomNachziehstapelGeben(indexAktiverSpieler);
                kannAblegen = false;}
            else {kannAblegen=kartePrüfen (auswahl);}
            
            if (kannAblegen == true) {
                AblageStapel.KarteHinzufügen(spielerrunde [indexAktiverSpieler].spieleKarte(auswahl));
            }
            if (NachZiehStapel.getAnzahl()==0) {
                Karte Zwischenspeicher =AblageStapel.getObersteKarte();
                NachZiehStapel = AblageStapel;
                NachZiehStapel.Mischen();
            }
            if (indexAktiverSpieler < anzahlSpieler) {indexAktiverSpieler ++;}
            else {indexAktiverSpieler =0;}
        } ;
        
        gewinner = indexAktiverSpieler;
        return gewinner;
        
    }
    
    
    
    
    public static void main(String[] args) {
            Blatt = BlattErstellen ();
            Konfiguration Konfiguration = new Konfiguration();
            gewinner =Spielzug (spielerrunde, anzahlSpieler);   
            System.out.println("Gewonnen hat: " + spielerrunde[gewinner].getName());
    }
            

}
 
Der Fehler liegt ja schon darin, dass der Stapel nicht die Karte erweitert. Der Stapel ist eine gewisse Anzahl an Karten aber nicht eine Erweiterung einer Karte. Also das extens ist vom Konzept her einfach falsch.
 
Das Hauptproblem ist nach wie vor erstmal, wo erstelle ich beim erstes Blatt, also alle KArten.
Wenn man sich das so anschaut, dann fehlen dir offenbar sehr wichtige Grundlagen, die du dir dringend z.B. anhand eines guten Buches zuerst aneignen solltest.

Du solltest darauf achten, dass du Java Konventionen einhältst, z.B. Klassennamen werden im CamelCase (Großbuchstabe am Anfang) geschrieben und Methoden- und Variablennamen werden im sogenannten lowerCamelCase (Kleinbuchstabe am Anfang) geschrieben.

Dann sollten Klassen nur eine Funktionalität haben und nichts vermischen. In deinem Fall z.B. eine Hauptklasse "Kartenspiel" mit der main() Methode und die Klassen "Karte" und "Blatt" für den Anfang.

Deine "extends" Anweisungen sind auch völlig fehl am Platz, wie schon @Thallius geschrieben hat. "Extends" bedeutet immer eine Ist-ein-Beziehung und ein Stapel ist keine Karte, sondern enthält Karten.

In der main() könnten dann ungefähr stehen:

Java:
    public static void main(String[] args) {
        // die Klasse Blatt enthält eine Kollektion von Karten, die zusammen ein Blatt ergeben
        // die Initialisierung (zufällige Erzeugung) kannst du bereits im Konstruktor machen. 
        Blatt blatt = new Blatt();

        // mit diesem Blatt kannst du jetzt spielen
        Karte ersteKarte = blatt.getErsteKarte();
    }
Edit:

Sinnvoll wäre hier allerdings, dass "Blatt" von "Stapel" erbt und den einfachen Stapel um die Funkionalität erweitert einen gemischten Kartenstapel zu erzeugen.
 
Zuletzt bearbeitet:
Mal ein konkreter Vorschlag, wie die Klasse Karte aussehen könnte. Ich habe zusätzlich noch Enumerationen für Farbe und Wert vorgesehen, die das Ganze klarer machen und Fehler vermeiden (Strings sind für diese Funktionalität sehr fehleranfällig).

Die Karte ist immutabel, d.h. das sich Farbe und Wert nicht ändern können, wenn die Karte erstellt wurde. Das ist aber auch in einem echten Spiel so der Fall, also durchaus logisch. Darum gibt es auch keine Setter-Methoden.

Java:
public enum Farbe {
    KREUZ("Kreuz"), PIK("Pik"), HERZ("Herz"), KARO("Karo");

    private String info;

    Farbe(String info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return info;
    }
}

public enum Wert {

    SIEBEN("7"), ACHT("8"), NEUN("9"), ZEHN("10"), BUBE("Bube"), DAME("Dame"), KOENIG("König"), AS("As");

    private String info;

    Wert(String info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return info;
    }
}

public class Karte {

    private final Farbe farbe;
    private final Wert wert;

    public Karte(Farbe farbe, Wert wert) {
        this.farbe = farbe;
        this.wert = wert;
    }

    public Farbe getFarbe() {
        return farbe;
    }

    public Wert getWert() {
        return wert;
    }

    // normalerweise trennt man Funktion und Ausgabe, aber dennoch
    public void zeigen() {
        System.out.println(this);
    }

    @Override
    public String toString() {
        return farbe + " " + wert;
    }
}
Und in der main() exemplarisch, damit du siehst, wie das verwendet wird. Deine tatsächliche main() wird wohl später etwas anders aussehen.

Java:
public class Main {

    public static void main(String[] args) {
        Karte karte = new Karte(Farbe.HERZ, Wert.AS);

        karte.zeigen();

        // oder

        System.out.println(karte);
    }
}
Nimm das mal als Start für deine weiteren Klassen.
 
Zuletzt bearbeitet:
K

kneitzel

Ich möchte einen Punkt noch einmal kurz vertiefen:

Der Startpunkt ist immer die public static void main Methode, d.h. eine statische Methode. Hier hast Du also eine Startposition, bei der noch keine Objekte existieren. Daher ist es jetzt wichtig, dass Du Dir an dieser Stelle die Welt, die Du brauchst, erstellst.

Also was ist das zentrale Element in Deinem Spiel? Das kann das Spiel selbst sein. Also eine Klasse Spiel oder Game, falls Du die Namen auf Englisch bevorzugst.

Somit wird da immer in der main Methode sowas sein wie: Erstelle das zentrale Objekt und dann starte da drin den eigentlichen Ablauf (also z.B. eine start oder run Methode in Spiel/Game).

Und ehe Du anfängst auch nur irgend einen Code zu schreiben, ist nun wichtig, dass Du Dir im klaren darüber bist, was es denn alles so für Elemente gibt.

In dem Spiel gibt es Spieler. Wie viele? Was macht ein Spieler aus? (Was für Daten sind hier wichtig? Was muss der Spieler können?)
Was ist in dem Spiel sonst noch wichtig? Es gibt von mir aus einen Kartenstapel, von dem Karten gezogen werden können. Es können Karten abgelegt werden, ....

Du musst Dir das im Detail genau überlegen. Und dann kennst Du die einzelnen Elemente, die Du brauchst incl. dem, was diese Elemente aus machen und was diese machen können.

So hat ein Spieler z.B. eine Menge Karten, hat einen Namen, ...
Ein Spieler kann eine Karte ziehen (unter bestimmten Bedingungen, z.B. wenn er am Zug ist), kann eine Karte ablegen (am Zug ist, und ggf. gibt es Regeln, wann er welche Karte wie ablegen darf.)

Und dann ist klar, was es alles so gibt oder nicht gibt. Hier ist dann auch wichtig, dass man dann alles, was man schreibt, direkt testen kann. Hier ist meine klare Empfehlung: Schau die Unit Tests an. JUnit ist nicht so kompliziert! Oder mach es einfach in der Form von "Unit Tests für Dumme": Schreib einfach Klassen wie "XyzTest" mit Xyz dem Namen einer Klasse und in der Klasse hast Du in erster Linie eine public static void main Methode, in der Du dann mit Spieler irgendwas machst, um den Spieler zu testen.
Der Spieler soll einen Namen haben, also kannst Du da ganz einfach testen: Wenn Du einen Spieler erstellst und den Namen setzt: Ist dann der Name wirklich gesetzt? Trivialer Test, scheint erst einmal unnötig, aber testen halt setter und getter vom Namen. Wird aber auch komplexer: Du generierst von mir aus eine Spiel Instanz mit einem Kartenstapel und dann testest Du, dass ein Spieler eine Karte ziehen kann, incl:
- Wenn der Spieler nicht dran ist, dann bekommst Du eine Exception.
- Die oberste Karte ist danach nicht mehr auf dem Stapel und der Spieler hat diese Karte danach.
- Wenn der Stapel leer ist, dann kommt auch eine Exception wie gewünscht
- ....
Einfach alle Testfälle. Diese Testfälle sind etwas blöd, da Du die immer nur manuell selbst aufrufen kannst, aber das ist ein Anfang. Später kannst Du die Funktion etwas umschreiben, JUnit einbinden für das @test und paar Asserts und so, aber das wäre ein erster Anfang.
 
Jo, alles ist immer ganz einfach

Nimm doch den Windowbuilder um frames , contents, panels , LAyouts zu erzeugen GANZ Einfach
nimm doch dieses oder jenes oder ENUMS (habe ich schon tausendmal gehört und esse ich jeden Tag zum Frühstück
Nimm doch ArrayList, dann hast du alle Methoden gleichzeitg
Nimm doch einen stack-Array, dann hast du automatisch einen Kellerspeicher

Erzeuge doch dieses und jenes und importiere dieses Package,

speicher hier und da

Super

Die Bücher fangen immer mit Hello World an und dann kommen auf der zweiten Seite schon eintausendvierhundertachtundfünfzig Wörter, für die man je weiter eintausendvierhunderachtunfünfzig Bücher lesen muss.

Wenn man alles kann, lesen sich die Bücher sehr einfach und man denkt, ja, genau, super beschrieben.

Ansonsten hangelt man sich von einem Eintrag und Index zum anderen und nach zwei Wochen schafft man gerade anstatt HAllo Word vielleicht Hallo ihr alle zu schreiben.

Ich habe vor 30 Jahren in Basic programmiert, dann in PAscal, im Studium musste ich irgendwie mit VisualBAsic rumfuddeln, dann 20 Jahre nichts.
Ich habe drei Kinder, bin Feuerwehrmann, Musiker, Lehrer und laufe und fahre gerne Fahrrad, gerade bin ich froh, dass ich mit einem kaputten Kreuzband im Bett liege und eine Woche Zeit habe mal was zu programmieren außer "Hello World"

Also die Namen, klar, krieg ich hin.
Das mit dem Extends habe ich auch kapiert und das regt euch anscheinend sehr auf, also mache ich es weg, dass ist gegen die Konventionen.

Das mit den Klassen , static usw hat mir als promovierter Physiker in den letzten zwei Wochen der Professor selber, sein Assistent, mehrere Leute die schon JAhre programmieren usw versucht zu erklären, aber JUNGS, ihr denkt halt schon anders. Es kommen bei euch sofort zweihundertachtundreißig Worte in jedem Satz, die ein nicht-Programmierer erst mal nachschauen muss. Da für mich das wichtigste war, das mit den Unterklassen und so zu kapieren, bin ich froh, dass ich das so hinbekommen habe, wie ich es hinbekommen habe.

Die Konventionen werde ich ab sofort einhalten und glaubt mir , ich bin in meiner Lerngruppe nicht der , der am weitesten hinten ist.



Danke für eure kosntruktive Hilfe, ich mach mich an die Abreit.
 
Zum konkreten Problem Blatt:

Blatt ist doch nur ein Spezialfall von Stapel, kriegt Blatt dann einen eigenen Konstruktor?
Ist das sinnvoll? Ich benötige das doch nur einmal am Anfang. Dann wäre aber extends wenigstens mal im richtigen Sinne verwendet.
Blatt rufe ich im main Programm auf, so weit war ich ja schon, aber ich lasse es auch dort initiieren, und nicht in der Methode blattErstellen?, Ok, ist schon implementiert.

Mein Main Programm war ja sehr kurz, daher dachte ich, dass Konfiguration, was im Prinzip der Konstruktor für ein Spiel ist, da er die Anzahl der Spieler erzeugt , den Namen abfragt, "Blatt" erzeugt, die Stapel vereilt, und den Nachziestapel vorbereitet.
Ansonsten war da ja nur das Spiel selber und ein paar kleine Methoden, soll aber trotzdem nicht ins main-Fenster???
Also, so wie ich es verstanden habe. soll der Konfigurator, der alles erzeugt, was man für das Spiel braucht in eine extra Klasse in Konfigurator ( spielerrunde, anzahlSpieler, anzahlStartHandKarten, nachZiehStapel und AblageStapel).

Wo sollen die Methoden hin, die für das Spiel selber benötigt werden? In Konstruktor oder in die Klasse mit dem main Programm. Wenn ich es richtig verstanden habe. sollen die helfenden Methoden nicht in die gleiche Klasse wie das main-Programm. (spielzug, kartePrüfen, ZahlEinlesen, kartePrüfe, kartevomNachziehstapelGeben, kartenAuswählen)



Dann muss ich die spielerrunde, die alle Spieler mit allem enthält und im Konfigurator erzeugt wird doch immer komplett mit übergeben, macht das Sinn?

Also, ich erzeuge Blatt jetzt erstmal im Konstruktor meiner Main Klasse, die ich erstmal in der Klasse Konfigurator lasse (ja, ist UNMÖGLICH!)


Vielen Dank!

Norman


P.S.: Wie genau es mein Blatt geschafft hat, static zu werden habe ich immernoch nicht verstanden. Vielleicht stand das bei eurer Version vor Blatt, aber die war auch ohne es davor zu schreiben plötzlich static.



Danke nochmals
 
Blatt ist doch nur ein Spezialfall von Stapel, kriegt Blatt dann einen eigenen Konstruktor?
Ist das sinnvoll? Ich benötige das doch nur einmal am Anfang. Dann wäre aber extends wenigstens mal im richtigen Sinne verwendet.
Blatt rufe ich im main Programm auf, so weit war ich ja schon, aber ich lasse es auch dort initiieren, und nicht in der Methode blattErstellen?, Ok, ist schon implementiert.
Erstmal: Kompliment für dein Durchhaltevermögen. Es gibt Leute, die haben über diesen Kram Klausuren mit einer guten Note bestanden und weniger verstanden als du bis jetzt. Kopf hoch, und weiter so. :)

Zu deiner Frage: Schaue dir einfach mal die Realität an. 'Stapel' ist eine Ansammlung von Karten, 'Blatt' auch. Aber: wenn du zwei oder mehr Blätter erzeugen willst, mußt du dafür Sorgen, daß nicht in zwei Blättern ein Pik As vorkommt. Jede Karte muß einzigartig sein, die Reihenfolge jedoch trotzdem zufällig.

Es würde, meiner Meinung nach, Sinn ergeben, für 'Blatt' gar keinen (öffentlichen!) Konstruktor vorzusehen. Besser wäre, wenn die Klasse 'Stapel' einfach Blätter austeilt. Was du also machen könntest:
-für alle Klassen, die direkt mit deinen Karten zu tun haben, ein eigenes Package Karten anlegen (deine main-Methode kommt in ein eigenes Packages main).
-den Konstruktor von 'Blatt' auf package private setzen (also einfach keinen Sichtbarkeitsmodifizierer mitgeben), dann können nur Klassen desselben Packages den Konstruktor aufrufen. Also z.B. die Klasse Stapel. In der main-Methode könntest du den Konstruktor jedoch nicht erreichen.


Übrigens: Ich hab etwa ein Jahr daran gesessen, eine vernünftige MVC-Struktur in meinem Programm zu implementieren. Es ist nicht so daß wir das Problem, so absolut gar nichts zu verstehen, nicht kennen würden. Jeder hat irgendwann mal angefangen. :)
 
Jetzt stehe ich schon wieder vor dem gleichen Problem.

Für alle Methoden in der Klasse Konfiguration soll z.B.anzahlSpieler gleich sein, (also static??),

ich muss dann aber im main-Programm auf diesen Wert zurückgreifen, da aber genau verweigert sich java?

anzahlSpieler wird ja im Konfigurator erzeugt. Daher erstelle ich in der Klasse eine Methode, um diesen Wert für meine main-Klasse abrufen zu können. Die main Klasse benötigt anzahlSpieler um dann in der Klasse Konfigurator (oder einer anderen, noch zu erstellenden) den Gewinner des Spiels zu ermitteln. Das klingt strange, aber ihr habt mehr Ahnung als ich und ich verstehe es halt noch nicht.
Wenn ich die Variablen im Konstruktor erzeuge bzw. verwende (und sie dann Teil von diesem sind?) muss ich diese dann immer hin- und herschicken und da kommt dann zum Beispiel wenn ich das hier machen will:

Code:
public int getAnzahlSpieler() {
         return  this.anzahlSpieler;
     }

should be accesed in a static way
 
Das war eine schöne Antwort, Danke!


Erstmal: Kompliment für dein Durchhaltevermögen. Es gibt Leute, die haben über diesen Kram Klausuren mit einer guten Note bestanden und weniger verstanden als du bis jetzt. Kopf hoch, und weiter so. :)

Zu deiner Frage: Schaue dir einfach mal die Realität an. 'Stapel' ist eine Ansammlung von Karten, 'Blatt' auch. Aber: wenn du zwei oder mehr Blätter erzeugen willst, mußt du dafür Sorgen, daß nicht in zwei Blättern ein Pik As vorkommt. Jede Karte muß einzigartig sein, die Reihenfolge jedoch trotzdem zufällig.

Es würde, meiner Meinung nach, Sinn ergeben, für 'Blatt' gar keinen (öffentlichen!) Konstruktor vorzusehen. Besser wäre, wenn die Klasse 'Stapel' einfach Blätter austeilt. Was du also machen könntest:
-für alle Klassen, die direkt mit deinen Karten zu tun haben, ein eigenes Package Karten anlegen (deine main-Methode kommt in ein eigenes Packages main).
-den Konstruktor von 'Blatt' auf package private setzen (also einfach keinen Sichtbarkeitsmodifizierer mitgeben), dann können nur Klassen desselben Packages den Konstruktor aufrufen. Also z.B. die Klasse Stapel. In der main-Methode könntest du den Konstruktor jedoch nicht erreichen.


Übrigens: Ich hab etwa ein Jahr daran gesessen, eine vernünftige MVC-Struktur in meinem Programm zu implementieren. Es ist nicht so daß wir das Problem, so absolut gar nichts zu verstehen, nicht kennen würden. Jeder hat irgendwann mal angefangen. :)
 
Für alle Methoden in der Klasse Konfiguration soll z.B.anzahlSpieler gleich sein, (also static??),
Wie wäre es denn mit folgendem Ansatz: Erstelle eine Klasse Kartenspiel. Wenn du ein neues Spiel eröffnest (den Konstruktor von 'Kartenspiel' aufrufst) gibst du alle nötigen Informationen mit. Der gesamte Spielablauf würde innerhalb dieser Klasse stattfinden. Von außen greifst du nur noch mit Methoden wie 'nächsterSpieler' oder so zu. Und diese Klasse weiß natürlich, wieviele Spieler teilnehmen.

Denn, angenommen du hättest zwei Spiele parallel zu laufen: Was interessiert es die eine Spielrunde, wieviele Teilnehmer die jeweils andere hat?
Es ist allgemein gut, möglichst restriktiv zu programmieren. D.h. jede Klasse bekommt nur die Informationen, die sie wirklich braucht. Informationen, die die Klasse nicht braucht, werden nicht freigegeben, deswegen gibt es die ganzen Sichtbarkeitsmodifizierer. Später etwas nachträglich freizugeben ist in der Regel nie ein Problem. Später aber den Zugriff zu entfernen ist oft ein Problem.
 
Danke!

OK, ich habe das mit dem static immer weiter nach oben geschoben. In der Klasse Konfiguration gibt es den Konstruktor Konfiguration, der alles erstellt was man für ein Spiel braucht (Blatt, verschiedene Stapel, Spieler usw.
Außerdem liegen da alle Methoden, die man für das Spiel braucht. (prüfeKarte, wähleSpieler usw
Meine MAin-Klasse sieht jetzt nur noch so aus.

Code:
public class MauMau {
    static int anzahlSpieler;
    Konfiguration Konfiguration;
    

    public static void main(String[] args) {
        System.out.println("Bitte geben Sie an, mit wie vielen Spielern Sie spielen wollen:");
        anzahlSpieler = Hilfsprogramm.zahlEinlesen (2,6);
        Konfiguration Konfiguration = new Konfiguration(anzahlSpieler);
        Konfiguration.spiel();
        Konfiguration.gewinnerAusgeben();
        
    }

}
Komischerweise sagt der Compiler, dass Konfiguration keinen integer übergeben haben will, obwohl ich ihn dahingehend geändert habe.
Jetzt kommt aber wieder das Problem mit
stati-nonstatic


Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Cannot make a static reference to the non-static method zahlEinlesen(int, int) from the type Hilfsprogramme
The constructor Konfiguration(int) is undefined

Das erste Problem verstehe ich nicht, weil ich es einfach immernoch nicht kapiere.
Das zweite Problem verschwindet vielleicht, wenn ich das Programm schließe und wieder öffne, da ich den Konstruktor Konfigurator ganz sicher so geändert habe, dass er ein Integer übernimmt.

Danke für die ganzen Hinweise, aber stati-nonstatic ist immer noch nicht ganz durch bei mir.

Grüße
Norman
 
Ich bemühe noch einmal die Klasse Foo ;)

Java:
class Foo {

    // Diese Methode wird direkt auf der Klasse aufgerufen: Foo.staticDoSomething();
    public static void staticDoSomething() {
        // hier steht Code
    }

    // für diese Methode musst du vorher eine Instanz der Klasse erzeugen: Foo instance = new Foo();
    // auf diese Instanz kann die Methode aufgerufen werden: instance.nonStaticDoSomething();
    public void nonStaticDoSomething() {
        // hier steht Code
    }
}
Der Unterschied zwischen den beiden Methoden ist, dass die statische Methode direkt auf der Klasse Foo aufgerufen wird, während nicht statische Methoden nur und ausschließlich auf Instanzen dieser Klasse aufgerufen werden können. Bei Variablen ist es im Prinzip genauso. Eine statische Variable gehört zur Klasse, d.h. es gibt sie nur einmal, egal wieviele Instanzen du von der Klasse erzeugst, der Inhalt der statischen Variablen ist für alle identisch.

Nicht statische Variablen hingegen gehören zur Instanz der Klasse. Jede Instanz hat eine "eigene" Variable.

Und noch einmal: Statische Methoden oder Variablen sind eher selten. Die Regel ist nicht statisch.
 
In der Klasse Konfiguration gibt es den Konstruktor Konfiguration, der alles erstellt was man für ein Spiel braucht (Blatt, verschiedene Stapel, Spieler usw.
BTW, die meisten deiner Klassen enthalten keine Konstruktoren, sondern nur Methoden, die genauso heißen wie die Klasse und void als Rückgabetyp haben - durch den Rückgabetyp ist es aber einfach nur noch eine normale Methode, da solltest du noch mal drüber gucken :)

Das dürfte dann auch der Grund hierfür sein:
The constructor Konfiguration(int) is undefined
 
Also, bei
anzahlSpieler = Hilfsprogramme.zahlEinlesen(2,6)
beschwert sich der compiler, "can'T make a static reference ..........."
Die MEthode zahlEinlesen ist in ihrer Klasse auf jeden Fall non-static.
Die VAriable anzahlSpieler im main Programm da habe ich auch das static gelöscht.
Mir erscheint es so, dass wenn ich mit einer VAriable anfange zu arbeiten, diese also aufrufe, diese dann static wird.
JEtzt muss diese Variable aus irgendeinem Aufruf herkommen, und dann verlangt der compiler in meinen Augen, dass diese Methode auch static sein muss, weil die VAriable ja da "festgelegt" wird. Wenn ich das aber nach unten verlängere, dann ist doch irgendwie alles static, und das kann ja nicht im Sinne des Erfinders sein.

Die Methode zahlEinlesen ist ein sehr gutes Beispiel, da diese wirklich sehr überschaubar ist.

Immer verlangt der compiler, dass ich diese static machen soll, wo liegt da denn der Haken, das verstehe ich nicht.

Wenn mir das mal einer erklären könnte, dann kann ich auch meinen Frieden mit java machen.

Wie soll ich das denn verhindern?

Vielen Dank wenn ihr da das Brett vor meinem Kopf entfernen könntet

Grüße
Norman
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben