Ankündigung

Einklappen
Keine Ankündigung bisher.

Static return type bei Klassen

Einklappen

Neue Werbung 2019

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

  • Static return type bei Klassen

    Hallo Zusammen

    Bin echt verunsichert beim Static return type.

    Eigentlich kann man da ja $this, new static() oder new self() returnieren laut PHP RFC:
    https://wiki.php.net/rfc/static_return_type

    Gibt es denn nicht einen return type welches unterscheidet ob man $this oder eine neue Instance new static()
    returnieren muss?



    Denn wenn ich z.B die Laravel Collection Klasse anschaue, wird $this oder static dokumentiert.
    Jedoch mit PHP 8 könnte man den ja static als return type definieren.
    Jedoch wüsste man dann ja nicht ob eine neue Instance zurückgegeben wird oder das selbe Objekt ausser mann schaut die @return Doku.
    Oder sehe ich das falsch?

    PHP-Code:
        /**
         * Flip the items in the collection.
         *
         * @return static
         */
        
    public function flip()
        {
            return new static(
    array_flip($this->items));
        }

        
    /**
         * Remove an item from the collection by key.
         *
         * @param  string|array  $keys
         * @return $this
         */
        
    public function forget($keys)
        {
            foreach ((array) 
    $keys as $key) {
                
    $this->offsetUnset($key);
            }

            return 
    $this;
        } 

  • #2
    Der Return-Type bestimmt nur, welchen Type der Wert haben muss, nicht um welchen Wert es sich handelt.

    Der Type von $this und new static() ist der selbe.

    Kommentar


    • #3
      Ok danke Dir für den Hinweis hellbringer.

      Doch wenn ein Interface implementiert ist könnte mann auch dieses als return type angeben anstatt static. Oder was macht mehr Sinn?. Ist denn da ein Vorteil oder Nachteil?

      PHP-Code:
      class Foo implements FooInterface
      {
          
      /**
           * @var null|string
           */
          
      protected ?string $name null;

          
      /**
           * Set name
           *
           * @param string
           * @return FooInterface
           */    
          
      public function setName(string $name): FooInterface
          
      {
              
      $this->name $name
              
      return $this;
          }

      Kommentar


      • #4
        Das hängt davon ab, was die Methode tut. Gibt die Methode immer eine Instanz von Foo zurück? Oder auch andere Instanzen, die FooInterface implementiert haben?

        Kommentar


        • #5
          Könnte man den nicht auch self oder static als return type definieren? Echt verwirrend das Ganze. Denn ich hatte Probleme wo ich ein anderes Interface implementieren wollte und die eine Klasse die andere extended.

          Beispiel :
          PHP-Code:
          interface FooInterface
          {
              public function 
          setName(string $name): FooInterface;
          }

          interface 
          BarInterface
          {
              public function 
          setName(string $name): BarInterface;
          }

          class 
          Foo implements FooInterface
          {
              
          /**
               * @var null|string
               */
              
          protected ?string $name null;

              
          /**
               * Set name
               *
               * @param string
               * @return FooInterface
               */    
              
          public function setName(string $name): FooInterface
              
          {
                  
          $this->name $name;
                  return 
          $this;
              }
          }

          // throws:
          // Declaration of Foo::setName(string $name): FooInterface must be compatible with BarInterface::setName(string $name): BarInterface
          class Bar extends Foo implements BarInterface
          {
              
          //

          Dannach musste ich die Interfaces to self anpassen:

          PHP-Code:
          interface FooInterface
          {
              public function 
          setName(string $name): self;
          }

          interface 
          BarInterface
          {
              public function 
          setName(string $name): self;

          Wäs wäre denn wenn ich static als return type nehme? Hier würde es doch keinen Unterschied geben? Oder sehe ich das falsch?

          Kommentar


          • #6
            Was meinst du mit "static als return type"?

            Kommentar


            • #7
              Typehint
              PHP-Code:
              public function setName(string &name): static; 

              Kommentar


              • #8
                Zitat von strub Beitrag anzeigen
                Typehint
                PHP-Code:
                public function setName(string &name): static; 
                Also da schmeißt PHP bei mir einen Fehler.

                Kommentar


                • #9
                  Erst ab php8 siehe oben Link im ersten Post

                  Kommentar


                  • #10
                    Ausserdem wurde mir erst jetzt klar, dass wenn ich self aus return type hint definiere, muss man in der Extended Klasse die Methode auch definieren ansonsten bekommt man einen Error:
                    PHP-Code:
                    interface FooInterface
                    {
                        public function 
                    setName(string $name): self;
                    }

                    interface 
                    BarInterface
                    {
                        public function 
                    setName(string $name): self;
                    }

                    class 
                    Foo implements FooInterface
                    {
                        
                    /**
                         * @var null|string
                         */
                        
                    protected ?string $name null;

                        
                    /**
                         * Set name
                         *
                         * @param string
                         * @return FooInterface
                         */    
                        
                    public function setName(string $name): self
                        
                    {
                            
                    $this->name $name;
                            return 
                    $this;
                        }
                    }

                    class 
                    Bar extends Foo implements BarInterface
                    {

                    }

                    // throws:
                    // Declaration of Foo::setName(string $name): Foo must be compatible with BarInterface::setName(string $name): BarInterface 

                    So klappt es:
                    PHP-Code:
                    class Bar extends Foo implements BarInterface
                    {
                        
                    /**
                         * Set name
                         *
                         * @param string
                         * @return FooInterface
                         */    
                        
                    public function setName(string $name): self
                        
                    {
                            
                    $this->name $name;
                            return 
                    $this;
                        }


                    Somit ist static eben besser, wenn man davon ausgeht später die Klasse abzuleiten (extend).

                    Kommentar

                    Lädt...
                    X