
Die Klasse "Artikel" dient im Beispiel vornehmlich der Modellierung und Strukturierung des entstehenden Systems. Es sollen
aber keine konkreten Instanzen davon erzeugt werden. Es soll nur möglich sein, die verschiedenen Arten von Artikeln
auf eine konsistente Art und Weise zu verwenden.
Die Klasse "Artikel" wird auch abstrakte Klasse genannt. Damit wird explizit ausgedrückt, dass keine Instanzen dieser Klasse erzeugt werden dürfen. Spezifische Details werden in den abgeleiteten Unterklassen implementiert.
In der UML werden abstrakte Klassen mit dem Wort abstract in geschweiften Klammern gekennzeichnet. Alternativ
kann der Klassenname kursiv gesetzt werden.

Für die Implementierung abstrakter Klassen in Java verwendet man das Schlüsselwort abstract. Sobald
eine Klasse als abstract gekennzeichnet wurde, dürfen keine Instanzen von ihr erzeugt werden. Ansonsten sind sie
aber wie normale Klassen aufgebaut: Sie können Attribute definieren und ihnen Werte zuweisen sowie Methoden definieren
und implementieren. Abgeleitete Klassen erben diese Attribute und Methoden wie gehabt. Versucht man, Instanzen dieser Klasse
zu erzeugen, meldet der Compiler einen Fehler.

Es können aber nicht nur Klassen, sondern auch Methoden einer Klasse als abstract gekennzeichnet werden. Eine
abstrakte Methode hat eine Signatur, aber keine Implementierung. So wie es von abstrakten Klassen kein konkreten
Instanzen geben darf, dürfen abstrakte Methoden keine Methodenrümpfe definieren. Das hat zur Folge, dass eine
Klasse mit einer oder mehreren abstrakten Methode nicht vollständig ist. Definiert deshalb eine Klasse mindestens
eine abstrakte Methode, so muss sie in der Klassendeklaration ebenfalls als abstract gekennzeichnet werden. Die abstrakte
Methode muss dann in allen Unterklassen durch Überschreiben implementiert werden.

In einer Unterklasse muss diese Methode nun implementiert werden, das funktioniert genauso wie das Überschreiben
einer geerbten Methode.

Das Implementieren einer geerbten abstrakten Methode in einer Unterklasse wird vom Compiler erzwungen. Die einzige Möglichkeit, eine abstrakte Methode nicht in einer direkten Unterklasse zu implementieren ist, sie dort wieder als abstract zu kennzeichnen. Das hat allerdings zur Folge, dass diese Unterklasse zu einer abstrakten Klasse wird und so die Verantwortung der Implementierung an weitere Unterklassen delegiert wird.
Es is möglich, Variablen vom Typ einer abstrakten Klasse zu deklarieren. Da aber keine Objekte von dieser
abstrakten Klasse erzeugt werden können, muss der zugewiesene Wert der so deklarierten Variable zwingend ein
Objekt einer abgeleiteten Klasse sein.

Polymorphie bedeutet Vielgestalt. Sie bezeichnet in objektorientierten Systemen die Tatsache, dass eine Variable, die
vom Typ einer bestimmten Klasse deklariert ist, auch Instanzen der Unterklassen annehmen kann. Eine Variable kann sich
also in einer Vielzahl an konkreten Gestalten zeigen. Die folgende Abbildung zeigt anhand der Vererbungsbeziehungen, dass
sich hinter einer Variablen der Klasse "Artikel" auch Instanzen von "Buch", "Musikartikel", "Spiel" und "Film" verbergen
können.

Die einzelnen Unterklassen können Methoden überschreiben, um so das Verhalten zu spezialisieren. Im Beispielsystem wird von Artikeln im Allgemeinen gesprochen und ganz bestimmte Anforderungen - wie beispielsweise die Ausgabe eines Beschreibungstextes - an sie gestellt. Die Umsetzung dieser Anforderung unterscheidet sich aber von Unterklasse zu Unterklasse. Polymorphie erlaubt es, alle Instanzen der Unterklassen als Artikel zu behandeln und trotzdem auf die jeweilige spezielle Implementierung der Methoden zuzugreifen.
So wie der Typ einer Variable darüber entscheidet, welche Methoden aufgerufen werden können, entscheidet die
Instanz einer Klasse, weche Implementierung dieser Methoden ausgeführt wird.

Das Konzept der Polymorphie ermöglicht es, Methoden von Objekten aufzurufen, ohne wissen zu müssen, zu welcher konkreten Unterklasse diese Objekte gehören. Es zählt, dass die Objekte die Funktionalität implementieren, die man benötigt.
Möglich ist aber auch, zur Laufzeit zu überprüfen, zu welcher Klasse eine Instanz gehört. Mit dem instanceof-Operator kann ein Test auf Klassenzugehörigkeit durchgeführt werden. Dadurch werden allerdings die Vorteile der Polymorphie aufgehoben. Man testet nun auf eine ganz spezifische Klassenzugehörigkeit und kann nicht mehr mit beliebigen Unterklassen-Instanzen arbeiten.
Im folgenden Beispiel wird der instanceof-Operator verwendet, um das übergebene Objekt auf die Zugehörigkeit zur
Klasse "Buch" zu testen. Ist dies der Fall, so können spezielle Vorbereitungen für das Verarbeiten eines
Buch-Objektes getroffen werden. Es lohnt sich aber, darüber nachzudenken, ob diese Vorbereitungen auch vom
Buch-Objekt selber getroffen werden können, um die Abfrage nach der konkreten Klasse zu vermeiden.

Klassenvariablen werden auch statische Attribute genannt, da sie nicht an ein Objekt gebunden sind, sondern bereits
ab der Existenz einer Klasse verfügbar sind. Statische Attribute gelten dabei für alle Instanzen einer Klasse.
Ihr Wert ist für alle Instanzen der Klasse derselbe. Deklariert werden Klassenvariablen über das
Schlüsselwort static. Man kann dann im Folgenden über die Klasse auf dieses Attribut zugreifen und
muss vorher kein Objekt erzeugen.

Ändert man den Wert des statischen Attributs, so ändert er sich für alle Objekte der Klasse und der Unterklassen.
Neben Attrbiuten können auch Methoden als static deklariert werden. Diese Methoden sind ebenfalls
unabhängig von der Existenz eines konkreten Objekts und werden über die Klasse aufgerufen.

Da statische Methoden auch ohne die Existenz von Objekten der jeweiligen Klasse aufgerufen werden können, darf im Methodenrumpf nicht auf Instanzmethoden oder -variablen zugegriffen werden.
Statische Attribute findet man in der Java-Klassenbibliothek häufig bei der Definition von Konstanten. So sind zum Beispiel die Kreiszahl pi und die Eulersche Zahl e als statische Attribute der Klasse "Math" definiert.
Beispiele für statische Methoden findet man ebenfalls in der Klasse "Math". Die Ergebnisse der Methoden sin, cos, log sind berechenbar, ohne dass auf den internen Zustand eines Objektes zugegriffen werden muss. Vor der Verwendung dieser Methoden muss also keine Instanz von "Math" erzeugt werden.