{"id":129,"date":"2007-09-17T23:57:33","date_gmt":"2007-09-17T22:57:33","guid":{"rendered":"http:\/\/www.sahits.ch\/blog\/?p=129"},"modified":"2009-01-08T16:11:37","modified_gmt":"2009-01-08T15:11:37","slug":"mehrfachvererbung-in-java","status":"publish","type":"post","link":"https:\/\/sahits.ch\/blog\/blog\/2007\/09\/17\/mehrfachvererbung-in-java\/","title":{"rendered":"Mehrfachvererbung in Java"},"content":{"rendered":"<p>Im allgemeinen ist wahrscheinlich so, dass das Unterbinden von Mehrfachvererbung eher ein Segen als ein Fluch ist. Doch wie immer gibt es auch hier F\u00e4lle, wo dies unumg\u00e4nglich ist. Dabei m\u00fcchte ich nicht auf die Gr\u00fcnde eingehen. Es sei lediglich der Hinweis erlaubt: Es ist in jedem Fall weniger aufw\u00e4ndig, ohne Mehrfachvererbung aus zukommen. Somit ist der Aspekt ob Mehrfachvererbung tats\u00e4chlich notwendig ist zu \u00fcberpr\u00fcfen. Wie der Umstand von Single Inheritance umgangen werden kann soll hier am Beispiel der Programmiersprache Java erl\u00e4utert werden.<\/p>\n<ol type=\"a\">\n<li>Beide Klassen, die Abzuleiten sind liegen im eigenen Namensraum, d.h. beide Klassen geh\u00f6ren zum selben Projekt wie die zu erstellende Ableitung. Hier w\u00e4hlt man eine Klasse aus von der man ableitet. Von der anderen Klasse erstellt man ein Interface, das man implementiert. Dieses vorgehen legt nahe, dass man f\u00fcr das Interface die Klasse mit weniger Implementationsaufwand verwendet. Wenn m\u00f6glich sollte hier auch die erwartete API Stabilit\u00e4t einfliessen. D.h. eine Klasse deren API, oder zu einem geringeren Grad die Implementation, noch \u00e4ndern kann sollte wo m\u00f6glich nicht als Interface verwendet werden, da hier aufgrund der Anpassung der Klasse, das Interface und dann die &#8222;abgeleitete&#8220; Klasse angepasst werden muss.<\/li>\n<li>\u00c4hnlicher Fall wie oben, nur dass hier die eine Klasse ausserhalb des Projekts liegt. Liegt diese Klasse jedoch noch innerhalb des eigenen Einflussbereichs, z.B. anderes Projekt des Teams, so kann selbes vorgehen wie oben angewandt werden; andernfalls ist die externe Klasse pr\u00e4destiniert f\u00fcr ein Interface zumal hier davon ausgegangen werden kann, dass die API stabil ist.<\/li>\n<li>Beide Klassen liegen Ausserhalb des Einflussbereichs. Eine der beiden Klassen implementiert ein Interface, das die essentiellen Methoden enth\u00e4lt. In diesem Fall kann dieses Interface implementiert werden und die andere Klasse implementiert werden.<\/li>\n<li>Trifft keiner der obigen Punkte zu so muss eine komplexere L\u00f6sung gefunden werden. Komplexer ist sie weil sie mehr Aufwand bedeutet, aber auch weil sie einer echten Mehrfachvererbung am n\u00e4chsten kommt: Man w\u00e4hlt den Ansatz, dass man eine der beiden Klassen ableitet und von der anderen eine Reimplementation vornimmt. Handelt es sich hierbei um eine Klasse von Sun, so kann sie dem src.zip entnommen werden. Zum Beispiel:\n<pre>\r\npublic class ObservableThread extends Thread {\r\n    private boolean changed = false;\r\n    private Vector<observer> obs;\r\n    public ObservableThread() {\r\n\tobs = new Vector<\/observer><observer>();\r\n    }\r\n    public synchronized void addObserver(Observer o) {\r\n        if (o == null)\r\n            throw new NullPointerException();\r\n\tif (!obs.contains(o)) {\r\n\t    obs.addElement(o);\r\n\t}\r\n    }\r\n    public synchronized void deleteObserver(Observer o) {\r\n        obs.removeElement(o);\r\n    }\r\n    public void notifyObservers() {\r\n\tnotifyObservers(null);\r\n    }\r\n   public void notifyObservers(Object arg) {\r\n        Object[] arrLocal;\r\n\r\n\tsynchronized (this) {\r\n\t    if (!changed)\r\n                return;\r\n            arrLocal = obs.toArray();\r\n            clearChanged();\r\n        }\r\n\r\n        for (int i = arrLocal.length-1; i>=0; i--)\r\n            ((Observer)arrLocal[i]).update(new HiddenObservable(this), arg);\r\n    }\r\n    public synchronized void deleteObservers() {\r\n\tobs.removeAllElements();\r\n    }\r\n    protected synchronized void setChanged() {\r\n\tchanged = true;\r\n    }\r\n    protected synchronized void clearChanged() {\r\n\tchanged = false;\r\n    }\r\n    public synchronized boolean hasChanged() {\r\n\treturn changed;\r\n    }\r\n    public synchronized int countObservers() {\r\n\treturn obs.size();\r\n    }\r\n<\/observer><\/pre>\n<p>Hierbei handelt es sich jedoch noch nicht um eine echte Mehrfachvererbung. In vielen F\u00e4llen sollte dies jedoch schon gen\u00fcgen. Wo nicht kann der Mehrfachvererbung mehr Authentizit\u00e4t verliehen werden indem von der urspr\u00fcnglichen Klasse die reimplementiert wird ein Interface gebildet wird und dieses implementiert wird. Nun hat die Klasse beide Typen (Thread und Observable). Eine andere oder weitere M\u00f6glichkeit &#8211; insbesondere wenn <code>this<\/code> semantisch mit der urspr\u00fcnglichen Klasse verwendet wird  &#8211; besteht darin eine versteckte Inner Class zu bilden, die die reimplementierte Klasse ableitet und alle Methoden, die von dieser Klasse geerbt werden, \u00fcberschreibt. Die Implementation der Methoden reicht die Ausf\u00fchrung an die selbe Methode in der \u00e4usseren Klasse weiter:<\/p>\n<pre>\r\n    private class HiddenObservable extends Observable{\r\n    \t        private ObservableThread ot;\r\n     \t        public HiddenObservable(ObservableThread obersevable){\r\n    \t\t       ot = obersevable;\r\n    \t        }\r\n\t\tpublic synchronized void addObserver(Observer o) {\r\n\t\t\tot.addObserver(o);\r\n\t\t}\r\n\t\tprotected synchronized void clearChanged() {\r\n\t\t\tot.clearChanged();\r\n\t\t}\r\n\t\tpublic synchronized int countObservers() {\r\n\t\t\treturn ot.countObservers();\r\n\t\t}\r\n\t\tpublic synchronized void deleteObserver(Observer o) {\r\n\t\t\tot.deleteObserver(o);\r\n\t\t}\r\n\t\tpublic synchronized void deleteObservers() {\r\n\t\t\tot.deleteObservers();\r\n\t\t}\r\n\t\tpublic synchronized boolean hasChanged() {\r\n\t\t\treturn ot.hasChanged();\r\n\t\t}\r\n\t\tpublic void notifyObservers() {\r\n\t\t\tot.notifyObservers();\r\n\t\t}\r\n\t\tpublic void notifyObservers(Object arg) {\r\n\t\t\tot.notifyObservers(arg);\r\n\t\t}\r\n\t\tprotected synchronized void setChanged() {\r\n\t\t\tot.setChanged();\r\n\t\t}\r\n    }\r\n<\/pre>\n<p>Zu beachten: Dies ist n\u00f6tig, da im ersten Code-Teil (bereits angepasst) ein Aufruf mit <code>this<\/code> gemacht wird und <code>this<\/code> nun mal vom Typ Observable und nicht vom Typ Thread oder ObservableThread ist.<br \/>\nEinziger Nachteil dieser L\u00f6sung: <code>instanceof Observable<\/code> wird immer false zur\u00fcckgeben. Solange diese Abfrage jedoch im eigenen Code ist, spielt dies keine weitere Rolle.\n<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Im allgemeinen ist wahrscheinlich so, dass das Unterbinden von Mehrfachvererbung eher ein Segen als ein Fluch ist. Doch wie immer gibt es auch hier F\u00e4lle, wo dies unumg\u00e4nglich ist. Dabei m\u00fcchte ich nicht auf die Gr\u00fcnde eingehen. Es sei lediglich der Hinweis erlaubt: Es ist in jedem Fall weniger aufw\u00e4ndig, ohne Mehrfachvererbung aus zukommen. Somit &hellip; <a href=\"https:\/\/sahits.ch\/blog\/blog\/2007\/09\/17\/mehrfachvererbung-in-java\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eMehrfachvererbung in Java\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,6],"tags":[99,301,300,25,22],"class_list":["post-129","post","type-post","status-publish","format-standard","hentry","category-java","category-programmieren","tag-de","tag-java","tag-programmieren","tag-tutorial","tag-vererbung"],"_links":{"self":[{"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/comments?post=129"}],"version-history":[{"count":5,"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/129\/revisions"}],"predecessor-version":[{"id":450,"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/129\/revisions\/450"}],"wp:attachment":[{"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/media?parent=129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/categories?post=129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/tags?post=129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}