rfc:nested_classes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:nested_classes [2013/10/01 23:12] – [Syntax Example] krakjoerfc:nested_classes [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 4: Line 4:
   * Date: 2013-09-29   * Date: 2013-09-29
   * Author: Joe Watkins, krakjoe@php.net   * Author: Joe Watkins, krakjoe@php.net
-  * Status: Under Discussion+  * Status: Withdrawn
   * First Published at: http://wiki.php.net/rfc/nested_classes   * First Published at: http://wiki.php.net/rfc/nested_classes
  
Line 41: Line 41:
   * public - the class is accessible everywhere   * public - the class is accessible everywhere
   * private - the class may be accessed by any class declared in the //outer// class   * private - the class may be accessed by any class declared in the //outer// class
-  * protected - the class may be accessed by any class up to and including the //outermost// class+  * protected - the class may be access by any class in the same virtual namespace
  
-INSERT DIAGRAMS HERE+===== Private Classes =====
  
-===== Syntax Example =====+The following example shows how to blackbox some of your functionality in a private nested class:
  
-The following is a syntax example and use case example; the primary use case for nested classes is black boxing: a nested class, interface, abstract etc should declare or contain functionality that is required for it's outer class to function, and support it'(public) API, but it should not always be exposed to the public.+<code php> 
 +<?php 
 +/* 
 +* \foo 
 +* @package \foo 
 +*/ 
 +class foo  
 +
 +    /* 
 +    * \foo\bar supporting class for foo 
 +    * @subpackage \foo\bar 
 +    * @private 
 +    */ 
 +    private class bar 
 +    { 
 +        public function __construct() 
 +            /* ... */ 
 +        } 
 +    } 
 +     
 +    /* PUBLIC API METHODS HERE */ 
 +     
 +    public function __construct()  
 +    { 
 +        $this->bar = new \foo\bar(); 
 +    } 
 +}
  
-In the following example''io\FileReader'' is a public API, the only public facing API method is ''::getFileType'', the remainder of the functionality is declared as a blackboxonly accessible where it must be accessible in order for ''io\FileReader'' to support public functionality.+var_dump(new \foo()); 
 +?> 
 +</code> 
 + 
 +In the example ''\foo'' is the public facing API''\foo\bar'' contains supporting logic never to be exposed outside of ''\foo''any class declared in the virtual namespace ''\foo'' will be able to access the ''\foo\bar'' class. 
 + 
 +Attempting:
  
 <code php> <code php>
-<?php +var_dump(new \foo\bar()); 
-namespace io {+</code>
  
-    class FileReader +will result in 
-        protected interface IOBuffer {}+ 
 +<code> 
 +Fatal error: Cannot access private class foo\bar from an unknown scope in %s on line %d 
 +</code> 
 + 
 +Private classes are very private, the following example demonstrates this: 
 + 
 +<code php> 
 +<?php 
 +/* 
 +* foo 
 +* @package foo 
 +*/ 
 +class foo  
 +
 +    /* 
 +    * foo\bar supporting class for foo 
 +    * @subpackage foo\bar 
 +    * @private 
 +    */ 
 +    private class bar 
 +    {
                  
-        const UNKNOWN = 0; +        /* 
-        const ZIP = 1; +        * \foo\bar\baz supporting class for foo\bar 
-        const GZIP = 2; +        * @subpackage foo\bar\baz 
-         +        * @private 
-        private class ZipFileReader { +        */ 
-            private class Buffer implements FileReader\IOBuffer { +        private class baz  
-                /* ... */ +        {
-            }+
                          
             public function __construct() {             public function __construct() {
-                $this->buffer = new FileReader\ZipFileReader\Buffer(); +                 
-            }+            }    
         }         }
                  
-        private class GzFileReader +        public function __construct() 
-            private class Buffer implements FileReader\IOBuffer +            $this->baz = new foo\bar\baz(); 
-                /* ... */ +        } 
-            } +    } 
-            +     
 +    /* PUBLIC API METHODS HERE */ 
 +     
 +    public function __construct()  
 +    { 
 +        $this->bar = new \foo\bar(); 
 +        $this->baz = new \foo\bar\baz(); /* line 39 */ 
 +    } 
 +
 + 
 +new \foo(); 
 +?> 
 +</code> 
 + 
 +Output: 
 + 
 +<code> 
 +Fatal error: Cannot access private class foo\bar\baz from foo in %s on line 39 
 +</code> 
 + 
 +===== Protecting bits of your Privates ===== 
 + 
 +The following example shows how protected and private classes can be used in conjunction to provide versatile encapsulation: 
 + 
 +<code php> 
 +<?php 
 +/* 
 +* foo 
 +* @package foo 
 +*/ 
 +class foo 
 +
 +    /* 
 +    * foo\bar supporting class for foo 
 +    * @subpackage foo\bar 
 +    * @private 
 +    */ 
 +    private class bar 
 +    { 
 +  
 +        /* 
 +        * \foo\bar\baz supporting class for foo\bar 
 +        * @subpackage foo\bar\baz 
 +        * @protected 
 +        */ 
 +        protected class baz 
 +        { 
 + 
             public function __construct() {             public function __construct() {
-                $this->buffer = new FileReader\GzFileReader\Buffer();+ 
             }             }
         }         }
-         +  
-        public function __construct($filename) { +        public function __construct() { 
-            switch (FileReader::getFileType($filename)) { +            $this->baz = new foo\bar\baz();
-                case FileReader::ZIP:+
-                    $this->reader = new FileReader\ZipFileReader($filename); +
-                } break; +
-                 +
-                case FileReader::GZIP:+
-                    $this->reader = new FileReader\GzFileReader($filename)+
-                } break; +
-                 +
-                /* ... */ +
-            } +
-        } +
-         +
-        public static function getFileType($filename) { +
-            /** .. **/ +
-            return FileReader::ZIP;+
         }         }
 +    }
 + 
 +    /* PUBLIC API METHODS HERE */
 + 
 +    public function __construct()
 +    {
 +        $this->bar = new \foo\bar();
 +        $this->baz = new \foo\bar\baz();
     }     }
 } }
  
-namespace { +var_dump(new \foo()); 
-    var_dump(new io\FileReader($argv[0]));+</code> 
 + 
 +Output: 
 + 
 +<code> 
 +object(foo)#1 (2) { 
 +  ["bar"]=> 
 +  object(foo\bar)#2 (1) { 
 +    ["baz"]=> 
 +    object(foo\bar\baz)#3 (0) { 
 +    } 
 +  } 
 +  ["baz"]=> 
 +  object(foo\bar\baz)#4 (0
 +  }
 } }
-?> 
 </code> </code>
  
-More examples to come as the questions come in ...+The protected class ''\foo\bar\baz'' can now be used in ''\foo'', for example:
  
 +<code php>
 +<?php
 +/*
 +* foo
 +* @package foo
 +*/
 +class foo
 +{
 +    /*
 +    * foo\bar supporting class for foo
 +    * @subpackage foo\bar
 +    * @private
 +    */
 +    private class bar
 +    {
 + 
 +        /*
 +        * \foo\bar\baz supporting class for foo\bar
 +        * @subpackage foo\bar\baz
 +        * @protected
 +        */
 +        protected class baz
 +        {
 + 
 +            public function __construct() {
 + 
 +            }
 +        }
 + 
 +        public function __construct() {
 +            $this->baz = new foo\bar\baz();
 +        }
 +    }
 +    
 +    /*
 +    * \foo\qux supporting class for foo
 +    */
 +    private class qux extends foo\bar\baz
 +    {
 +        public function __construct() {
 +            
 +        }
 +    }
 + 
 +    /* PUBLIC API METHODS HERE */
 + 
 +    public function __construct()
 +    {
 +        $this->bar = new \foo\bar();
 +        $this->baz = new \foo\bar\baz();
 +        $this->qux = new \foo\qux();
 +    }
 +}
 + 
 +var_dump(new \foo());
 +</code>
 +
 +Output:
 +
 +<code>
 +object(foo)#1 (3) {
 +  ["bar"]=>
 +  object(foo\bar)#2 (1) {
 +    ["baz"]=>
 +    object(foo\bar\baz)#3 (0) {
 +    }
 +  }
 +  ["baz"]=>
 +  object(foo\bar\baz)#4 (0) {
 +  }
 +  ["qux"]=>
 +  object(foo\qux)#5 (0) {
 +  }
 +}
 +</code>
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
  
rfc/nested_classes.1380669164.txt.gz · Last modified: 2017/09/22 13:28 (external edit)