package oop.InnereKlassen;
/*
 * - diese ist die einfachste Variante einer innere Klasse
 * - wege der Schachtelung wird dieser Typ im Englischen "nested top-Level class" genannt
 * - diese Klasse kann das Gleiche wie "normale" Klassen oder Schnittstellen
 * - statische innere Klasse benötigen keine Instanzen (Exemplare) der äußeren Klasse
 * - statische innere Klasse werden nur sehr selten verwendet 
 * - Statische innere Klassen in Java können auf die statischen Elemente der äußeren Klasse zugreifen,
 *   (sobald) diese Elemente in der statischen inneren Klasse aufgerufen werden
 *  - der Zugriff von der äußeren Klasse auf die innere Klasse ist nur möglich, wenn die äußere Klasse eine Instanz der inneren Klasse erstellt,
		es sei denn, die innere Klasse ist statisch
	
	- der statische Klasse soll anderen Name als der äußere Klasse haben
		
 *  Wichtig: es gibt aber einen Weg, um auf die nicht-statische Elemente zuzugreifen (mit ein Objekt)
 */

public class StatischeInnereKlasse {
	public static int x = 2;
	private int y = 1;
	
	// äußere Klasse
		public static String außen() {
			return "ich bin außen";
		}
		
		// Zugriff auf die innere Klasse von äußen
		public int getf() {
			Innereklasse k1 = new Innereklasse();
			return k1.f;
		}
	
	//Innere klasse
	public static class Innereklasse{
		public static int d = x;
		public static int f = 20;
		
		public String toString() {
			return "ich bin innen";
		}
		//Aufruf der statische Attribute der x der äußern klasse
		public int getx() {
			return x;
		}
		
		// Aufruf der nicht statische Elemente der äußere Klasse
		public void printy(StatischeInnereKlasse ob) {
			System.out.println(ob.y);
		}
		
		//Aufruf der Konstruktor  der äußere Klasse
		 void accessOuterConstructor() {
			// Erstellen einer neuen Instanz der äußeren Klasse und Zugriff auf ihre Elemente
			 StatischeInnereKlasse newOuterInstance = new StatischeInnereKlasse();
			System.out.println("New Instance Variable: " + newOuterInstance.y);
			}

	}
	
	
	
	
	//zugreife auf innen und außen
	public static void main(String[] args) {
		
		//zugriff nur auf das äußere Klasse
		StatischeInnereKlasse außereKlasse = new StatischeInnereKlasse();
		System.out.println(außereKlasse.toString());
		//zugriff auf die elemente der innere Klasse von äußen
		System.out.println(außereKlasse.getf());
		//System.out.println(außereKlasse.f); Fehler geht nicht
		
		//Zugriff auf die innere Klasse
		StatischeInnereKlasse.Innereklasse innere = new StatischeInnereKlasse.Innereklasse();
		System.out.println(innere.getx());//2
		//System.out.println(innere.d);
		innere.printy(außereKlasse);
	}
	
}
