凤凰平台注册开户_凤凰彩票app下载安装_凤凰彩票投注网

热门关键词: 凤凰平台注册开户,凤凰彩票app下载安装,凤凰彩票投注网

PHP使用静态方法的几个注意事项_php技巧_脚本之家

作者: 编程知识  发布:2019-11-24

本文实例介绍了PHP使用静态方法的几个常见注意事项。分享给大家供大家参考。具体方法如下:

static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。

php.net

1. 即使类中的方法并未用static声明,但其未使用到可改变的类成员变量,在外部仍可用操作符::来调用;

简单分的可以有这么几个类别

Class member variables are called "properties".
You may also see them referred to using other terms such as "attributes" or "fields",
but for the purposes of this reference we will use "properties".
类的变量成员叫做"属性",或者叫"字段"、"特征",在本文档统一称为"属性"。
 They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration.
 This declaration may include an initialization, but this initialization must be a constant value--that is,
 it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
属性声明是由关键字 public,protected 或者 private 开头,然后跟一个普通的变量声明来组成。
属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指 PHP 脚本在编译阶段(E compile time)时就可以得到其值,而不依赖于运行(E run-time)时的信息才能求值。

2. 以静态方式调用的方法中$this的取值是由调用时的上下文决定的!而不是定义他的类!!

  • static 变量
  • static 方法
  • static 代码块

Within class methods non-static properties may be accessed by using -> (Object Operator): $this->property
(where property is the name of the property).

normal_v.'
'.self::$STATIC_V; } } class TestClass2 { public $normal_v = 'normal_v from TestClass2'; public static $STATIC_V = 'STATIC_V from TestClass2'; public function test_func2() { TestClass1::test_func1(); } } $t2 = new TestClass2; 

一、特点

  • 1、随着类的加载而加载,优先于对象存在,不依赖于类的实例,被所有对象所共享,也就是说——static的成员和方法可以被直接被类名调用

    被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

    只要一个类的方法或者成员被static修饰,那么就可以直接通过 类名.方法名 或者 类名.变量名 访问。当然也可以被该类的实例调用

  • 2、static的方法仅能调用其他的static 方法,只能访问static数据,不能以任何方式引用this 或super。

    static有足够的自由,但是只能陪自由的人玩,随着类的加载而加载,没有this,meiyou super。

    阿敏说:别的成员都是伴随着对象存在的,static如果调不是static的东西不可能,不是一个等级,static在别人不在,怎么一起工作?

  • 3、通常一个普通类不允许声明为静态的(非法),只有内部类才可以。这时这个声明为静态的内部类可以直接作为一个普通类来使用,而不需实例一个外部类。

    静态类只允许是内部类,使用内部静态类不需要实例化。
    静态内部类和非静态内部类之间到底有什么不同呢?下面是两者间主要的不同。

  • (1)内部静态类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。()

  • (2)非静态内部类能够访问外部类的静态和非静态成员。静态类不能访问外部类的非静态成员。他只能访问外部类的静态成员。

  • (3)一个非静态内部类不能脱离外部类实体被创建,一个非静态内部类可以访问外部类的数据和方法,因为他就在外部类里面。

 

这段代码是输出会是什么呢,我原以为会是normal_v from TestClass1
STATIC_V from TestClass1,测试发现其实我错了,正确的输出是:

二、static与访问修饰符

Static properties are accessed by using the :: (Double Colon): self::$property.

normal_v from TestClass2STATIC_V from TestClass1

1、static与访问修饰符

与public
用public修饰的static成员变量和成员方法本质是全局变量和全局方法

与private
static 变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。

The pseudo-variable $this is available inside any class method  when that method is called from within an object context. 

说明:test_func1()虽然是在TestClass1中定义的,但却是在TestClass2中调用的,其内部的$this变量则是由TestClass2决定的!

三、static变量

按照是否静态的对类成员变量进行分类可分两种:

  • 一种是被static修饰的变量,叫静态变量或类变量;
  • 另一种是没有被static修饰的变量,叫实例变量。

两者的区别是:

静态变量/类变量

对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。

实例变量

对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响。

$this is a reference to the calling object (usually the object to which the method belongs, but possibly another object,

其实这两个类的关系应该属于"双向关联".

四、static方法

  • 静态方法可以直接通过类名调用,
  • 任何的实例也都可以调用,
  • 静态方法不能被继承
  • 静态方法中不能用this和super关键字
    (我不能实例化都可以存在,我this我干嘛,我不能被继承,你super我干嘛)
  • 不能直接访问所属类的实例变量和实例方法,只能访问所属类的静态成员变量和成员方法。
    (因为实例成员与特定的对象关联!)
  • 因为static方法独立于任何实例,因此static方法不能是abstract,因为static方法要有方法体。

static方法可以是private,这个不冲突,访问修饰符永远只做访问修饰符做的事情,但是标记为private的static方法在其他类中(包括子类)就不能通过 类名.方法名 调用了。

if the method is called statically from the context of a secondary object).
当一个方法在类定义内部被调用时,有一个可用的伪变量 $this。

感兴趣的朋友可以测试运行本文实例,相信会有新的收获!

4、静态代码块

用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块

$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。

五、证明

It is possible to define constant values on a per-class basis remaining the same and unchangeable.

1、证明 类的所有实例共享同一个static变量

public class SpeClassTest {
     static int num = 0;
}

.

.

一个对象改变static属性的值,全部对象改变

import java.util.Arrays;

public class TestClass {
    public static void main(String[] args) {    
        SpeClassTest spe1 = new  SpeClassTest();
        SpeClassTest spe2 = new  SpeClassTest();
        System.out.println("spe1 的成员值:"+spe1.num+"    spe2 的成员值:"+spe2.num+"n");
        // 因为SpeClassTest里面的num属性是static的,所有对象共享,一个变则全部变
        spe1.num = 3;
        System.out.println("spe1 的成员值:"+spe1.num+"    spe2 的成员值:"+spe2.num+"n");
    }
}

.

.

输出

spe1 的成员值:0    spe2 的成员值:0
spe1 的成员值:3    spe2 的成员值:3

由此可以证明它们共享一块存储区。static变量有点类似于C中的全局变量的概念。

Constants differ from normal variables in that you don't use the $ symbol to declare or use them.

2、静态代码块在类加载时加载,而且只执行一次,static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何

普通代码块是在类初始化的时候加载
.
.

public class MyValue {
    static int val = 0;
    MyValue(){
        val = 10;
    }
    MyValue(int i){
        val = i;
    }
   void add(){
        val = val+1;
    }
}

.

.

import java.util.Arrays;
public class TestClass {
    MyValue myValue = new MyValue(10);
    static MyValue v1,v2;
    static{
        prt("v1.val  "+v1.val+"   v2.val:"+v2.val);
        v1 = new  MyValue(30);
        prt("v1.val  "+v1.val+"   v2.val:"+v2.val);
        v1 = new  MyValue(40);
        prt("v1.val  "+v1.val+"   v2.val:"+v2.val);
    }

    public static void main(String[] args) {    
        TestClass test = new TestClass();
        prt("test.myValue.val: "+test.myValue.val);
        prt("v1.val  "+v1.val+"   v2.val:"+v2.val);
        v1.add();
        prt("test.myValue.val: "+test.myValue.val);
        prt("v1.val  "+v1.val+"   v2.val:"+v2.val);
    }
    public static void prt(String s) {
           System.out.println(s);
    }
}

.

输出

v1.val  0   v2.val:0
v1.val  30   v2.val:30
v1.val  40   v2.val:40
test.myValue.val: 10
v1.val  10   v2.val:10
test.myValue.val: 11
v1.val  11   v2.val:11

分析:

开始的三句输出,

v1.val 0 v2.val:0
v1.val 30 v2.val:30
v1.val 40 v2.val:40

是因为TestClass这个静态代码块随着类的加载而加载导致的(如果我们把main方法的里面的逻辑去掉,那么只有前面的三句了)

重点是:static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何。正如在程序中所表现的,虽然myValue出现在v1和v2的前面,但是结果却是v1和v2的初始化在myValue的前面

.

.

.

而第4句

test.myValue.val: 10

是因为main方法里面TestClass test = new TestClass();这句执行,但是此时static代码块已经记载过就不会再加载了,所以打印的是10.

(如果没TestClass test = new TestClass();这一句,那么肯定val的值还是40)

后面几乎就没什么了,没什么特别的了。

The default visibility of class constants is public.

3、static类只能是内部类,其他静态类非法

public class StaticCls {
    public static void main(String[] args) {
       OuterCls.InnerCls oi = new OuterCls.InnerCls();
    }
}

class OuterCls {
    public static class InnerCls {
       InnerCls() {
           System.out.println("InnerCls");
       }
    }
} 
    结果为:InnerCls

.
.
.

下面代码演示 java中创建静态内部类和非静态内部类

/* 下面程序演示如何在java中创建静态内部类和非静态内部类 */

class OuterClass{
   private static String msg = "GeeksForGeeks";
   // 静态内部类
   public static class NestedStaticClass{
       // 静态内部类只能访问外部类的静态成员
       public void printMessage() {
         // 试着将msg改成非静态的,这将导致编译错误 
         System.out.println("Message from nested static class: " + msg); 
       }
    }
    // 非静态内部类
    public class InnerClass{
       // 不管是静态方法还是非静态方法都可以在非静态内部类中访问
       public void display(){
          System.out.println("Message from non-static nested class: "+ msg);
       }
    }
} 

class Main
{
    // 怎么创建静态内部类和非静态内部类的实例
    public static void main(String args[]){
       // 创建静态内部类的实例
       OuterClass.NestedStaticClass printer = new OuterClass.NestedStaticClass();
       // 创建静态内部类的非静态方法
       printer.printMessage();   
       // 为了创建非静态内部类,我们需要外部类的实例
       OuterClass outer = new OuterClass();        
       OuterClass.InnerClass inner  = outer.new InnerClass();
       // 调用非静态内部类的非静态方法
       inner.display();
       // 我们也可以结合以上步骤,一步创建的内部类实例
       OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
       // 同样我们现在可以调用内部类方法
       innerObject.display();
    }
}

The value must be a constant expression, not (for example) a variable, a property, or a function call.

六、static和final一块用表示什么

static final用来修饰成员变量和成员方法,可简单理解为“全局常量”!
对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
对于方法,表示不可覆盖,并且可以通过类名直接访问。

可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。
常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。

本文由凤凰平台注册开户发布于编程知识,转载请注明出处:PHP使用静态方法的几个注意事项_php技巧_脚本之家

关键词: