# Auf Variablen in fremden Objekten zugreifen



## nin (18. Mai 2005)

Hallo Forum,

ich bin ein blutiger Java-Anfänger, deswegen weiß ich nichtmal, ob meine Überschrift so sinnvoll gewählt ist, aber ich versuche es einfach mal damit.

Zu meinem Problem:

Ich habe eine Klasse, in der anfangs Objekte anderer Klassen erstellt und denen Werte übergeben werden. An dieser Klasse darf ich nichts ändern. Nachdem die Objekte erstellt wurden, möchte ich sie mit einer Funktion der 2. Klasse bearbeiten. Allerdings ist das Objekt, aus dem ich etwas auslesen will, Teil der 3. Klasse und ich kann die Variablen darin nicht auslesen, aber das muss doch irgendwie gehen?

Ich hoffe irgendwer kann mir helfen, auch wenn ich vermute, dass ich nicht fähig genug war, das Problem zu beschreiben.


Liebe Grüße
nin


----------



## Anselmus (18. Mai 2005)

nin hat gesagt.:
			
		

> Ich hoffe irgendwer kann mir helfen, auch wenn ich vermute, dass ich nicht fähig genug war, das Problem zu beschreiben.




da hast du wohl recht... poste mal deinen code und dann versuchs nochmal


----------



## dotlens (18. Mai 2005)

wenn du nur auslesen willst machst du getter methoden, welche die werte zurückliefern, die du möchtest. falls du sie auch setzen möchtest benötigst du noch setter methoden.

du öbergibst eine referenz auf das objekt mit deinen gewünschten Daten der klasse, die die Daten auslesen sollen und holst dann mit den getter methoden die werte.


----------



## nin (18. Mai 2005)

Das war zu vermuten. Also hier der Code:

Ich arbeite mit BlueJ, falls dieses Übersichtsdiagramm hilfreich ist, sagt bescheid 

Die vorgegebene Klasse, an der nicht geändert werden soll:

```
/**
 * Klasse FunctionalSimulator ist ein einfacher Logiksimulator, der nur 
 * Nand-Gatter simulieren kann und keine Zeitverzögerungen berücksichtigt.
 * Die zu simulierende Schaltung wird im Konstruktor der Klasse erzeugt.
 * Es handelt sich hierbei um einen einfachen Volladdierer.
 * Zum Testen Ihrer Klassen <CODE>Nand</CODE> und <CODE>Signal</CODE> müssen Sie
 * einfach nur eine Instanz dieser Klasse erzeugen und dann die Methode
 * <CODE>simulate()</CODE> aufrufen.
 * @author Christian Hochberger, TU Dresden
 * @version 1.0 Erste Fassung
 */
public class FunctionalSimulator   {

     // Eingänge (i1-i3) und Ausgänge (s1,s0) der Schaltung
    Signal	i1,i2,i3,s1,s0;
    // Innere Signale, geben das invertierte Signal der Eingänge an
    Signal	ni1,ni2,ni3;
    // Innere Signale, die bei der Berechnung der Summe benötigt werden
    Signal	t1,t2,t3,t4,t5,t6,t7;

    // Nand-Gatter zum Invertieren der Eingänge
    Nand	inv1,inv2,inv3;
    // Nand-Gatter zur Berechnung der Summe
    Nand	n1,n2,n3,n4,n5,n6,n7,n8,n9;
    
    /**
     * Konstruktor, der die zu simulierende Schaltung aufbaut.
     * Simuliert wird ein einfache Volladdierer.
     */
    public FunctionalSimulator() {
	// Alle Signale anlegen
	// Der Konstruktor bekommt einen Signalnamen als Parameter
    i1=new Signal("i1");
	i2=new Signal("i2");
	i3=new Signal("i3");
	ni1=new Signal("ni1");
	ni2=new Signal("ni2");
	ni3=new Signal("ni3");
	s1=new Signal("s1");
	s0=new Signal("s0");
	t1=new Signal("t1");
	t2=new Signal("t2");
	t3=new Signal("t3");
	t4=new Signal("t4");
	t5=new Signal("t5");
	t6=new Signal("t6");
	t7=new Signal("t7");

	// Alle Gatter anlegen
	// Parameter des Konstruktors ist die Anzahl von Eingängen
	// Die Inverter sind sozusagen entartete Nand-Gatter (1 Eingang)
	inv1=new Nand(1);
	inv2=new Nand(1);
	inv3=new Nand(1);
	n1=new Nand(3);
	n2=new Nand(3);
	n3=new Nand(3);
	n4=new Nand(3);
	n5=new Nand(3);
	n6=new Nand(3);
	n7=new Nand(3);

	n8=new Nand(4);
	n9=new Nand(4);

	// Inverter mit Ein- und Ausgängen verbinden.
	// Die Methode setInput() des Gatters bekommt die Nummer des Eingangs
	// und das Signal, mit dem dieser Eingang verbunden werden soll.
	inv1.setInput(0,i1);
	// Die Methode setOutput() bekommt nur ein Signal, welches durch diesen
	// Ausgang bestimmt wird
	inv1.setOutput(ni1);
	inv2.setInput(0,i2);
	inv2.setOutput(ni2);
	inv3.setInput(0,i3);
	inv3.setOutput(ni3);

	// Die Nand-Gatter zur Summenberechnung richtig verbinden
	n1.setInput(0,ni1);
	n1.setInput(1,ni2);
	n1.setInput(2,i3);
	n1.setOutput(t1);
	
	n2.setInput(0,ni1);
	n2.setInput(1,i2);
	n2.setInput(2,ni3);
	n2.setOutput(t2);
	
	n3.setInput(0,ni1);
	n3.setInput(1,i2);
	n3.setInput(2,i3);
	n3.setOutput(t3);
	
	n4.setInput(0,i1);
	n4.setInput(1,ni2);
	n4.setInput(2,ni3);
	n4.setOutput(t4);
	
	n5.setInput(0,i1);
	n5.setInput(1,ni2);
	n5.setInput(2,i3);
	n5.setOutput(t5);
	
	n6.setInput(0,i1);
	n6.setInput(1,i2);
	n6.setInput(2,ni3);
	n6.setOutput(t6);
	
	n7.setInput(0,i1);
	n7.setInput(1,i2);
	n7.setInput(2,i3);
	n7.setOutput(t7);

	// n8 und n9 berechnen die eigentlichen Ausgänge
	n8.setInput(0,t1);
	n8.setInput(1,t2);
	n8.setInput(2,t4);
	n8.setInput(3,t7);
	n8.setOutput(s0);

	n9.setInput(0,t3);
	n9.setInput(1,t5);
	n9.setInput(2,t6);
	n9.setInput(3,t7);
	n9.setOutput(s1);

	// Die Signale s1 und s0 sind mit keinen weiteren Gattern verbunden.
	// Sorgen Sie dafür, dass in diesem Fall eine Wertänderung dieser
	// Signale ausgegeben wird.
    }

    /**
     * Diese Methode führt die eigentliche Simulation durch. Dazu werden den
     * Eingangssignalen (i1,i2,i3) einfach nur neue Werte zugeordnet. Diese
     * Wertänderungen propagieren sich dann durch die Schaltung bis zum Ausgang
     * und werden dort ausgegeben.
     */
    public void simulate() {
	// Zunächst alle Eingänge auf false setzen (ist zwar schon nach dem)
	// Erzeugen des Gatters so, aber durch ein erneutes Setzen werden
	// die inneren Signale der Schaltung vernünftig berechnet)
	
	i1.setValue(false);
	i2.setValue(false);
	i3.setValue(false);

	// Eingang i1 auf true: Dadurch sollte als Summe s1=false und s0=true
	// herauskommen. Es ist aber normal, dass Änderungen an s1 und s0 mehrfach
	// ausgegeben werden, bevor das Endergebnis herauskommt.
	System.out.println("==== i1 -> true");
	i1.setValue(true);
	
	// Eingang i1 und i2 auf true: Dadurch sollte als Summe s1=true und
	// s0=false herauskommen.
	System.out.println("==== i2 -> true");
	i2.setValue(true);
	
	// Eingang i1,i2 und i3 auf true: Dadurch sollte als Summe s1=true und
	// s0=true herauskommen.
	System.out.println("==== i3 -> true");
	i3.setValue(true);
	
	// Eingang i1 und i3 auf true: Dadurch sollte als Summe s1=true und
	// s0=false herauskommen.
	System.out.println("==== i2 -> false");
	i2.setValue(false);
	
	// Eingang i3 auf true: Dadurch sollte als Summe s1=false und
	// s0=true herauskommen.
	System.out.println("==== i1 -> false");
	i1.setValue(false);

	// Eingang i2 und i3 auf true: Dadurch sollte als Summe s1=true und
	// s0=false herauskommen.
	System.out.println("==== i2 -> true");
	i2.setValue(true);
    }

    /**
     * Main Methode dieser Klasse. Sie müssen das im Moment noch nicht
     * verstehen. Diese Methode wird benötigt, wenn Sie den Simulator ohne
     * BlueJ laufen lassen wollen. Wenn Sie diese Klasse in BlueJ nutzen,
     * dann ignorieren Sie diese Methode einfach.
     */
    public static void main(String[] args) {
	FunctionalSimulator s=new FunctionalSimulator();

	s.simulate();
    }
}
```


1. Klasse (Signal):

```
public class Signal
{
   public boolean status;
   public String name;
   
	/**
	 * Constructor for objects of class Signal
	 */
	public Signal(String new_name)
	{
	    name = new_name;
	    status = false;
	}
       
        // Hier ist die Funktion, um die es geht (siehe Erklärung unten)
	public boolean setValue(boolean new_status)
	{
		status = new_status;
		return status;
	}

}
```

2. Klasse (Nand)

```
import java.util.ArrayList;

public class Nand
{
	public ArrayList input;
	public Signal output;
	public Signal i1;

	public Nand(int initialCapacity)
	{
		input = new ArrayList(initialCapacity);
	}

	public void setInput(int eingang, Signal name)
	{
	    input.add(name);
	}
	
	public Signal setOutput(Signal name)
	{
		output = name;
		return output;
	}
}
```


Ich sitze gerade an der Funktion setValue der Klasse Signal. Ich versuche dort die Werte der Nand-Objekte auszulesen ( z.B. System.out.println(n2.output); ), aber das funktioniert hinten und vorne nicht.


----------



## Anselmus (18. Mai 2005)

das geht nicht, weil es keine methode output in der klasse signal gibt... du bräuchtest ne methode, die dir den aktuellen wert eines signals zurückgibt...

etwa so


```
public boolean getSignalStatus(){
return status;
}
```

das kannst du dann ungefähr so aufrufen:


```
System.out.println(n2.getSignalStatus());
```


----------



## nin (18. Mai 2005)

Also, erst einmal vielen Dank für eure Antworten 


...aber ich bin wohl immernoch zu doof dazu.


Ich habe die Klasse Nand nun um diese Methode erweitert:


```
public Signal getNandOutput()
{
     return output;
}
```


Und versuche diese in der Klasse Signal (Methode setValue()) aufzurufen:

```
public boolean setValue(boolean new_status)
{
	status = new_status;
	System.out.println(n1.getNandOutput());
	return status;
}
```


Jetzt bekomme ich zwei verschiedene Fehler. Wenn ich die n1 oben in der Klasse Signal mit "Nand n1;" angebe, sagt er an der Stelle:

NullPointerException
null

Wenn ich sie nicht deklariere, meckert er, dass er die Variable nicht kennt.


----------



## Anselmus (19. Mai 2005)

ich seh grad n2 ist ja eine nand und kein signal... mein fehler...

aber ich wunder mich grade was die setOutput methode überhaupt macht... sie bekommt ein seignal übergeben und gibt das selbe signal wieder zurück??? für was ist denn das?

ich weiß außerdem grade gar nicht was du brauchst oder was du verändern willst...
wenn du willst kannst mich mal im icq anpiepen: 64341140


----------



## Anselmus (19. Mai 2005)

also um nand-objekte(ein nand ist ja nur ne liste mit signalen drin, wenn ich das richtige sehe) auszulesen zu können kannst du zb diese liste zurückgeben

(in nand)


```
public ArrayList getNand(){
return input;
}
```

dann brauchst du noch in der signal-klasse:


```
public boolean getSignal status(){
return status;
}


public String getSignalName(){
retrun name;
}
```

jetzt kannst du dir die liste übergeben lassen und dann die einzelnen objekte auslesen. allerdings wird das nicht in der klasse signal funktionieren, weil die das objekt n2 gar nicht kennt. das müßtest du schon in functionSimulator machen...

da kannst du dir dann die liste übergeben lassenund auslesen. zb:


```
ArrayList nandList = n2.getNand();
for (int i =0; i<nandList.size(); i++){
Signal newSignal = nandList.get(i);
System.out.println(newSignal.getSignalName);
System.out.println(newSignal.getSignalStatus);
}
```


----------



## nin (19. Mai 2005)

Ok, also der Reihe nach 

Output brauche ich später noch. Im Moment macht das nicht sonderlich viel, aber ich war ja noch nicht fertig.

Wenn es keine Möglichkeit gibt, die Nand's in der Klasse Signal bekannt zu machen, habe ich ein Problem, da in FunctionalSimulator vorgegeben ist, dass die Funktion setValue eine Methode von Signal ist. Vermutlich ist mein ganzer Ansatz dann wohl für den Papierkorb


----------



## Anselmus (19. Mai 2005)

also ich seh auch nicht den sinn darin die nand objekte in signal bekannt zu machen, weil nand-objekte ja auch selbst signal-objekte enthalten...

falls das ganze ne aufgabe ist, kannst du ja mal die aufgabe posten und was schon vorgegeben ist... allerdinsg hab ich keinen plan von BlueJ


----------



## Anselmus (19. Mai 2005)

setValue() setzt doch den wert eines Signals, und wenn ich das richitg sehe, kannst du doch auf die siganle direkt zugreifen...

zb

```
i1.setValue(true);
```


----------



## nin (19. Mai 2005)

Die Aufgabe ist hier zu finden:
http://www.mr.inf.tu-dresden.de/lehre/ss05/inf-et2/praktikum-et-2005.html

Es geht um die 1. Aufgabe (Übungsaufgabe).

Nach setValue müsste ich die gesamte Schaltung durchgehen und den Status aller Signale durchgehen, die mit dem Ausgangssignal über die Gatter  verändert wurden. Deswegen der Zugriff auf Nand, da steht drin wer mit wem verbunden ist.


----------



## Anselmus (19. Mai 2005)

ok. jetzt weiß ich zumindest, was dein problem ist =)

ich würde in der nand-klasse eine statische Liste/Vektor erzeugen, in die alle nand-objekte gelegt werden, die erzeugt werden.
wenn jetzt setValue aufgerufen wird rufst du von dort aus eine statische methode in nand auf (wo ja alle nands bekannterweise in der liste liegen), die alle neuen ausgänge berechnet... ich probier das mal, aber muß erst mal was arbeiten =)


----------



## Anselmus (19. Mai 2005)

so sollte das gehen. geht zumindest bei mir


```
import java.util.ArrayList;

public class Nand
{
	static ArrayList nandList = new ArrayList();
	 boolean help = true;
   public Signal outputSignal = new Signal("neu");
   ArrayList entrySignals;

   public Nand(int initCap)
   {
      entrySignals = new ArrayList(initCap);
   }
   
   public void setOutput(Signal name)
   {
      
	  outputSignal = name;
	  nandList.add(this);
      
   }
   

   public void setInput(int eingang, Signal name)
   {
       entrySignals.add(eingang, name);
   
   }
   
   public static boolean getNewStatus(boolean oldStatus){
   		boolean newStatus = oldStatus;
   		for(int i= 0; i<nandList.size(); i++){
   			Nand helperNand = (Nand)nandList.get(i);
   			newStatus = helperNand.checkNand();
   			(helperNand.outputSignal).setOutputValue(newStatus);
   			nandList.set(i, helperNand);
   			if(((helperNand.outputSignal).getName()).equals("s1") || ((helperNand.outputSignal).getName()).equals("s0")){
   				System.out.println((helperNand.outputSignal).getName()+" =>"+(helperNand.outputSignal).getValue());
   			}
   		}
   		return newStatus;
   }
   
   public boolean checkNand(){
   		for(int j = 0; j<entrySignals.size(); j++){
   			if( ((Signal)entrySignals.get(j)).getValue() == false){
   				
   				return true;
   			}
   		}return false;
   }
        
}
```



```
public class Signal {
	String name;
	boolean status;
	
	public Signal(String sName){
		name = sName;
	}
	
	public void setValue(boolean newStatus){
		status = newStatus;
		Nand.getNewStatus(status);
	}
	public boolean getValue(){
		return status;
	}
	public String getName(){
		return name;
	}
	public void setOutputValue(boolean newStatus){
		status = newStatus;
	}
}
```


----------



## nin (19. Mai 2005)

Wow, ich bin absolut begeistert!

Erst einmal vielen vielen Dank!

Der Knackepunkt ist also die Liste mit den Objekten 

Ich lese deinen Quelltext jetzt mal gaaanz genau durch und versuche es dann nochmal selber (sonst bringt die Übung ja nicht sonderlich viel...) 


Also, bis dann und nochmals Danke!


----------



## Anselmus (19. Mai 2005)

jep, war sicher auch nicht die idee  von dem forum das andere leuts die aufgabe für dich machen, aber hat spaß gemacht...daher... :wink:

kann morgen mal paar kommentare reinschreiben... dann haste vielleicht eher den durchblick


----------



## bygones (20. Mai 2005)

stephanschoeffel hat gesagt.:
			
		

> jep, war sicher auch nicht die idee  von dem forum das andere leuts die aufgabe für dich machen, aber hat spaß gemacht...daher... :wink:


es wird aber auch gar nicht gern gesehen !!


----------



## Anselmus (20. Mai 2005)

kannst ja weggucken  :wink:


----------

