Genau so lese ich aber deinen Einwand. (Liskov? Hm vielleicht mal gehört, aber ich habe nun mal nicht theoretische Informatik studiert. Auch was du unter "Zusicherung" verstehst ist mir nicht bekannt - die Prinzipien dürften mir schon bekannt sein, aber nicht unter den Namen)
Zu Liskov (
http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/lsp-liskov-substitutionsprinzip):
„Wenn es für jedes Objekt u vom Typ U ein Objekt o vom Typ O gibt, so daß für alle Programme p, die in Operationen des O definiert wurden, das Verhalten von p unverändert bleibt, wenn o durch u ersetzt wird, dann ist der Typ U ein Untertyp des Typs O.“
Salopp ausgedrückt heisst das, überall dort wo du einen Basistyp verwendest solltest du auch einen seiner Subtypen verwenden können ohne das Verhalten des Programmes zu ändern. Das bekommt man in OO Sprachen wie Java über Vererbung und Polymorphie faktisch geschenkt.
Und jetzt kommt das ABER, durch den obigen Satz lassen sich noch mehr Dinge fordern in Bezug auf die Korrektheit von Programmen. Das geht z.B. von der Frage aus, was passiert wenn Subtypen Methoden überschreiben oder re-implementieren. Also muss man irgendwas im Supertyp festlegen was die Subtypen einhalten müssen.
Im Allgemeinen heissen die Dinger dann Vor-/Nachbedingungen und Invarianten (Klasseninvariante, Schleifeninvariante). Vor- und Nachbedingungen sind einfach gesagt Bedingungen die erfüllt sein müssen bevor ein Stück Code läuft und Bedingungen die erfüllt sein müssen nachdem ein Stück Code gelaufen ist und Invarianten sind Dinge die immer erfüllt sein müssen (aber kurzfristig verletzt werden können innerhalb einer Methode z.B.). Als "rudimentäres" Beispiel in Java können als Vorbedingungen z.B. assert x!= null verstanden werden oder das sich ein integer-Argument innerhalb eines bestimmten Bereichs befindet. Als Nachbedingung z.B. dass wenn du y= x*x rechnest die Nachbedingung x = sqrt(y) ist.
Diese ganze Sammlung von Konsistenzbedingungen wird dann z.B. im DbC als "Contract" bezeichnet. Für diese Bedingungen gibt es dann weitere Regeln, eine davon ist wie ich schon erwähnte, das Vorbedingungen höchstens aufgeweicht aber nicht verschärft werden dürfen. Bei Klasseninvarianten ist es ähnlich, stell dir vor du legst im Basistyp ein Attribut an welches nur Ganzzahlen in einem bestimmten Bereich erlaubt. In einem Subtyp darfst du den Bereich höchstens weiter einschränken aber nicht erweitern.
Einfacher kann ich es nicht beschreiben, man kann das ganze dann auch noch recht theoretisch angehaucht auswalzen...
EDIT: Die ganzen Diskussionen über das Substitutionsprinzip etc. führen natürlich auch zu Auseinandersetzungen was denn nun "richtig" sei und wann man wie etwas verletzen darf. Umgangsprachlich wird ein Subtyp der das LSP komplett erfüllt als "wahrer" oder echter Subtyp bezeichnet also das was die "ist-ein" Beziehung ausmacht. Den Rest bezeichne ich gerne als "is-like-a", sprich "ist-wie-ein" (d.h. ähnlich aber nicht 100%). Wenn man übrigens die "Client-"Schnittstelle (sehr einfach ausgedrückt also die "public"-Methoden) des Subtyps um Methoden erweitert ist es schon kein "wahrer" Subtyp mehr, das LSP ist da ein wenig streng.