OOP Basics

Werbung
OOP Basics
Arthur Zaczek
Aug 2015
OOP Basics
1
Was sind “Objekte”?
1.1
Ein Java-Beispiel
public class Pet {
private int _weight;
public int getWeight() {
return _weight;
}
public Pet() {
_weight = 100;
}
public void eat(int amount) {
_weight += amount;
}
public abstract string sound();
}
1.2
Ein C#-Beispiel
public class Pet {
private int _weight;
public int Weight {
get { return _weight; }
}
public Pet() {
_weight = 100;
}
public virtual void Eat(int amount) {
_weight += amount;
}
public abstract string Sound();
}
1.3
Was sind “Klassen”?
Eine Klasse ist eine Übereinkunft über das Verhalten von Instanzen
• Daten:
– Weight
• Methoden:
– Eat(), Sound()
1
OOP Basics
1.4
Was sind “Instanzen”?
Eine Instanz ist ein konkretes “Objekt” einer Klasse
Pet tom = new Pet();
Pet jerry = new Pet();
tom.Eat(50);
tom.Weight == 150;
jerry.Weight == 100;
1.5
Was sind “Objekte”?
• “Objekt” ist ein Überbegriff für Klassen und Instanzen, wird typischerweise anstelle von
“Instanz” verwendet
• “Objekt-orientiert” sind Programmiermethoden, die Daten und Methoden als Einheit sehen
• Objekt-orientierte Programmiersprachen unterstützen diesen Ansatz mit ihren Features
2
Kapselung
2.1
Kapselung
• Als Kapselung bezeichnet man in der Programmierung das Verbergen von Implementierungsdetails.
• Der direkte Zugriff auf die interne Datenstruktur wird unterbunden und erfolgt statt dessen
über definierte Schnittstellen.
• Objekte können den internen Zustand anderer Objekte nicht in unerwarteter Weise lesen
oder ändern.
• Ein Objekt hat eine Schnittstelle, die darüber bestimmt, auf welche Weise mit dem Objekt
interagiert werden kann.
2.2
Beispiel ohne Kapselung
public class Pet {
public int Weight;
}
Pet tom = new Pet();
tom.Weight = -100; // Was nun?
2.3
Beispiel mit Kapselung
public class Pet {
private int _weight;
public int Weight {
get { return _weight; }
}
}
2
OOP Basics
Pet tom = new Pet();
tom.Weight = -100; // Compilererror
2.4
Sinn
• Implementor: Innerhalb der privaten Teile der Klasse kann man sich darauf verlassen, dass
nur lokale Methoden den Zustand der Instanz ändern.
• Benutzer: Muss sich nicht um Implementationsdetails der verwendeten Klasse kümmern.
3
Vererbung
3.1
Vererbung
• Verknüpft Klassen in einer Hierarchie
• Abgeleitete Klassen können überall eingesetzt werden wo eine ihrer Basisklassen erwartet
wird
• Abgeleitete Klassen erweitern und verändern Funktionalität
• Basisklassen stellen allgemeine Funktionalität zur Verfügung
3.2
C#:
Java:
Beispiel Ableitung
public class Cat : Pet
public class Cat extends Pet
{
public void Scratch(object furniture) {
// ...
}
}
Cat tom = new Cat();
Pet jerry = new Pet();
tom.Eat(50);
jerry.Eat(5);
tom.Scratch(chair);
jerry.Scratch(chair); // error: no Cat
3.3
Interpretation
• Objekte vom Typ “Cat” haben alle Daten und Funktionen des Typs “Pet”
• Klasse “Cat” erweitert “Pet” um die Funktion “Scratch()”
3.4
Sinn
• Definierte Eingriffe in gekapselte Funktionalität
• Erweiterung von Funktionalität ohne Details kennen zu müssen
3
OOP Basics
3.5
Methoden überschreiben
Manchmal ist es notwendig oder praktisch, in abgeleiten Klassen zu ersetzen
• Java: Überschreibung mit @Override, verhindern mit final
• C#: Methode muss als virtual gekennzeichnet sein, Überschreibung mit override, verhindern mit sealed
3.6
Methoden überschreiben
Die Implementierung der Basisklasse kann dann immer noch benutzt werden
• Java: super.Methode(...) ruft Implementierung der Parent-Klasse auf
• C#: base.Methode(...) ruft Implementierung der Parent-Klasse auf
3.7
Methoden überschreiben - Java
public class Pet {
public void eat(int amount) {
}
}
public class Cat extends Pet {
@Override
public void eat(int amount) {
// cats need much energy
super.eat(amount / 2);
}
}
Pet fritz = new Cat();
fritz.eat(50); // fritz.Weight == 125
3.8
Methoden überschreiben - CS
public class Pet
{
public virtual void Eat(int amount)
{
}
}
public class Cat : Pet
{
public override void Eat(int amount) {
// cats need much energy
base.Eat(amount / 2);
}
}
Pet fritz = new Cat();
fritz.Eat(50); // fritz.Weight == 125
4
OOP Basics
3.9
C++: Mehrfachableitung
• Im Gegensatz zu C# und Java kann C++ auch von mehreren Basisklassen ableiten
• Die resultierende Klasse muss alle Eigenschaften aller Basisklassen beachten
• In manchen Fällen sind dazu komplexe Auflösungsregeln erforderlich
4
Schnittstellen
4.1
•
•
•
•
4.2
Schnittstellen
Definiert Funktionen ohne Implementierung
Wirkt als einfacher Vertrag zwischen Komponenten
Kann immer statt einer spezifischen Klasse als Variablentyp eingesetzt werden
Vermeidet Bindung an spezifische Implementierung
Polymorphismus
• Objekte mit der gleichen Schnittstelle können benutzt werden ohne ihren spezifischen Typ zu
kennen
• Ermöglicht durch Vererbung
• Eine Klasse kann mehrere Schnittstelle implementieren
• Vereinfacht durch Schnittstellen
http://www.complang.tuwien.ac.at/franz/objektorientiert/skript07-1seitig.pdf
4.3
Beispiel
public interface Feedable {
/* Let the instance eat an amount of food */
void eat(int amount);
}
4.4
Java-Implementierung
public class Pet implements Feedable {
public void eat(int amount) {
// ...
}
}
public class StarShip implements Feedable {
public void eat(int amount) {
// ...
}
}
void feed(Feedable something, int amount) {
something.eat(amount);
}
5
OOP Basics
Cat tom = new Cat();
StarShip enterprise = new StarShip();
feed(tom, 50);
feed(enterprise, 50);
4.5
C#-Implementierung
public class Pet : IFeedable
{
public void Eat(int amount)
{
// ...
}
}
public class StarShip : IFeedable
{
public void Eat(int amount)
{
// ...
}
}
void Feed(IFeedable something, int amount)
{
something.Eat(amount);
}
Pet tom = new Pet();
StarShip enterprise = new StarShip();
Feed(tom, 50);
Feed(enterprise, 50);
4.6
Sinn
Erlaubt es Funktionalität ohne Rücksicht auf tatsächlichen Typ des Objektes zu implementieren
4.7
C# Spezifisches
• Interfaces werden mit einem I am Anfang benannt IFeedable
• Interfaces können auch explizit implementiert werden. Die Klasse beinhaltet dann die
Methoden nicht, eine Instanz lässt sich aber in den Typ der Schnittstelle casten.
public class Duck : IFeedable
{
void IFeedable.Eat(int amount)
{
// ...
}
}
Duck daffy = new Duck();
daffy.Eat(50); // Compile error
6
OOP Basics
IFeedable f = (IFeedable)daffy;
f.Eat(50); // Legal
5
Sprachfeatures
5.1
Gruppieren von Klassen
• namespaces (C#) oder packages (Java) gruppieren Klassen in Namensräumen
• Ansprechen von “Fremd-”Klassen über using bzw. import oder absoluten Namen
5.2
Beispiel: namespace
namespace Animals {
public class Pet { /* ... */ }
public class Cat : Pet { /* ... */ }
}
Animals.Cat tom;
using Animals;
Cat tom;
5.3
Beispiel: package
package Animals;
public class Cat extends Pet { /* ... */ }
Animals.Cat tom;
import Animals.Cat;
import Animals.*;
Cat tom;
5.4
Accessibility
• public: Teil der öffentlichen - für alle erreichbaren - Schnittstelle
• protected: nur für die Klasse und ihre Erben sichtbar
• private: nur für die Klasse sichtbar
• C#: internal: nur für Mitglieder der aktuellen DLL/EXE Assembly sichtbar
• Java: ohne Schlüsselwort, nur für Mitglieder des aktuellen Packages sichtbar
5.5
Fields
private float _weight;
• Felder halten den unmittelbaren Zustand einer Instanz
• Sollten immer private sein
7
OOP Basics
5.6
Properties CS
public float Weight {
get { return _weight; }
protected set { _weight = value; }
}
• Daten können geprüft, geändert oder konvertiert werden
• In der Regel ist auch der Setter public. Der protected Setter ist hier nur ein Beispiel.
• In Spezialfällen, zB bei der Verwendung von Listen, kann er auch als private markiert werden
oder ganz weggelassen werden.
5.7
Properties Java
public float getWeight() {
return _weight;
}
protected void setWeight(float value) {
_weight = value;
}
• Java unterstützt keine besondere Property-Syntax
• Konvention: get* und set* Methoden
5.8
Methods
• Eine Methode kapselt ein Stück prozeduralen Code
• Argumente sind die erwarteten Informationen
• Parameter sind die tatsächlich übergebenen Werte
• Rückgabewerte oder void
• this: Zugriff auf die aktuelle Instanz
• base bzw. super: Zugriff auf die übergeordnete Instanz
5.9
Überladen
Um elegantere Schnittstellen zu erzeugen, erlauben C# und Java Methoden mit gleichem Namen
aber unterschiedlichen Argumentlisten.
public void Feed(Cat c) { /* ... */ }
public void Feed(Dog d) { /* ... */ }
Dog spike = new Dog();
Feed(spike); // ruft richtige Methode auf
Der Rückgabetyp muss immer gleich sein.
8
OOP Basics
5.10
Klassenvariablen: static
Manche Informationen oder Funktionen sind nicht Instanz-spezifisch sondern arbeiten auf der
gesamten Klasse. Diese werden mit static markiert:
public class Pet {
private static HashSet _allPets = new HashSet();
public static Set getAllPets() {
return (Set)_allPets.clone();
}
public Pet() {
_allPets.add(this);
}
}
Pet.getAllPets().size()
5.11
Operator overloading
In C# können Operatoren durch Klassen überladen werden:
public class Complex
{
public static Complex operator +(Complex a, Complex b)
{
// ...
}
}
6
Exceptions
6.1
Beispiel
try {
throw new ArgumentNullException(„arg“);
} catch(ArgumentException aex) {
...
} catch(InvalidOperationException opex) {
...
} catch(Exception ex) {
...
} finally {
...
}
6.2
catch
• Einen Catch – Block immer dort einbauen, wo man die Exception auch behandeln kann
• Niemals Exceptions „schlucken“, d.H. fangen und nicht reagieren
• Nach Möglichkeit sollten allg. Exceptions nicht gefangen werden, sondern nur konkrete z.B.:
– SQLException
9
OOP Basics
– FormatException
• Nur das stellt sicher, dass man den „richtigen“ Fehler behandelt
6.3
finally
• finally Blöcke helfen, Ressourcen wieder frei zu geben
• Damit ist man immun gegen Ressource- bzw. Memoryleaks
6.4
Exceptions werfen
• Immer die passende Exception werfen z.B.:
– FileNotFoundException
– ArgumenNullException
• Stellt das Framework/Sprache keine passende Exception zur Verfügung -> selber implementieren
– Nur das stellt sicher, dass im Fehlerfall alle wichtigen Informationen gesammelt und
ausgewertet werden können.
6.5
Beispiele
java.net.UnknownHostException: dasz.a2t
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:177)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:525)
at java.net.Socket.connect(Socket.java:475)
at java.net.Socket.<init>(Socket.java:372)
at java.net.Socket.<init>(Socket.java:186)
at javasockets.Main.read(Main.java:36)
at javasockets.Main.main(Main.java:30)
6.6
Beispiele
Exception in thread "Thread-7" java.lang.NullPointerException
at java.util.LinkedList.remove(LinkedList.java:791)
at java.util.LinkedList.remove(LinkedList.java:226)
at javathreads.LockThread.run(LockThread.java:37)
Code:
if (!strings.isEmpty()) {
String str = strings.peek();
System.out.println(str);
// Do some work
Thread.sleep(20);
strings.remove(str);
}
10
OOP Basics
6.7
Beispiele
System.IO.FileNotFoundException: Could not load file or assembly ‚Zetbox.Objects' or one of its de
File name: 'Zetbox.Objects'
at System.RuntimeTypeHandle._GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCas
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase
at System.RuntimeType.PrivateGetType(String typeName, Boolean throwOnError, Boolean ignoreCase,
at System.Type.GetType(String typeName, Boolean throwOnError)
at Zetbox.API.FrozenContext.TryInit() in p:\Zetbox\API\FrozenContext.cs:line 101
6.8
Beispiel
System.ArgumentNullException was unhandled
Message="Value cannot be null.\r\nParameter name: stream"
Source="CSSockets"
ParamName="stream"
StackTrace:
at CSSockets.Program.Write(NetworkStream stream) in D:\data\FH\SWE1\Beispiele zu den Folien
at CSSockets.Program.Read() in D:\data\FH\SWE1\Beispiele zu den Folien\CSSockets\CSSockets\
at CSSockets.Program.Main(String[] args) in D:\data\FH\SWE1\Beispiele zu den Folien\CSSocke
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback
at System.Threading.ThreadHelper.ThreadStart()
7
Abstrakte Klassen
7.1
•
•
•
•
•
•
7.2
Abstrakte Klassen
Diese Klassen können nicht instanziiert werden
Dienen als Basisklassen
Stellen einer abgeleiteten Klasse Basisfunktionalität zur Verfügung
Im Unterschied zu Schnittstellen
Stellen auch einen Vertrag dar
Können die Implementierung von Methoden und Eigenschaften erzwingen
Beispiel abstrakte Klassen
public abstract class Pet
{
public abstract void MakeSound();
public virtual void Eat(float amount) { }
}
8
Lifecycle
8.1
Constructor
• Bringt das Objekt nach der Speicherzuweisung in definierten Grundzustand
11
OOP Basics
• Aufruf mittels new Klasse(. . . )
• hat keine Rückgabe
• heisst immer wie die Klasse in der er definiert ist
8.2
Beispiel Constructor
public class Pet {
public Pet(string name) {
this._name = name;
}
}
8.3
Destructor
• Wird in C#, Java und C++ komplett unterschiedlich gehandhabt
• Werden bei Beenden des Programmes normalerweise nicht ausgeführt
8.4
C#: Finalizer
public class Pet
{
~Pet() { /* ... */ }
}
•
•
•
•
werden in eigenem Thread ausgeführt
können nur noch eingeschränkte Operationen machen
können von der Laufzeitumgebung abgebrochen werden (zB bei zu langer Ausführung)
Besser: IDispose implementieren und using() verwenden:
using (BigObject obj = new BigObject())
{
// obj verwenden
} // obj.Dispose() wird automatisch aufgerufen
8.5
Java: finalize()
public class Pet {
protected void finalize() throws Throwable {
// ...
}
}
• werden in eigenem Thread ausgeführt
• Besser: close() implementieren und try { } finally { } verwenden:
try {
BigObject obj = new BigObject();
// obj verwenden
} finally {
obj.close();
}
12
OOP Basics
8.6
Java 8: try ()
try (BigObject obj = new BigObject()) {
// obj verwenden
} // obj.close();
8.7
C++: Destruktor
public class Pet {
~Pet() {
// ...
}
}
werden sofort bei der Deallokation ausgeführt
{
BigObject obj;
// obj verwenden
}
// automatische Ausführung des Destruktors
// bei Verlassen des Scopes
Sonst, bei Aufruf von delete
13
Herunterladen