JAVA & Objektorientiertes Programmieren
Eine Einführung in das objektorientierte Programmieren mit JAVA Diese Kartei baut auf dem Stoff des Moduls OOP an der HSLU geleitet von Roland Gisler auf.
Eine Einführung in das objektorientierte Programmieren mit JAVA Diese Kartei baut auf dem Stoff des Moduls OOP an der HSLU geleitet von Roland Gisler auf.
Kartei Details
Karten | 500 |
---|---|
Lernende | 19 |
Sprache | Deutsch |
Kategorie | Informatik |
Stufe | Universität |
Erstellt / Aktualisiert | 04.12.2016 / 16.08.2024 |
Weblink |
https://card2brain.ch/box/java_objektorientiertes_programmieren
|
Einbinden |
<iframe src="https://card2brain.ch/box/java_objektorientiertes_programmieren/embed" width="780" height="150" scrolling="no" frameborder="0"></iframe>
|
Diese Klasse ist typsicher. Sie Kann wirklich nur Temperatur-Objekte aufnehmen.
Nun möchten wir auch einen Speicher für die beiden Klassen Rectangle und Circle.
Schlechte Idee: Die StoreTemperatur-Klasse zu kopieren und den Datentyp anzupassen wäre ineffizient und würde viele Coderedundanzen erzeugen.
Was wäre besser?
Wir könnten Object als Typ für den Store verwenden.
Object ist der Supertyp aller Klassen, und kann somit jedes beliebige Objekt aufnehmen.
Wir haben damit den universellen Speicher erfunden?
Was ist der Nachteil wenn man alle Daten im universellen Speicher Object speichern?
Wir können zwar ganz einfach jedes beliebige Objekt darin speichern:
storeObject.save(new Rectangle(...));
Aber wenn wir das Objekt mit get() wieder holen wollen, kriegen wir dieses nur unter dem Supertyp Object, und müssen es somit explizit von Hand auf den eigentlichen Typ zurück casten. Rectangle rec = (Rectangle) storeObject.get(); nicht sehr elegant.
Was ist der Vorteil von Generics?
Generics erlauben uns, konkrete Klassen zu schreiben, deren exakt verwendete Typen parametrisiert werden können.
Bei der Deklaration einer Variablen von einem generischen Klassentyp geben wir zusätzlich was noch an?
Für welchen Datentyp diese verwendet werden soll:
StoreGeneric<Temperatur> tempStore = new StoreGeneric<>();
Hinweis: Da beim Konstruktor zwingend der selbe Typ stehen muss, darf man den Typ dort auch weglassen. Die leeren "<>" bezeichnet man Diamond-Operator
Die Verwendung von generischen Klassen ist in der Regel relativ einfach und intuitiv, wenn man das Konzept verstanden hat
Die eigene Implementation von generischen Klassen kan durchaus anspruchsvoll und trickreich sein
Warum testen wir?
Um die Qualität der Software zu überprüfen.
Qualität ist die Übereinstimmung mit den Anforderungen unter gleichzeitiger Einhaltung von Qualitätskriterien.
Was sind Qualitätskriterien einer Software?
Funktionalität, Zweckdienlichkeit, Robustheit, Zuverlässigkeit, Sicherheit, Effizienz, Benutzbarkeit, Geschwindigkeit, ...
Welche wichtige Methode für die Qualitätssicherung kann man vorallem anwenden?
Das Testen:
- Dabei überprüfen wir das Verhalten eines Programms anhand der Spezifikation (Anforderungen)
- Wichtig: Wir sollten so viel wie möglich automatisiert testen, weil manuelles Testen sehr aufwändig und zeitintensiv ist!
Welche Begleitmassnahmen zum Testen gibt es, welche qualitätssichernd und -unterstützend wirken?
beispielsweise: Reviews, Entwicklungsprozess, Walkthrough, Metriken, Analysen, Regression, Automatisation etc.
Welche Fehler kann man in einer Software finden (3 Fehlerarten)?
Syntaktische Fehler: Abweichungen von der Sprachsyntax
Semantische Fehler: inhaltliche Fehler
Funktionale Fehler: Abweichungen von den Anforderungen oder die Erfüllung falscher/unerwünschter Anforderungen
Was sind syntaktische Fehler?
Abweichungen von der Sprachsyntax (Schreibweise und Grammatik) -> formale Fehler.
- Beispiel auf Deutsch: "Der Leser list den Buch."
- Beispiel in Java: if (i = 10) then {i = 0;}
Syntaktische Fehler werden durch den Kompiler aufgedeckt!
Was sind semantische Fehler?
Abweichungen oder Unstimmigkeiten, die auf Kenntnissen über die Dinge beruhen -> inhaltliche Fehler.
- Beispiel auf Deutsch: "Die Erdnuss ass einen Elefanten."
- Beispiel in Java: double kelvin = celsius - 273.15d;
(Werden durch Testing gesucht)
Was sind funktionale Fehler?
Abweichungen von den Anforderungen oder die Erfüllung falscher/unerwünschter Anforderungen.
- Beispiel: "Ein Liter Bier kostet ab sofort CHF 1'000.-"
Funktionale Fehler können wir nur bedingt durch Testen finden!
Was bedeutet "Testen"?
Das systematische, gezielte und möglichst effiziente Durchprobieren nach verschiedenen Qualitätskriterien, wie z.B. der Funktionalität.
Man testet mit wohlüberlegten Eingabedaten / Testwerten und versucht dabei aussagekräftige Tests durchzuführen (kein zielloses, chaotisches "Pröbeln"!)
Was ist die grösste Schwierigkeit beim Testen?
Man kann zwar immer nur das Vorhandensein von Fehlern zeigen, aber nie die Abwesenheit von Fehlern beweisen. Nach einem Test weiss man nur, dass ein Programm für die getesteten Eingabedaten korrekt läuft. Darum wählt man die Eingabedaten so, dass man möglichst viele (bis alle) Fehler finden und eliminieren kann.
Welche verschiedene Testarten bzw. -verfahren gibt es?
Unit Tests, Integrationstests, Systemtests,
orthogonal dazu: Black- oder Whitebox Testing, man testet ohne oder mit Kenntnis der Implementation
Was sind Unit Tests?
Man testet "nur" eine Methode, Klasse bzw. Einheit. Sind sehr klein, übersichtlich, einfach, schnell ausführbar und einfach automatisierbar (Ausführung und Validation)
Was sind Integrationstests?
Man testet typisch mehrere Klassen (auch Module/Komponenten oder Teilsysteme) in ihrem Zusammenspiel. Schon deutlich aufwändiger, aber auch automatisierbar.
Was sind Systemtests?
Man testet das ganze System bestehend aus vielen Klassen bzw. Einheiten. Klassischen Testen, erst spät möglich, aufwändig, aber auch automatisierbar!
Welche Einheiten werden in Unit Tests getestet?
Die getesteten Einheiten sind einzelne Methoden bzw. Klassen.
-> kleine und sehr überschaubare Testfälle!
Bei Unit Tests werden die Testfälle programmiert und sind somit automatisiert, jederzeit schnell ausführbar und wiederholbar.
Die Verifikation ob die Testfälle von Unit Tests erfolgreich durchgeführt wurden, erfolgt wie?
Automatisch ("self-validating")
Welche Frameworks zu Unit Testing stehen für Java zur Verfügung?
z.B. JUnit (am populärsten), UnitNG, etc.
Zeige ein Beispiel eines Unit Tests in Java
Was ist "Good Practise" beim Erstellen von Unit Tests?
Testklassen erstellen:
Die Tests für eine Klasse Demo werden in einer eigenen Klasse DemoTest zusammengefasst. Test als Appendix für die einfache Zuordnung. Alle Testklassen werden in /src/main/test abgelegt!
Testmethoden erstellen:
Der Basisname für die Testfälle einer Methode foo(...) lautet testFoo[Xyz]().
test als Prefix, Xyz als freie, ergänzende Fallbeschreibung. Testmethoden haben keine formale Parameter
Empfehlungen für gute Unit Tests
Besser kleine Testmethoden als wenige (wie eine grosse z.B.)!
-> bessere Selektivität!
Möglichst wenige asser*(...)-Statements pro Testmethode.
Methoden mit Returnwert lassen sich am einfachsten testen. Bei void-Methoden testet man ggf. indirekt über Statusabfragen auf dem getesteten Objekt.
Getter&Setter-Methoden werden häufig gemeinsam oder indirekt und "beiläufig" mitgetestet.
Nie für die Testbarkeit Schnittstellen oder Sichtbarkeit ändern!
Ist eine Klasse oder Methode schwierig zu testen, sollte man deren Design hinterfragen, kann ein Hinweis sein!
Wir testen ________, um _________ Gewissheit zu haben, dass es funktioniert
Was ist die Hauptaussage der TestFirst-Methodik?
Immer vor der Implementation die Testfälle schreiben!
Was sind die Vorteile der TestFirst-Methodik?
- Während dem Schreiben der Testfälle denkt man unmittelbar auch an die Implementation des zu testenden Codes. Dabei "reift" diese buchstäblich heran!
- Typisch fallen einem dabei viele Ausnahmen und Sonderfälle ein, welche man bei der Implementation der eigentlichen Komponenten dann "automatisch" auch berücksichtigt.
- Kaum ist die Komponente fertig, kann sie sofort getestet werden!
Was ist der einzige Haken bei der TestFirst-Methode?
Man muss es wollen und machen!
Was ist Code Coverage?
Code Coverage ist eine Metrik, welche zur Laufzeit misst (zählt), welche Quellcodezeilen abgearbeitet wurden.
Diese Messung wird typisch bei der Ausführung der Unit Testfälle (z.B. mit JUnit) durchgeführt.
(Aber auch zur normalen Laufzeit zur Messung, welche Funktionen tatsächlich genutzt werden!)
Somit kann eine Aussage gemacht werden, wie umfassend der Code tatsächlich getestet wurde!
Ist hohe Code Coverage ein Beweis für gute Testfälle oder Fehlerfreiheit?
Nein, weder noch! Es ist ein Mittel zur gezielten Effizienzsteigerung der Testfälle.
Worin besteht der Unterschied zwischen den folgenden Aussagen?
- Er benutzt dieselbe Zahlbürste
- Er benutzt die gleiche Zahnbürste
- Er benutzt eine Zahnbürste
Überlege dir auch ein Beispiel dazu in der Objektorientierung
Identität, Wertegleichheit, Typgleichheit
Man unterscheidet in der Programmierung zwischen drei verschiedene Arten von Gleichheit, die je nach Kontext und Anforderungen zum Einsatz kommen. Welche?
Identität (Entity Types)
Wertegleichheit (Value Types)
Typgleichheit (Class Types)
Es besteht also eine implizite Reihenfolge bezüglich der Strenge, wie eine potentielle Gleichheit betrachtet wird.