🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
6.如果没有明确的关键字(private,protected)限定,类的属性和方法默认为公有。 [TOC] ## **Static** 声明类属性或方法为静态,就可以不实例化类而直接访问。 静态属性的使用: * 在类中,通过`self::静态属性名`访问。 * 在类外,通过`类名::静态属性名`访问。 * 不能通过一个类已实例化的对象来访问。 * 不可以由对象通过 -> 操作符来访问。 * 只能被初始化为文字或常量(整数或数组),不能使用表达式。 * 不能初始化为另一个变量或函数返回值,也不能指向一个对象。 静态方法的使用: * 在类中,通过`self::静态方法名()`访问。 * 在类外,通过`类名::静态方法名()`访问; 或者通过一个类已实例化的对象通过`对象变量名->静态方法名()`访问。 * 在静态方法中只能访问静态属性/方法,所以类没有实例化对象的时候,伪变量` $this` 在静态方法中不可用。 * 用静态方式调用一个非静态方法会导致一个 **`E_STRICT`** 级别的错误。 >[info] 自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字 *self*,*parent* 或 *static*。 示例: ~~~php <?php class Foo {     public static $my_static = 'foo';     public function staticValue() {         return self::$my_static;     } } class Bar extends Foo {     public function fooStatic() {         return parent::$my_static;     } } print Foo::$my_static . "\n"; $foo = new Foo(); print $foo->staticValue() . "\n"; print $foo->my_static . "\n";      // Undefined "Property" my_static  print $foo::$my_static . "\n"; $classname = 'Foo'; print $classname::$my_static . "\n"; // As of PHP 5.3.0 print Bar::$my_static . "\n"; $bar = new Bar(); print $bar->fooStatic() . "\n"; ?>    </programlisting>   </example>   <example>    <title>静态方法示例</title>     <programlisting role="php"> <![CDATA[ <?php class Foo {     public static function aStaticMethod() {         // ...     } } Foo::aStaticMethod(); $classname = 'Foo'; $classname::aStaticMethod(); // 自PHP 5.3.0起,可以用一个变量来动态调用类 ?> ~~~ ## **继承** ### **接口类 / interface** ### **抽象类 / abstract** ## 类/对象 函数(20个) 1. __autoload — 尝试加载未定义的类 2. call_user_method_array — 以参数列表的数组,调用用户方法 3. call_user_method — 对特定对象调用用户方法 4. class_alias — 为一个类创建别名 5. class_exists — 检查类是否已定义 6. get_called_class — 后期静态绑定("Late Static Binding")类的名称 7. get_class_methods — 返回由类的方法名组成的数组 8. get_class_vars — 返回由类的默认属性组成的数组 9. get_class — 返回对象的类名 10. get_declared_classes — 返回由已定义类的名字所组成的数组 11. get_declared_interfaces — 返回一个数组包含所有已声明的接口 12. get_declared_traits — 返回所有已定义的 traits 的数组 13. get_object_vars — 返回由对象属性组成的关联数组 14. get_parent_class — 返回对象或类的父类名 15. interface_exists — 检查接口是否已被定义 16. is_a — 如果对象属于该类或该类是此对象的父类则返回 TRUE 17. is_subclass_of — 如果此对象是该类的子类,则返回 TRUE 18. method_exists — 检查类的方法是否存在 19. property_exists — 检查对象或类是否具有该属性 20. trait_exists — 检查指定的 trait 是否存在 ## 待考证 ### 1静态方法与实例方法的优劣 * 一般情况下声明静态方法的类大多是工具类,并且这些静态方法不需要访问类型中的非静态字段和事件,也就是说静态方法与该类型中的非静态字段和事件不具有逻辑上的关联性。如果一个方法声明为静态方法,也意味着不能被重写,该方法失去面向对象的扩展和多态的特性。 * 静态方法与实例方法在性能和占用内存上没有明显的区别,是否声明为静态方法需要从类型的非静态字段、事件、面向对象扩展和多态这三方面来考虑。** * 在并发数较少的情况下,在构造方法中实例化并在方法中调用略占优,但三者性能无太大差别。**当并发数较多时**,尤其大并发情况下,优先推荐构造方法中实例化,再其次是方法中实例化,最后再是静态方法。**高并发情况下,静态方法对性能影响比较大**。 * 多个线程调用静态方法,是否会出现并发问题取决于,静态方法内部是否需要引用共享区内的静态变量。当线程调用静态方法时,都会创建一套临时变量,可见性是在这个线程内部,所以当多个线程调用静态方法时,并且这个静态方法没有引用外部静态变量的。不会有线程并发的问题。 * 由于静态方法在内存中只有一份,无论你调用多少次,都是共用的,而且没有对象的概念,所以不能在静态方法里面使用$this调用,如果非得调用的话,只能实例化自身类 * 而实例化不一样,每一个实例化是一个对象,在内存中是多个的。 * 静态属性、方法(包括静态与非静态)在内存中,只有一个位置(而非静态属性,有多少实例化对象,就有多少个属性)。