Objekt soll anderes Objekt zerstören

Richtig, ist nicht ganz das Selbe, es ging mir dabei aber auch nur um die Referenzen. Nur weil eine Referenz erlischt, stirbt nicht das Original, es wird nur eine Verbindung gekappt. Alle anderen Verbindungen, sofern welche vorhanden sind, bleiben weiterhin bestehen und lassen das Objekt "leben".
 
@ Akeshihiro:

Okay, das mit den Pointern stimmt natürlich. Das hab ich so genau nicht beachtet. Aber im Prinzip würde es mir ja schon reichen, wenn das Objekt für mein Programm verschwunden ist, also alle Seile zum Jenseits gekappt sind und das Huhn im Hühnerhimmel (= irgendwo im Speicher) rumschwebt. Dann isses mir auch wurscht, wanns letztendlich im Fegefeuer (= GC) landet.


@ Kai008:

Kannst du mir ein Beispiel geben, wie ich das implementieren kann? Ich steh da grad n bissel aufm Schlauch :-P


Viele Grüße und besten Dank euch!
Frezl
 
Hab versehendlich die Konstante falsch genannt, zu spät aufgefallen. :-(

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package zoo;
 
/**
 *
 * @author Frezl
 */
public class Main {
 
	//KONSTANTEN
	private static final byte HUEHNER_ANZAHL = 2;
	
	private static final byte HUEHN_ELFRIEDE = 0;
	private static final byte HUEHN_BERTA = 1;

	// VARIABLEN
	private static Huhn[] huehner;
    // METHODEN
 
	
	
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
 
        // Hühner#
    	huehner = new Huhn[HUEHNER_ANZAHL];
        huehner[HUEHN_ELFRIEDE] = new Huhn(HUEHN_ELFRIEDE, "Elfriede", 430, "braun", 2);
        huehner[HUEHN_BERTA] = new Huhn(HUEHN_BERTA, "Berta", 410, "weiß", 3);
 
        // Leben auf dem Hühnerhof
        huehner[HUEHN_ELFRIEDE].gackern();
        huehner[HUEHN_BERTA].gruessen();
        huehner[HUEHN_BERTA].scharren();
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].scharren();
        huehner[HUEHN_ELFRIEDE].gackern();
        huehner[HUEHN_ELFRIEDE].gackern();
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].scharren();
        huehner[HUEHN_ELFRIEDE].gackern();
        huehner[HUEHN_ELFRIEDE].gackern();
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]);
        huehner[HUEHN_BERTA].attackieren(huehner[HUEHN_ELFRIEDE]); // hier stirbt Elfi, da die Lebenspunkte auf 0 sinken
 
        // leider lebt der Geist von Elfi aber munter weiter :-P
        // jetzt nicht mehr ;)
        huehner[HUEHN_ELFRIEDE].gackern();
        huehner[HUEHN_ELFRIEDE].scharren();
        Ei Osterei = huehner[HUEHN_ELFRIEDE].eiLegen();
 
        // erst wenn Gott das Huhn mit eigener Hand tötet, ist es erlöst
        huehner[HUEHN_ELFRIEDE] = null;
        huehner[HUEHN_ELFRIEDE].gackern(); // und kann auch nicht mehr gackern... (Was zu einer NullPointerException führt)
    }
    static void setHuhn(byte id, Huhn neuesHuhn) {
    	huehner[id] = neuesHuhn;
    }
}
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package zoo;
 
/**
 *
 * @author Frezl
 */
public class Huhn {
 
// ATTRIBUTE
	byte id;
    String Name;
    float Gewicht;
    String Farbe;
    int Alter;
    int Lebenskraft;
 
// METHODEN
    void gackern() {
        System.out.println(Name + ": gack");
    }
 
    void gruessen() {
        System.out.println(Name + ": Hallo, ich bin " + Name + ".");
    }
 
    void scharren() {
        System.out.println(Name + ": *scharr*");
    }
 
    void attackieren(Huhn Huhn) {
        Huhn.Lebenskraft = Huhn.Lebenskraft - 10;
        System.out.println("> " + Huhn.Name + " hat jetzt noch " + Huhn.Lebenskraft + " Lebenspunkte.");
 
        if(Huhn.Lebenskraft <= 0) {
            Huhn.finalize(); // Hier soll das attackierte Huhn getötet werden
            System.out.println("> " + Huhn.Name + " wurde von " + this.Name + " getötet.");
        }
    }
 
    Ei eiLegen() {
        System.out.println("> " + Name + " hat ein Ei gelegt.");
 
        return new Ei("braun", 45);
    }
 
// KONSTRUKTOR
    Huhn(byte id, String Name, float Gewicht, String Farbe, int Alter) {
    	this.id = id;
        this.Name = Name;
        this.Gewicht = Gewicht;
        this.Farbe = Farbe;
        this.Alter = Alter;
        this.Lebenskraft = 100;
 
        System.out.println("> " + Name + " wurde geboren.");
    }
 
// DESTRUKTOR
    @Override
    protected void finalize() {
        System.out.println(Name + ": *röchel*");
    	Main.setHuhn(id, null);
        System.out.println("> " + Name + " ist gerade gestorben.");
    }
 
}

btw. dachte ich immer, dass Ostereier von Hasen gelegt werden. :confused:


@Akeshihiro: Meinte nicht dich, wie ich begonnen habe war dein Post noch nicht da. It's a unsynchronized World. :(
 
Aaahja, interessant. Danke für den Post! Ich werds mir morgen mal genauer anschaun... Aber jetzt erst mal gute Nacht! *gähn*
 
Hallo, liebe Leute,

da mein eigentliches Problem ("Objekt soll anderes Objekt zerstören") an der Realität* vorbeizugehen schein, habe ich eine andere Lösung gefunden: Es gibt eine Klasse Gott, die andere Objekte erschaffen kann. Außerdem verwaltet sie das BuchDesLebens, in dem alle lebenden Objekte verzeichnet sind. Aus dieser Klasse wird das Objekt derHerr instanziert, der bis in alle Ewigkeit über seine Schöpfung wacht.

Das ganze sieht dann so aus:

Main.java
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package zoo002;

/**
 *
 * @author Frederik
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        // Gott wird erschaffen...
        Gott DerHerr = new Gott("DerHerr");

        // ...und beginnt mit der Arbeit.
        DerHerr.start();

        // als erstes erschafft er ein paar Hühner
        Huhn Elfi = DerHerr.erschaffeHuhn("Elfriede", 730, "braun");
        Huhn Berta = DerHerr.erschaffeHuhn("Berta", 523, "weiß");

        // Die Hühner leben friedlich auf dem Bauernhof
        Elfi.gruesse();
        Berta.gruesse();
        Elfi.scharre();
        Berta.gackere();
        Ei Osterei = Berta.legeEi();
        
        // Bis der Herr beschließt, dass es genug ist und ein Huhn tötet
        Elfi = DerHerr.toeteLebewesen(Elfi);     // hier fände ich eine Lösung mit Out-Parameter intuitiver!

        // Elfi.scharre();     // und hier wird eine Exception geworfen, weil das Huhn ja tot ist :-)

        // weil es jetzt aber Langweilig ist auf der Erde, schafft Gott wieder ein zweites Huhn
        Huhn Gundi = DerHerr.erschaffeHuhn("Kunigunde", 620, "schwarz");

        // und das Leben geht weiter...
        Gundi.gruesse();

        // ...bis Gundi eines Tages völlig grundlos auf Berta losgeht
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta);
        Berta.gackere();
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta);
        Gundi.attackiere(Berta); // hier stirbt Berta


    }

}

Lebewesen.java:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package zoo002;

/**
 *
 * @author Frederik
 */
public class Lebewesen {

    // ATTRIBUTE

    private String Name;
    private int Lebenskraft;


    // GETer & SETer

    void setName(String x) {
        Name = x;
    }

    String getName() {
        return Name;
    }
    
    void setLebenskraft(int x) {
        Lebenskraft = x;
    }

    void erhöheLebenskraft(int x) {
        Lebenskraft += x;
    }

    void erniedrigeLebenskraft(int x) {
        Lebenskraft -= x;
    }

    int getLebenskraft() {
        return Lebenskraft;
    }


    // DESTRUKTOR

    @Override
    protected void finalize() {
        System.out.println(this.getName() + "> ist gerade gestorben.");
    }

}

Huhn.java:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package zoo002;

/**
 *
 * @author Frederik
 */
public class Huhn extends Lebewesen {

// ATTRIBUTE
    
    private float Gewicht;
    private String Farbe;


// METHODEN

    void gackere() {
        System.out.println(getName() + ": *gack* *gack*");
    }

    void gruesse() {
        System.out.println(getName() + ": Hallo, ich bin " + getName() + ".");
    }

    void scharre() {
        System.out.println(getName() + "> scharrt auf dem Boden.");
    }

    void attackiere(Huhn Huhn) {
        Huhn.erniedrigeLebenskraft(10);

        if(Huhn.getLebenskraft() <= 0) {
            System.out.println(getName() + "> hat " + Huhn.getName() + " getötet!");
            // Wie im echten Leben! Da die Lebenskraft des Gegners <= 0 ist, meint das Huhn, es hätte seinen Gegner getötet.
            // Aber wirklich tot ist das Huhn erst, wenn Gott es von seinen Leiden erlöst hat.
            // Denn vielleicht lässt er es ja wiederauferstehen?
        } else {
            System.out.println(getName() + "> hat " + Huhn.getName() + " attackiert!");
        }
    }

    Ei legeEi() {
        System.out.println(getName() + "> hat ein Ei gelegt.");

        return new Ei("braun", 45);
    }

// KONSTRUKTOR
    Huhn(String Name, float Gewicht, String Farbe) {
        this.setName(Name);
        this.setLebenskraft(100);
        this.Gewicht = Gewicht;
        this.Farbe = Farbe;

        System.out.println(this.getName() + "> wurde soeben geboren.");
    }

}

Gott.java
Java:
package zoo002;


import java.util.ArrayList;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Frederik
 */
public class Gott extends Thread {  // eigentlich würde hier "extends Lebewesen impements Runnable" besser passen!

    // ATTRIBUTE

    String Name;
    
    private ArrayList<Lebewesen> BuchDesLebens;


    // METHODEN

    @Override
    public void run() {

        // Gott macht bis in alle Ewigkeit nichts anderes, als seine Schöpfung zu überwachen
        while(true) {
            for(int i = 0; i < (BuchDesLebens.size() - 1); i++) {
                Lebewesen Delinquent = BuchDesLebens.get(i);
                if(Delinquent.getLebenskraft() <= 0) {
                    this.toeteLebewesen(Delinquent);
                }
            }
        }
        
    }

    Huhn erschaffeHuhn(String Name, int Gewicht, String Farbe) {
        // Das, was Gott am liebsten macht - ein neues Huhn erschaffen:
        Huhn neuesHuhn = new Huhn(Name, Gewicht, Farbe);

        // jetzt kommt der Verwaltungskram:
        BuchDesLebens.add(neuesHuhn);      // Huhn ins Buch des Lebens eintragen

        // Das neue Huhn ins Leben entlassen:
        return neuesHuhn;
    }

    Huhn toeteLebewesen(Lebewesen altesLebewesen) {
        BuchDesLebens.remove(altesLebewesen);
        altesLebewesen.finalize();
        System.out.println(this.getName() + "> hat " + altesLebewesen.getName() + " von seinen Leiden erlöst.");
        return null;
    }


    // KONSTRUKTOR
    Gott(String Name) {
        this.setName(Name);
        BuchDesLebens = new ArrayList(0);
    }

}

Jetzt gibt es zumindest mal ein Konstrukt, das über Leben und Tod der einzelnen Objekte wacht. Wie kann ich es aber realisieren, dass derHerr darüber wacht, was ein Objekt darf und was nicht? Ich stell mir das so vor, dass Berta scharren will (Berta.scharre();). derHerr schaut dann in sein BuchDesLebens und sieht "oh, da steht keine Berta drin, also ist sie tot". Und dann verbietet er Berta das Scharren.

Du verstehst, was ich meine? Dass also nicht das Objekt selbst in jeder Methode prüft, ob es die noch ausführen darf oder nicht. Vielmehr soll das Objekt derHerr managen, ober ein anderes Objekt überhaupt noch irgendwas darf oder nicht. egal was das ist...

Viele Grüße,
Frezl

---------------------------
* Wer diesen Satz aufmerksam liest, merkt, dass ich ganz nebenbei die Existenz Gottes bewiesen habe...
 
Habs jetzt nur überflogen, aber ArrayList enthält dafür eine eigene Methode. Ich glaube sie heißt contains, aber hab Eclipse atm nicht gestartet. Daraus kannst du Gott eine Methode verpassen, die einen boolean zurückliefert, woraus du wieder prüfen kannst, ob es lebt. Wobei das wieder nicht so wäre, wie du willst, zu dem verstehe ich nicht warum man sowas in einer globalen Klasse speichern sollte, wenn es jedes Objekt für sich selbst enthalten könnte.

Vielleicht wäre für deine Methode eine HashMap besser, damit kannst du ein Objekt leicht wieder auf null setzen und das Huhn mit ihren Namen verknüpfen.
 
Wobei das wieder nicht so wäre, wie du willst, zu dem verstehe ich nicht warum man sowas in einer globalen Klasse speichern sollte, wenn es jedes Objekt für sich selbst enthalten könnte.

Wenn das Huhn selbst das Attribut boolean lebendig hätte, könnte es diesen Parameter auch selbst ändern. D.h. es kann selbst entscheiden, ob es tot, oder lebendig sein will. Das würde dann wieder nicht der Wirklichkeit entsprechen! Klar kann das Huhn Elfi Selbstmord begehen, indem es Lebensenergie = 0 setzt und darauf wartet, dass es von Gott aus der Liste der Lebenden gestrichen wird. Aber andersrum wird es natürlich nicht wieder lebendig, wenn es Lebensenergie > 0 setzt ;-) Daher will ich das auf diese Weise lösen...

Aber vielleicht ist mir bei meinem kreationistischen Programmieransatz auch ein kleiner Denkfehler unterlaufen: Wenn Gott über alles, was auf der Erde passiert, wacht, dann kann auch nur Gott dem Huhn erlauben, zu gackern. Demnach darf ich keinen direkten Pointer auf das Objekt Elfi setzten, sondern darf es nur über den Eintrag im BuchDesLebens ansprechen.

Mann mann, kompliziert! Gibt es Theologen unter uns, die mir erklären können, wie das mit Gott und der Schöpfung wirklich funktioniert?

Grüße,
Frezl
 
Also, ich glaube am Anfang schuf Gott über 6 Tage die Welt, am 7. Adam und Lilith. Lilith hat das Paradies verlassen, um sich mit den Sanddämonen in der Wüste zu verbünden, darum hat Gott Adam eine Rippe rausgerissen und daraus Eva geschaffen. Danach flogen sie raus, weil sie von Gottes Privatobst genascht haben, und seit dem sind wir Gott egal.

Weiß es aber nicht genau, glaube absolut nicht an Gott.

Ja, aber so genau kannst du die Realität auch nicht abbilden. Weiß ja keiner wie es wirklich ist. Außerdem hat ein Mensch auf seine HP (wenn man es so bezeichnen kann) auch keinen Zugriff, eine Instanz kann auf eine private Variable aber noch immer in jeder Instanz der Klasse zugreifen. Deshalb dürften die HP nicht im Huhn selbst gespeichert werden, was einerseits ein extrem kompliziertes Programm zur Folge hätte, andererseits den Sinn von OOP wieder nicht richtig nutzten würde.

Denke ich zumindest, hab mir darüber nie gedanken gemacht.
 
Der Gedanke, dass die Lebenspunkte dann nicht im Objekt selbst gespeichert werden dürfen, ist mir auch schon gekommen. Daraufhin habe ich festgestellt, dass Gott alles verwalten müsste UND DANN ist es mir wie Schuppen von den Augen gefallen: ICH BIN GOTT (Jedenfalls was mein Java-Programm betrifft). Schließlich bin ja ich der, der dem Huhn sagt, wann es gackern soll und ich bin auch der, der dem Huhn seine Lebenspunkte gibt und nimmt. Und wenn ich es will, dann kann das Huhn auch stricken :-)

Das ist also das Geheimnis der OOP :-O Wieder ein Mysterium gelöst.

Danke für eure Hilfe!

Grüße, Frezl
 
Was zum ... Das wird hier ja so langsam eine philosofische Angelegenheit xD

Warum machst du es dir so schwer? Es ist doch egal, ob ein Objekt im Nirvana ist oder nicht. Wenn du nicht mehr darauf zugreifst und alle Variablen von dem Objekt trennst (andere Referenz aufbauen oder null setzen), dann wird sich der GC schon darum kümmern. Ich hab langsam das Gefühl, dass du drauf aus bist NullPointerExceptions auszulösen, weil du Objekte killn willst, die noch Referenzen aufweisen und wenn eben so eine Referenz was ausführen will, dann wird es ein Problem geben, was nicht Sinn der Sache ist.

Man darf jetzt nicht den Fehler machen und versuchen ein lebendiges Wesen als lebendiges Wesen 1:1 abzubilden, das klappt eh nicht. Was Objekte intern machen, ist Sache der Objekte, der Zugriff von Außen aber nicht (z.B. Aktionen ausführen), das ist Sache des Controllers (Gott). Wenn ein Huhn tot ist, dann hat es das Flag tot auf true gesetzt, wenn das der Fall ist, sollten alle anderen Methoden nicht mehr ihre Aktionen ausführen. Es kann aber nicht sein, dass man auf NullPointerExceptions aus ist, um sicher zu stellen, dass ein Objekt verschwunden ist und damit Referenzen vorzeitig mit Gewalt vernichtet. Auch in C++ ist das nicht der Sinn dahinter, auch wenn es prinzipiell möglich ist. Die Destruktoren da werden eigentlich auch nicht für sowas verwendet, sondern damit beim Verwerfen des Objektes z.B. Arbeitsspeicher wieder sauber freigegeben wird etc., nicht um Pointer zu zerstören.

Mach dir einfach kein Kopf drum, was mit dem Huhn passiert, wenn es tot ist. Bau in die Methoden Abfragen ein, die prüfen, ob das Huhn tot ist und wenn ja, dann macht die Methode eben nichts. Das Huhn ist tot, na und? Wenn ein Huhn in der Realität tot ist, dann verpufft es ja nicht ins Nichts, der Körper ist immer noch da, es gackert zwar nicht mehr, aber man kann immer noch drauf zugreifen, z.B. es beerdigen. Wenn es nach dem Tot ins Nichts verschwindet, dann ginge das nicht mehr, genauso auch bei den Objekten. Es ist egal, ob das Huhn tot ist, sein Tod wird nicht am Nicht-"Vorhandensein" definiert, sondern anhand eines Flags, einer Eigenschaft, die zeigt, ob das Huhn tot ist oder nicht. In der Realität sieht das dann meist so aus, dass es sich nicht mehr bewegt (außer der Kopf wurde abgeschlagen und die Nerven spielen verückt) und Menschen sind ja schlau und sind in der Lage Schlussfolgerungen anzustellen: Huhn bewegt sich nicht (Kopf wurde zerquetscht) => muss tot sein.
 
Zuletzt bearbeitet:
Zurück