PHP 기본 튜토리얼 10: 정적 속성 및 정적 메서드

黄舟
풀어 주다: 2023-03-06 08:58:02
원래의
2589명이 탐색했습니다.

이 섹션에 설명된 내용

  • 정적 속성 및 정적 메서드

  • 액세스 수정자

  • 싱글톤 모드

  • 매직 메소드

  • 클래스 자동 로딩

서문

이전 섹션에서는 객체지향의 기본적인 사용법을 소개했지만, 이전 섹션의 지식으로는 실제로는 여전히 해결되지 않는 문제가 있습니다. 예를 들어 티켓을 사러 가면 총 투표 수가 있고(티켓의 속성을 정의) 사람이 티켓을 사러 옵니다( 티켓 - 1) 매번 객체를 생성하고 객체에 따라 메모리의 방법은 총 투표 수를 다시 생성하는 것이므로 여기서는 정적 개념을 사용합니다. PHP의 클래스:

  1. 정적 속성

  2. 정적 메서드

정적 속성

이 클래스의 정적 속성은 모든 객체가 공유하는 클래스입니다. 이 클래스의 객체가 액세스하면 마찬가지로 이 객체도 동일한 값을 얻습니다. 클래스가 이를 수정하면 동일한 변수도 수정됩니다.

<?php
    class Ticket{
        public static $number = 100; //设置总的票数是100;
        public $name ; 

        public function __construct($name){
            $this-> name = $name;
        }
        //定义一个方法进行买票
        public function sellTicket(){
            echo $this-> name . &#39;买票了<br>&#39;;
            self::$number--; //每调用一次方法总票数就减一。
        }
    }

    $people1 = new Ticket(&#39;小白&#39;);
    $people2 = new Ticket(&#39;小明&#39;);
    $people3 = new Ticket(&#39;小华&#39;);
    $people4 = new Ticket(&#39;小张&#39;);
    //每个人进行买票
    $people1 -> sellTicket();
    $people2 -> sellTicket();
    $people3 -> sellTicket();
    $people4 -> sellTicket();

    echo Ticket::$number; //在类的外部通过类名访问静态属性。
    ......结果........
    小白买票了
    小明买票了
    小华买票了
    小张买票了
    96
로그인 후 복사

위 코드에서 정적 속성이 정의되는 방식을 볼 수 있습니다.

访问修饰符  static  $静态属性名字 = 初始化值;
로그인 후 복사

정적 속성은 클래스 내부에서만 정의할 수 있습니다.

정적 속성에 액세스

클래스 외부

클래스 외부에서 클래스의 정적 속성에 액세스할 수도 있습니다. 위에서 설명한 대로 클래스 이름을 통한 직접 액세스(권한 수정자가 공개인 경우에만 수행 가능) Ticket::$number 여기서::는 범위 파서입니다.

정적 속성은 클래스 외부 객체를 통해서도 접근할 수 있습니다

$people4::$number;
로그인 후 복사

클래스 이름을 통한 접근은 범위 파서::를 통해 접근합니다.

클래스에서

위 코드에서 클래스에서 self::$static 속성 이름을 통해 액세스하는 것을 볼 수 있습니다. 이 메서드 외에도 클래스에서 액세스하는 또 다른 방법이 있습니다.

Ticket::$number--;
로그인 후 복사

클래스 이름으로 액세스됩니다. 권장되는 형식은 self를 통한 형식입니다. 이렇게 하면 클래스 이름이 변경될 때 수정할 필요가 없기 때문입니다. 그렇다면 self와 $this의 차이점은 무엇인가요?

$this와 self의 차이점

사실 이전 섹션에서 언급했듯이 $this는 현재 객체를 가리키며, 여기서 self는 현재 클래스를 가리키며, 하나는 객체를 가리키고 다른 하나는 클래스를 가리키며 서로 다른 지점을 가리킵니다. 동시에 이들은 서로 다른 방식으로 사용됩니다. self is two::, $this is ->. 그러나 둘 다 적용 범위는 동일하며 둘 다 클래스 내부에서 사용됩니다.

정적 속성 사용

위에서는 정적 속성을 사용해야 하는 경우에 대해서만 정의하고 사용하는 방법에 대해서만 설명했습니다. 프로젝트 개발 중에 모든 객체가 데이터 일부를 공유하도록 해야 할 경우 정적 속성 사용을 고려합니다.

정적 속성도 속성이므로 일반 속성과 차이점은 다음과 같습니다.

  • 속성에 static 키워드가 있으면 정적 속성이 됩니다.

  • 정적 속성은 클래스에 속하며, 모든 객체가 공유하는 속성

  • 일반 속성은 단일 객체에 속합니다.

위와 마찬가지로 정적 속성은 비정적 메서드에서 액세스할 수 있습니다. ;

정적 메서드

위에서 정적 속성에 대해 이야기했으니 다음에는 정적 메서드에 대해 이야기해 보겠습니다.

<?php
    class Ticket{
        public static $number = 100; //设置总的票数是100;
        public $name ; 

        public function __construct($name){
            $this-> name = $name;
        }

        public static function sayHello(){
            echo &#39;这是静态方法<br>&#39;;
        }

        public function info(){
            //在类的内部使用静态方法
            self::sayHello(); //通过self访问
            Ticket::sayHello();//通过类名的方式进行访问
        }
    }

    $people1 = new Ticket(&#39;小白&#39;);
    $people1 -> info();
    $people1::sayHello(); //在类的外部通过对象名进行访问
    Ticket::sayHello();  //通过类型进行访问。
    ......结果........
    这是静态方法
    这是静态方法
    这是静态方法
    这是静态方法
로그인 후 복사

정적 메서드는 static 키워드를 통해 정의됩니다.

访问修饰符 static function 方法名(参数列表){
    code....
}
로그인 후 복사

클래스 외부의 정적 메서드에 액세스

클래스 외부 정적 메서드의 접근 방식은 정적 속성에 접근하는 방법과 동일합니다(권한 한정자는 public인 경우에만 외부적으로 접근 가능).

  • 클래스 이름을 통한 액세스: :static 메서드 이름

  • 객체 이름을 통한 액세스: :static 메서드 이름(권장하지 않음)

  • 객체 이름별->정적 메서드 이름별. 이것이 접근 방식의 형태이다.

클래스 내

클래스 내 정적 메소드에 접근하는 방법은 정적 속성에 접근하는 방법과 동일합니다

  • self::정적 메서드 이름

  • 클래스 이름::정적 메서드 이름

사용 정적 메소드

그럼 어떤 상황에서 정적 메소드를 사용할까요? 정적 속성을 조작할 때 정적 메서드를 사용할 수 있습니다.

  • 정적 속성을 조작해야 할 경우

  • PHP 개발 시 단일 예제와 같은 일부 패턴을 사용하는 경우가 많습니다. 모드, 팩토리 모드, 관찰자 ​​모드 등은 모두 정적 메서드를 사용합니다.

참고: 정적 메서드는 비정적 속성에 액세스할 수 없습니다.

액세스 한정자

위의 코드와 설명을 보면 속성 앞이나 메소드 앞에 public이 있는 것을 알 수 있습니다. 그들 중. 접근 한정자는 객체 캡슐화를 구현하는 방법이라고 할 수 있습니다.

访问修饰符的分类及区别

在PHP中访问修饰符可以分为三中

  1. public 在上面的代码中我们都是使用的public,使用这种这个关键字修饰的属性和方法,不管在类的内部还是在类的内部都是可以访问的。

  2. protected(受保护的)如果使用这个关键字修饰,那么在类的外部是不能访问。只能在类的内部进行访问。

    <?php
    
        class Cat{
            public $name;
            protected $age;
            public function __construct($name,$age){
                $this -> name = $name;
                $this -> age = $age;
            }
    
        }
    
        $cat = new Cat(&#39;小白&#39;,4);
        echo $cat -> name; //在类的外部访问public
        echo &#39;<br>&#39;;
        echo $cat -> age; //在类的外部访问protected修饰的属性。
    ......结果.....
    小白
    
    Fatal error: Cannot access protected property Cat::$age in D:\mywamp\Apache24\htdocs\zendstudio\yunsuanfu\xiushifu.php on line 16
    로그인 후 복사

    错误的信息是说不能访问protected修饰的属性。

  3. private(私有的),只能在类的内部使用,在外部使用会报和上面一样的错误。

这三种,后面两种看起来作用一样,都是只能在类内部使用,那又有什么区别呢?现在看来,并没有区别,但是学过类的继承,那么这两种还是有区别的。
PHP 기본 튜토리얼 10: 정적 속성 및 정적 메서드
访问修饰符的使用:

  • 成员属性必须制定访问修饰符,不然会报错

  • 方法前面可以不写修饰符,默认是public

  • 静态属性可以不指定访问修饰符,默认是public

单例模式

上面讲解到我们什么时候使用到静态方法。在一些设计模式中,我们可以使用到静态方法和静态属性。

设计模式:是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。(百度)

在开发的时候,我们有这样的需求,在代码中我们创建一个对象,但是我们希望在一个项目中,这个对象实例只能有一个,不能创建多个对象,从而实现对数据库等资源的保护。这时候就使用到单例模式。

<?php

    class DaoMysql{
        public $link; //模拟数据库连接
        private static $instance;//当前类的对象。

        private function __construct(){
            echo &#39;数据库连接<br>&#39;;
        }

        public static function getInstance(){
            if(self::$instance == null){
                self::$instance = new DaoMysql();
            }
            return self::$instance;
        }

        public function insertSql(){
            echo &#39;添加数据<br>&#39;;
        }
    }

    $daoMysql = DaoMysql::getInstance();
    $daoMysql -> insertSql();
    $daoMysql2 = DaoMysql::getInstance();
    $daoMysql2 -> insertSql();
    ......结果.......
    数据库连接
    添加数据
    添加数据
로그인 후 복사

1. 既然是单例模式,那么就不能在外部创建对象,这就要把构造函数用private修饰(创建对象要调用构造函数,这里把构造函数私有化,调用不起来),这样在外部就不能创建对象。
2. 我们在类里面创建了一个对象的引用$instance,在类里面创建对象,这是允许的。
3. 在类中定义一个静态方法,我们就是通过这个方法来创建对象,通过类名::方法名进行创建,进去后先判断$instance是否为空,只有如空的时候我们才进行创建。然后返回对象。
4. 因为要在静态方法中访问属性,那么这个属性就应该是静态的属性。
5. 在类的外部通过类::静态方法名进行对象的创建。
6. 在结果中我们可以看到我们有两个对象,但是构造方法在第二次没有执行,说明对象没有创建。

虽然在上面我们做了很多限制,但是在PHP中还是有方法的到更过的对象,克隆和继承。

对象类型运算符

在上面的静态方法中判断对象是否创建还有一种方法。

if(!(self::$instance instanceof self)){
                self::$instance = new DaoMysql();
}
로그인 후 복사

其中instanceof就是类型运算符。 根据帮助文档,它有几个作用

  1. 用于确定一个 PHP 变量是否属于某一类 class 的实例:

  2. 可用来确定一个变量是不是继承自某一父类的子类的实例:

  3. 也可用于确定一个变量是不是实现了某个接口的对象的实例:

上面的代码中self代表当前的类。instanceof判断前面的变量是否是后面类的实例,然后取反。

魔术方法

在PHP中有一些定义在类中的神奇的方法,称为魔术方法。具体的魔术的方法的使用可以看另外一篇博客
PHP的魔术方法

类的自动加载

在前面我们讲过文件的引入,使用include和require这两种类型。在开发中我们有时需要引入大量的文件,可以是10个,也可能是20个,如果还是使用原来的方法,累人。

在 PHP 5 中,不再需要这样了。可以定义一个 __autoload() 函数,它会在试图使用尚未被定义的类时自动调用
而我们在写类的时候,一般都是一个类一个文件,而文件的名字我们一般是类名.class.php的格式。

<?php
    //自动加载的方法,当我们使用这个文件不存在的类的时候,就会自动加载。
    function __autoload($class_name){
        require_once &#39;./&#39; . $class_name . &#39;.class.php&#39;;
    }

    $dao = new Dao(&#39;小白&#39;,5);
    $cat = new Cat(&#39;小花&#39;,2);
    $dao -> eat();
    $cat -> eat();
로그인 후 복사

__autoload($类名),在个函数不是写在类中的,所以前面是没有权限修饰符。

上面的自动加载方式是有局限性的,当文件是在不同的文件夹中的时候,这种方法显然是不行的。这时候可以创建一个数组,把类名当做键,对应的路径当成值,进行存储。自动加载的时候就能正确的引入。

<?php

    $path = array(
            &#39;Dao&#39; => &#39;./dao/Dao.class.php&#39;,
            &#39;Cat&#39; => &#39;./cat/Cat.class.php&#39;
        );



    //自动加载的方法,当我们使用这个文件不存在的类的时候,就会自动加载。
    function __autoload($class_name){
        global $path;
        require_once $path[$class_name];
    }

    $dao = new Dao(&#39;小白&#39;,5);
    $cat = new Cat(&#39;小花&#39;,2);
    $dao -> eat();
    $cat -> eat();
로그인 후 복사

可以看到在前面定义了一个数组用来存储路径。
注意:在函数中使用global声明一下,才能使用全局变量。

总结

在面向对象中用到静态属性和静态方法的时候还是很多的。同时权限修饰符在面向对象中是很重要的,因为我们通过修饰符控制访问权限。魔术方法的掌握,也可以让我们在访问中明白各种调理机制。

 以上就是PHP基础教程十之静态属性和静态方法的内容,更多相关内容请关注PHP中文网(www.php.cn)!


원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!