Mastodon Nachhilfe | Nachhilfe online + Nachhilfe zu Hause : Nachhilfe-Vermittlung
...
close

Cookie-Einstellungen

Zulassen:

 

Infos/Erklärung
Gemäß Ihrem Recht auf informierte Selbstbestimmung.

Besser wissen durch Nachhilfe: Wissensfragen

Hier kannst Du eine Wissensfrage zu einem Thema stellen, das Dich interessiert.
Die Fragen und die Antworten darauf werden hier veröffentlicht und evtl. zusätzlich an interessierte Benutzer (Nachhilfelehrer/innen) weitergeleitet.

Die Fragen sollten eher allgemeiner Natur sein, z.B. : "Ich will eine chinesische Sprache lernen. Mandarin oder Kantonesisch?", oder: "Vor Klausuren bin ich immer sehr nervös und bin schnell blockiert, obwohl ich vorbereitet bin - was kann ich tun?"

Alle Fragen & Antworten werden moderiert. Unangebrachte oder unhöfliche Beiträge, Links zu anderen Webseiten o.ä. werden gelöscht. Achtung: hier gibt es keinen Kundenservice.
Dieser Service soll keinen Unterricht ersetzen.

OOP und Statische Klassen und Variablen

Ich bin neu in Sachen Objektorientierter Programmierung, .. was sind statische Klassen, Funktionen, oder statische Variablen? (static) - ich kenne mich bisher eher mit prozeduraler Programmierung aus und komme mit den bisherigen Erklärungen noch nicht so ganz klar.
OOP, statische Variablen, statische Klassen
Datum: 17.02.19 15:33, Benutzer 300866Antwort:
Eine Funktion ist einfach eine kleine Methode/Prozedur innerhalb eines Objektes die etwas durchführt, sprich ein Unterprogramm aber halt auch nur da nutzbar.
Bei "static" ist es so das das eine ähnliche Form ist wie "global", so eine Variable gilt dann für alle Objekte einer Klasse. Andere Variablen gelten nur innerhalb einer Instanz.
z.B. Ich habe eine Klasse "Tier" mit einer Unterklasse "Hund", in dieser sind 2 Variablen "Farbe" normal(static) und "Größe"(normal) wenn ich jetzt 2 Instanzen Waldi und Bello bilde, hätte jede Instanz eine eigene "Größe" aber die "Farbe" gilt für alle. Sollte ich noch eine Unterklasse "Katze" haben ist aber auch hier "Farbe" nicht sichtbar. Setzt sich dann eben mit allen Elementen fort.
+ 2 weitere Antworten:
Datum: 17.02.19 20:59, Benutzer: 26884

Kurz, aber nicht exakt: Statische Klassen-"member" werden von allen Objektinstanzen geteilt (shared), während alle nicht-statischen Member nur innerhalb (genau) einer Objektinstanz existieren.

Langversion: Eine Klasse definiert normalerweise einen Objekttyp, bestehend aus Konstanten, Eigenschaften (Variablen) und Methoden (Funktionen). Ziel ist dabei meist, eine oder mehrere unabhängige "Instanzen" dieser Klasse bzw. dieses Objekttyps zu generieren, eben die Objektinstanzen; (ähnlich, als würde man mehrere Variablen desselben Datentyps erstellen). Dabei erhält jede Objektinstanz ihren eigenen "Satz" an Objektvariablen, die nur in dieser Instanz existieren. Statische Klassenvariablen sind jedoch nicht Teil der Objektinstanz, sondern sind an die Klasse selbst gebunden. Ändert eine Objektinstanz den Wert einer statischen Klassenvariablen, dann betrifft dies die Klasse an sich und letztlich auch alle anderen Instanzen dieser Klasse, die auf diese statische Variable zugreifen. Statische Klassen-Funktionen können direkt aufgerufen werden, ohne eine Instanz zu benutzen, nicht-statische Objektmethoden dagegen nicht, deren Aufruf kann nur über das jeweilige instanzierte Objekt erfolgen. Statische Methoden und Eigenschaften werden oft dazu verwendet, um die Instanzen einer Klasse selbst zu kontrollieren. Manchmal ist es z.B. wünschenswert, das maximal eine Objektinstanz existiert, und beim Versuch, neue Instanzen zu erzeugen stattdessen die bereits bestehende Instanz Verwendung findet (das sogenannte "Singleton" Entwurfsmuster). Oder es soll einfach die Anzahl an Instanzen gewählt werden. In beiden Fällen benötigt man statische member.

Datum: 16.02.21 03:57, Benutzer: 302646zuerst static funktionen und static variablen. static (inner) klassen sind bischen anders.

kurze antwort: static funktionen und static variablen sind an keiner instanz gebunden. sie sind stattdessen an einer klasse gebunden. alle weitere eigenschaften von static ist von dieser tatsache abgeleitet.

zum kontrast: instanzmethoden (funktionen ohne static) und instanzvariablen (variablen ohne static) sind immer an einer instanz gebunden.

instanzen (bzw. objekte) in der objektorientierten ideale sind dinge mit eigenschaften und verhalten. die eigenschaften werden in (instanz)variablen gespeichert und das verhalten wird durch (instanz)methoden realisiert. dabei gilt (bzw. sollte gelten): die methoden sollten nur variablen der eigenen instanz ändern und die variablen sollten nur von den methoden der eigenen instanz verändert werden.

wenn ein java programm gestartet wird dann existieren die klassen in gewisser weise automatisch. mit den klassen existieren dann auch die static funktionen und static variablen. die instanzen hingegen müssen explizit mit den stichwort new erzeugt werden. die dazugehörigen instanzmethoden und instanzvariablen existieren auch erst dann. ohne instanz keine instanzvariablen. jede instanz seine eigene kopie von instanzvariablen.

beispiel static funktion:

String eingabe = "42";
int zahl = Integer.parseInt(eingabe);

zahl beinhaltet jetzt den integerwert 42

parseInt() ist eine static funktion. die funktion ist in der klasse Integer. man braucht (und soll) kein objekt von Integer instanziieren um parseInt() verwenden zu können.

beispiel instanzmethode:

String eingabe = "23 24 25";
Scanner scanner = new Scanner(eingabe);
int zahl1 = scanner.nextInt();
int zahl2 = scanner.nextInt();
int zahl3 = scanner.nextInt();

zahl1 beinhaltet jetzt den integer wert 23, zahl2 den integer wert 24, zahl3 den integer wert 25.

nextInt() ist eine instanzmethoden. die methode ist an der instanz scanner gebunden. scanner muss zuerst instanziiert werden mit new. ohne die instanziierung hätte man nextInt() nicht aufrufen können.

hier nicht sichtbar sind die instanzvariablen von scanner. scanner muss instanzvariablen haben um zu merken wie weit es in der eingabe schon gekommen ist. nach den ersten nextInt() aufruf wird gespeichert das "23" verarbeitet wurde. nach den zweiten aufruf das "24" verarbeitet wurde. nach den dritten das "25" verarbeitet wurde. ein weiterer aufruf würde ein fehler geben weil es keine weitere integers gibt in der eingabe.

beachte: wenn man die static funktion parseInt() noch mal mit den gleichen parameter aufruft würde man genau das gleiche ergebnis noch mal bekommen. die instanzmethode nextInt() hingegen liefert bei jeden aufruf ein anderes ergebnis. das nennt man nebeneffekt.

ein nebeneffekt sind veränderung im zustand des programs über den rückgabewert der funktion hinaus. oder mit anderen worten: eine nebeneffektfreie funktion liefert bei gleicher eingabe immer das gleiche ergebnis. eine funktion (oder methode) mit nebeneffekt hingegen kann bei gleicher eingabe andere ergebnise liefern.

static funktionen sind in der regel nebeneffektfrei. instanzmethoden hingegen haben oft nebeneffekte.

die nebeneffekt(freiheit) ist keine notwendige folge von static oder nicht static. es ist möglich (aber oft nicht sinnvoll) static funktionen mit nebeneffekte zu schreiben und instanzmethoden ohne nebeneffekte.

wenn eine static funktion nebeneffekte speichern will dann kann es dass nur tun in dem es static variablen verwendet. da es keine instanz hat kann es auch keine instanzvariablen verwenden. wenn du dich allerdings ertappst wie du eine static funktion mit nebeneffekt geschrieben hast dann solltest du funktion und variable zu instanzmethode und instanzvariable umwandeln. dafür sind instanzen da. um nebeneffekte zu speichern.

eine (zeitweise) nebeneffektfreie instanzmethode kommt häufiger vor. das sind in der regel informationsgebende methoden. z.b. scanner.hasNextInt() (gibt es ein nächsten integer? ja oder nein). das ergebnis wird auch bei mehrfachen aufrufen gleich bleiben (nebeneffektfrei) bis man eine methode wie nextInt() aufruft die als nebeneffekt den zustand der instanz verändert.

wir halten fest:

static funktionen leben in einer klasse. können (und sollten) ohne instanziierung aufgerufen werden. sollten keine nebeneffekte haben. und wenn sie nebeneffekte haben dann sollten sie zu instanzmethode umgewandelt werden.

instanzmethoden leben mit einer instanz. können nur von einer instanz aufgerufen werden. haben oft nebeneffekte. die nebeneffekte werden in der instanz (genauer: instanzvariablen) gespeichert.

desweiteren (in den beispielen oben nicht demonstriert): instanzmethoden können auf static variablen zugreifen. static funktionen können aber nicht ohne weiteres auf instanzvariablen zugreifen.

wann sollte man static verwenden:

static variablen sollte man verwenden wenn man konstanten speichern will. z.b. Math.PI. für alles andere sollte man instanzvariablen verwenden.

manchmal heißt es das man static verwenden soll wenn man eine variable hat die bei allen instanzen der klasse den gleichen wert haben soll. das ist (meiner meinung nach) eine veraltete ansicht. der grund für diese empfehlung liegt wohl darin das damals die computer noch nicht so mächtig waren wie heute. eine static variable ist "billiger" als eine instanz(variable). heute sind computer mächtiger als damals. arbeitsspeicher ist billig(er als damals). also, so lange es keine konstante ist, besser instanzvariablen verwenden.

static methoden sollte bzw. kann man verwenden wenn man keine nebeneffekte brauch. beispiele auch hier in der Math klasse: Math.sin(), Math.sqrt(), Math.pow(). insgesamt ist die Math klasse eine sammlung von konstanten und nebeneffektfreien mathematischen funktionen. ausnahme ist Math.random() welches bei jeden aufruf eine neue (pseudo)zufällige zahl liefert und somit ein nebeneffekt hat. der grund für Math.random() ist wohl komfort für den programmierer nicht erst ein random objekt instanziieren zu müssen wenn man doch nur eine zufallszahl haben will.

kommen wir zu static klassen:

static klassen gibt es nur als static *inner* klassen. inner klassen sind klassen die in anderen klassen eingebettet sind. grund ist der zugriff auf variablen. inner klassen können auf die private variablen der äußeren klasse zugreifen. ob man eine inner klasse static machen will hängt wiederrum an der instanz.

soll man die inner klasse verwenden können ohne eine instanz der äußeren klasse dann muss es static sein.

soll man die inner klasse nur verwenden können mit einer instanz der äußeren klasse dann darf es nicht static sein.

ein beispiel für inner klassen ohne static sind iteratoren. iteratoren werden verwendet um die einzelnen elemente einer collection zu erhalten. normalerweise in einer schleife. iteratoren werden meist als inner klasse von collection klassen implementiert um zugriff auf die (sinnvollerweise privaten) variablen der collection zu haben. iteratoren können keine static inner klasse sein weil ein iterator ohne eine instanz der collection ist sinnfrei.

ein beispiel für static inner klassen sind Line2D.Float und Line2D.Double. beide kann man verwenden ohne eine instanz von Line2D haben zu müssen. (insbesondere ist Line2D abstract so dass man sowieso keine instanz davon erzeugen kann).

soweit ich erkennen kann ist es nicht notwendig dass Line2D.Float und Line2D.Double static inner klassen sein müssen. es hätten wohl genauso gut eigenständige klassen (dann ohne static) sein können. notwendig wäre es dann wenn z.b. Line2D.Float auf eine private static variable von Line2D zugreifen wöllte.

ein beispiel von einer notwendigerweise static inner klassen habe ich nicht gefunden. static inner klassen werden wohl hauptsächlich verwendet um code zu organisieren. z.b. um die enge verwandschaft von klassen zu verdeutlichen wie bei Line2D.Float und Line2D.Double.

zu lang; nicht gelesen! (zusammenfassung:) static -> ohne instanz. kein static -> mit instanz!

bonus! da du prozedural erwähnt hast: wenn du in java alles static machst dann würdest du prozedural programmieren. das macht kein spaß aber ist möglich.

links!

doc für Integer.parseInt(): https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt(java.lang.String)

doc für Scanner: https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

iterator als beispiel für inner klasse ohne static: https://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html

code von Line2D.Float und Line2D.Double als beispiel für static inner class: https://github.com/openjdk/jdk/blob/739769c8fc4b496f08a92225a12d07414537b6c0/src/java.desktop/share/classes/java/awt/geom/Line2D.java
Aktion: ANTWORTEN
 
Weitere Fragen: 176









Merkzettel ()