Was ist objektorientierte Programmierung?
Objektorientierte Programmierung ist die Programmierung mit Laufzeitpolymorphie, bei der die Implementation aller Verben eines Typs an einer Stelle¹ zusammengefaßt wird. (¹ oder jedenfalls an wenigen verschiedenen Stellen)
Der Adressatenkreis dieses Textes
Der Sinn der objektorientierten Programmierung kann sich erst einem Programmierer erschließen, der schon Erfahrungen mit Situationen gemacht hat, in denen es wünschenswert ist, Laufzeittypen für Daten festzulegen und zu nutzen, und der schon Erfahrungen mit der Notwendigkeit zur Organisation von Code in Programmen, die viele Funktionen und Typen enthalten, gemacht hat.
Trotzdem soll hier ein Versuch unternommen werden, die Bedeutung der objektorientierten Programmierung so zu schildern, daß sie mit möglichst wenig Voraussetzungen verständlich wird.
Da diese FAQ-Antwort im Rahmen eines Java -Kurses geschrieben wurde, verwendet sie Java zur Erklärung.
Typverzweigungen (nicht objektorientiert, sondern prozedural)
Um eine Ausgangsbasis zu haben, mit der die objektorientierte Programierung verglichen werden kann, zeigen wir in diesem Abschnitt zunächst ein Programm, das im wesentlichen nicht objektorientiert, sondern prozedural aufgebaut ist.
Wir nehmen an, daß wir eine Sprache (wie Deutsch oder Englisch) durch eine Klasse repräsentieren und wir dann einen Hörer begrüßen wollen, dessen Sprache erst während der Ausführung des Programms bekannt wird.
Main.java
interface Language { }
final class German implements Language { }
final class English implements Language { }
final class LanguageUtils
{
public static java.lang.String morgengruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Morgen!":
hoerer instanceof English? "Good morning!":
null; }public static java.lang.String nachmittagsgruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Tag!":
hoerer instanceof English? "Good afternoon!":
null; }public static java.lang.String abendgruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Abend!":
hoerer instanceof English? "Good evening!":
null; }}public final class Main
{public static void main( final java.lang.String[] args )
{final Language hoerer = java.lang.Math.random() > 0.5 ?
new German() : new English();java.lang.System.out.println( LanguageUtils.morgengruss( hoerer )); }}
- Protokoll
Guten Morgen!
Das Hinzufügen von Verben (Methoden)
Das Hinzufügen eines weiteren Verbs (einer weiteren Methode) erscheint als relativ einfach. Dies liegt daran, daß die Definition des Verbs für alle Typen sich an einer einzigen Stelle des Programms findet.
Main.java
interface Language { }
final class German implements Language { }
final class English implements Language { }
final class LanguageUtils
{
public static java.lang.String morgengruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Morgen!":
hoerer instanceof English? "Good morning!":
null; }public static java.lang.String nachmittagsgruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Tag!":
hoerer instanceof English? "Good afternoon!":
null; }public static java.lang.String abendgruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Abend!":
hoerer instanceof English? "Good evening!":
null; }public static java.lang.String abschied( final Language hoerer )
{ return
hoerer instanceof German? "Auf Wiedersehen!":
hoerer instanceof English? "Goodbye!":
null; }}public final class Main
{public static void main( final java.lang.String[] args )
{final Language hoerer = java.lang.Math.random() > 0.5 ?
new German() : new English();java.lang.System.out.println( LanguageUtils.abschied( hoerer )); }}
- Protokoll
Auf Wiedersehen!
Das Hinzufügen von Typen
Das Hinzufügen einer weiteren Typs ist schwierig, da viele verschiedene Methoden geändert werden müssen, die in der Praxis nicht immer alle so schön an einer Stelle versammelt sind, wie in unserem Beispiel!
Main.java
interface Language { }
final class German implements Language { }
final class English implements Language { }
final class French implements Language { }
final class LanguageUtils
{
public static java.lang.String morgengruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Morgen!":
hoerer instanceof English? "Good morning!":
hoerer instanceof French? "Bonjour !":
null; }public static java.lang.String nachmittagsgruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Tag!":
hoerer instanceof English? "Good afternoon!":
hoerer instanceof French? "Bonjour !":
null; }public static java.lang.String abendgruss( final Language hoerer )
{ return
hoerer instanceof German? "Guten Abend!":
hoerer instanceof English? "Good evening!":
hoerer instanceof French? "Bonsoir !":
null; }}public final class Main
{public static void main( final java.lang.String[] args )
{final Language hoerer =
java.lang.Math.random() > 0.66666? new French():
java.lang.Math.random() > 0.50000? new German():
new English();java.lang.System.out.println( LanguageUtils.morgengruss( hoerer )); }}
- Protokoll
Bonjour !
Polymorphie (objektorientiert)
Man gelangt von der prozeduralen Programmierung zur objektorientierten Programmierung, wenn man Typverzweigungen durch Polymorphie ersetzt.
Main.java
interface Language
{ public java.lang.String morgengruss();
public java.lang.String nachmittagsgruss();
public java.lang.String abendgruss(); }final class German implements Language
{
public java.lang.String morgengruss()
{ return "Guten Morgen!"; }public java.lang.String nachmittagsgruss()
{ return "Guten Tag!"; }public java.lang.String abendgruss()
{ return "Guten Abend!"; }}
final class English implements Language
{
public java.lang.String morgengruss()
{ return "Good morning!"; }public java.lang.String nachmittagsgruss()
{ return "Good afternoon!"; }public java.lang.String abendgruss()
{ return "Good evening!"; }}
public final class Main
{public static void main( final java.lang.String[] args )
{final Language hoerer = java.lang.Math.random() > 0.5 ?
new German() : new English();java.lang.System.out.println( hoerer.morgengruss() ); }}
- Protokoll
Guten Morgen!
Der Aufruf »hoerer.morgengruss()« wählt die für den jeweiligen Hörertyp richtige Methode »morgengruss« zur Laufzeit aus, ohne daß im Programm ein Verzweigung dafür programmiert werden muß. Das ist Laufzeitpolymorphie.
Das Hinzufügen von Typen
Das Hinzufügen eines weiteren Typs erscheint nun als relativ einfach. Dies liegt daran, daß die Implementationen aller Verben eines Typs an einer Stelle versammelt sind.
Main.java
interface Language
{ public java.lang.String morgengruss();
public java.lang.String nachmittagsgruss();
public java.lang.String abendgruss(); }final class German implements Language
{
public java.lang.String morgengruss()
{ return "Guten Morgen!"; }public java.lang.String nachmittagsgruss()
{ return "Guten Tag!"; }public java.lang.String abendgruss()
{ return "Guten Abend!"; }}final class English implements Language
{
public java.lang.String morgengruss()
{ return "Good morning!"; }public java.lang.String nachmittagsgruss()
{ return "Good afternoon!"; }public java.lang.String abendgruss()
{ return "Good evening!"; }}final class French implements Language
{
public java.lang.String morgengruss()
{ return "Bonjour !"; }public java.lang.String nachmittagsgruss()
{ return "Bonjour !"; }public java.lang.String abendgruss()
{ return "Bonsoir !"; }}public final class Main
{public static void main( final java.lang.String[] args )
{final Language hoerer =
java.lang.Math.random() > 0.66666? new French():
java.lang.Math.random() > 0.50000? new German():
new English();java.lang.System.out.println( hoerer.morgengruss() ); }}
- Protokoll
Bonjour !
Das Hinzufügen von Verben (Methoden)
Das Hinzufügen einer weiteren Verbs ist nun schwierig, da viele verschiedene Typen geändert werden müssen, die in der Praxis nicht immer alle so schön an einer Stelle versammelt sind, wie in unserem Beispiel!
Main.java
interface Language
{ public java.lang.String morgengruss();
public java.lang.String nachmittagsgruss();
public java.lang.String abendgruss();
public java.lang.String abschied(); }final class German implements Language
{
public java.lang.String morgengruss()
{ return "Guten Morgen!"; }public java.lang.String nachmittagsgruss()
{ return "Guten Tag!"; }public java.lang.String abendgruss()
{ return "Guten Abend!"; }public java.lang.String abschied()
{ return "Auf Wiedersehen!"; }}final class English implements Language
{
public java.lang.String morgengruss()
{ return "Good morning!"; }public java.lang.String nachmittagsgruss()
{ return "Good afternoon!"; }public java.lang.String abendgruss()
{ return "Good evening!"; }public java.lang.String abschied()
{ return "Goodbye!"; }}public final class Main
{public static void main( final java.lang.String[] args )
{final Language hoerer = java.lang.Math.random() > 0.5 ?
new German() : new English();java.lang.System.out.println( hoerer.abschied() ); }}
- Protokoll
Goodbye!
Zusammenfassung
Man gelangt von der prozeduralen Programmierung zur objektorientierten Programmierung, wenn man Typverzweigungen durch Polymorphie ersetzt.
Bei prozeduraler Programmierung ist das Hinzufügen von Verben einfach und das Hinzufügen von Typen schwer.
Bei objektorientierter Programmierung ist das Hinzufügen von Typen einfach und das Hinzufügen von Verben schwer.