Ankündigung

Einklappen
Keine Ankündigung bisher.

Funktionen in vererbter Klasse deaktivieren

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Funktionen in vererbter Klasse deaktivieren

    Hallo,

    ich habe eine Klasse A mit den Funktionen F1, F2, F3.

    Jetzt erstelle ich die Klasse B und erbe von der Klasse A. In der Klasse B soll aber nur der Zugriff auf Methode F1 möglich sein, nicht auf F2 und F3.

    Kann ich das mit PHP umsetzen?


  • #2
    HM, was sllte dsa bringen?

    Möglichkeiten:

    Methode F1 als private oder public deklarieren
    F2 und F3 als protected (dann werden sie nicht weitervererbt)

    Kommentar


    • #3
      F2 und F3 als protected (dann werden sie nicht weitervererbt)
      Stimmt nicht. protected wird vererbt.
      Methode F1 als private oder public deklarieren
      Das bringt nichts. Nachträglich auf private setzen verletzt die Schnittstelle und ist syntaktisch verboten.

      Ein Möglichkeit wäre, Die Methoden mit Dummys zu überschreiben (leere Funktionalität) oder mit Methoden, die bspw. eine Exception werfen.
      --

      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
      Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


      --

      Kommentar


      • #4
        Zitat von ragtek Beitrag anzeigen
        Methode F1 als private oder public deklarieren
        F2 und F3 als protected (dann werden sie nicht weitervererbt)
        Du verwechselst protected mit private und vice versa.

        Geschützte (protected) Funktionen werden mit vererbt, sind aber auch dort nur innerhalb der Klasse verfügbar.
        Private Methoden werden nicht vererbt und sind ebenfalls nur innerhalb der Klasse verfügbar.

        Vom Design her wäre es schlauer, eine abstrakte Klasse zu definieren die die Schnittmengen zwischen beiden anderen Klassen darstellt, und diese dann zu erweitern.

        EDIT: nikosch war schneller..

        LG:
        jw-lighting

        Kommentar


        • #5
          Ups sorry.

          Aber wieso verletze ich die Schnittstelle?
          Vlt ist es ja nicht beabsichtigt, dass die 2 von aussen aufgerufen werden sollen.

          Persönlich finde ich das nachträgliche überschreiben viel grausamer.
          Wenn sie nicht verfügbar sein soll, dann soll die Elternklasse dafür sorgen.
          Wozu soll eine Methode in einer Kindsklasse verfügbar sein, wenn diese nicht aufrufbar sein darf.

          Das einzige Szenario wo ich mir sowas vorstellen könnte, wäre eine API wo etwas gravierendes geändert wurde und man nun bitte Methode / Klasse xyz verwenden soll.
          Das ist halt meine Sichtiweise.

          Kommentar


          • #6
            Wenn du ein Haustier haben willst, das zwei Beine und zwei Flügel hat - dann solltest du es nicht von zwei Säugetieren zeugen lassen.

            Wenn deine Kindklasse etwas bestimmtes nicht können/dürfen soll - wieso soll sie dann bitte überhaupt von einer Elternklasse erben, die diese Fähigkeiten hat?

            „Säugetier“ und „Vogel“ leiten sich beide von „Lebewesen“ ab.
            Du willst aber offenbar „Vogel“ von „Säugetier“ ableiten.

            Kommentar


            • #7
              Was Chris damit meint wäre

              Klasse A mit F1
              Klasse B erbt von A und definiert F2, F3
              Klasse C erbt von A und definiert F4

              Kommentar


              • #8
                Zitat von ChrisB
                „Säugetier“ und „Vogel“ leiten sich beide von „Lebewesen“ ab. Du willst aber offenbar „Vogel“ von „Säugetier“ ableiten.
                Ich nehme an, du (TE) hast das bisher nicht gemacht/machen wollen da du für 'Lebewesen' keine eigene Verwendung hast.

                Vom Design her wäre es schlauer, eine abstrakte Klasse zu definieren die die Schnittmengen zwischen beiden anderen Klassen darstellt, und diese dann zu erweitern.
                Um das Problem zu lösen gibt es, wie ich angesprochen hatte, die Möglichkeit eine Klasse (oder auch Methoden) als abstrakt zu definieren, d.h. das sie eine Grundlage darstellt die von Kindklassen erweitert werden MUSS, und so noch nicht instanziert werden darf.

                PHP-Code:
                abstract class Foo{

                   function 
                foo(){
                      
                // ...
                   
                }
                }

                class 
                Bar extends Foo{

                   function 
                Bar(){
                      
                // ...
                   
                }
                }

                class 
                Baz extends Foo{

                   function 
                baz(){
                      
                // ...
                   
                }

                LG

                Kommentar


                • #9
                  ich dachte an sowas wie sealed in c#, aber das verhindert auch nur weiteres überschreiben.

                  über Klasse A sitzt noch eine abstrakte Klasse und ein Interface mit jeder Menge Logik. Es sind bereits alle Methoden F1, F2, F3 im Interface defniert. Dann müsste man die Struktur doppelt anlegen und die ganze Logik davon auslagern (automatisches Suchen von Klassenpfaden, viel statisches).

                  Ich werde dann wohl doch auf die unschönere Methoder gehen und leer überschreiben.

                  Kommentar


                  • #10
                    Aber wieso verletze ich die Schnittstelle?
                    Weil eine einmal publizierte Methode nicht nachträglich eingeschränkt werden darf. Wenn A::foo() public ist und B:foo() private (B extends A), dann beendet B effektiv den weiteren Vererbungsbaum. Allgemeiner gefasst stellte dann jede Vererbung einer Vererbung eine potentielle Entwertung des Objekts dar. Stell Dir nur mal vor, Du gibst als Type-Hint A an, dann kannst Du B zwar übergeben, aber effektiv kann der Kontext trotzdem nicht sicher sein, dass die Schnittstelle noch konsistent ist, weil es eben B:foo() gar nicht mehr aufrufen könnte. Noch klarer wird das bei der Verwendung von Interfaces. Wenn A ein Interface mit foo() bedient, würde B (das ja die Implementierung erbt) nicht mehr das Interface repräsentieren (bzw. anders herum).

                    Vlt ist es ja nicht beabsichtigt, dass die 2 von aussen aufgerufen werden sollen.
                    Dann sollte man eben auch nur F1 als Schnittstelle definieren und den Rest entweder protected anlegen oder nur eine Ableitung zwischenschieben.

                    Persönlich finde ich das nachträgliche überschreiben viel grausamer.
                    Wenn sie nicht verfügbar sein soll, dann soll die Elternklasse dafür sorgen.
                    Nein das ist falsch. Die Elternklasse weiß ja nicht, dass sie Elternklasse ist. Ergo auch nichts über die Kinder, erst recht nicht über implementierte Funktionalitäten. Im Übrigen kann es durchaus sinnvolle Anwendungen für Methoden geben. Nimm das Beispiel „Automat wechselt nicht“. Briefmarkenautomat extends Selbstbedienungsautomat. gebeWechselgeld() ist dann eben eine Dummymethode, die aber trotzdem das Interface bedient, auf das vielleicht ein Objekt Automatentastatur oder Automatenprozessor aufsetzt.
                    --

                    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                    --

                    Kommentar


                    • #11
                      r2ls: Kannst DU das nicht konkreter machen? Dann könnte man auch vernünftig antworten. Für mich klingt die Frage, als wäre die http://de.wikipedia.org/wiki/Schablonenmethode vielleicht das Mittel der Wahl. Evtl. ist dafür aber bereits eine Entkernung des bestehenden Codes notwendig.
                      --

                      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                      Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                      --

                      Kommentar


                      • #12
                        Zitat von r2ls Beitrag anzeigen
                        ich dachte an sowas wie sealed in c#, aber das verhindert auch nur weiteres überschreiben.

                        über Klasse A sitzt noch eine abstrakte Klasse und ein Interface mit jeder Menge Logik. Es sind bereits alle Methoden F1, F2, F3 im Interface defniert. Dann müsste man die Struktur doppelt anlegen und die ganze Logik davon auslagern (automatisches Suchen von Klassenpfaden, viel statisches).

                        Ich werde dann wohl doch auf die unschönere Methoder gehen und leer überschreiben.
                        Dann ist aber doch dein Interface schon "falsch" oder ?

                        Wenn ein Interface sagt ich brauche methode A, B und C, dann sollten die klassen die es implementieren das auch haben.

                        Wie wäre es mit mehr als einem Interface ?

                        Eine Klasse kann ja mehr als 1 interface implementieren.
                        Dann mach 3 interfaces daraus, implementier die die du brauchst in deinen klassen.

                        Übrigends können auch Interfaces voneinander erben.
                        robo47.net - Blog, Codeschnipsel und mehr
                        | Caching-Klassen und Opcode Caches in php | Robo47 Components - PHP Library extending Zend Framework

                        Kommentar


                        • #13
                          ok, ich habe das wohl falsch aufgefasst.

                          Kommentar

                          Lädt...
                          X