OOP中的静态方法

use*_*422 5 oop static

我总是知道静态方法的定义是什么,但我总是避免在学校使用它们,因为我害怕我不知道的东西.

我已经明白你可以在整个项目中使用它作为计数器.

现在我实习了,我想知道什么时候使用完全静态的方法.从我到目前为止的观察结果来看,静态类/方法在包含许多将在许多不同类中使用的函数时使用,并且本身在类中不包含太多关键局部变量,而不需要创建瞬时它的.

举个例子,你可以有一个名为Zip的静态类来压缩和解压缩文件,并将它提供给许多不同的类,以便它们对它做任何事情.

我对吗?我有正确的想法吗?我很确定有很多方法可以使用它.

Add*_*rdt 10

静态函数很有用,因为它们不依赖于它们附加到的任何类的实例化成员.

静态函数可以提供与特定类相关的功能,而无需程序员首先创建该类的实例.

看到这个比较:

class Numbers
{
    public int Add(int x, int y)
    {
        return x + y;
    }

    public static int AddNumbers(int x, int y)
    {
        return x + y;
    }
}

class Main
{
    //in this first case, we use the non-static version of the Add function
    int z1 = (new Numbers()).Add(2, 4);

    //in the second case, we use the static one
    int z2 = Numbers.AddNumbers(3, 5);
}
Run Code Online (Sandbox Code Playgroud)


Bor*_*rov 6

从技术上讲,上述答案是正确的。但是从 OOP 的角度来看,这些例子是不正确的。

例如,你有一个这样的类:

class Zip
{
    public static function zipFile($fileName)
    {
        //
    }

    public static function unzipFile($fileName)
    {
        //
    }
}
Run Code Online (Sandbox Code Playgroud)

事实是,这里没有任何面向对象的东西。你刚才定义的,你需要使用花哨的语法喜欢叫两个函数Zip::zipFile($myFile),而不是只zipFile($myFile)

您不会在此处创建任何对象,Zip该类仅用作命名空间。

因此,在这种情况下,最好在类之外将这些函数定义为常规函数。从 5.3 版开始,php 中有命名空间,如果你想对你的函数进行分组,你可以使用它们。

使用 OOP 方法,您的类将如下所示:

class ZipArchive
{
    private $_archiveFileName;
    private $_files;

    public function __construct($archiveFileName) {
        $this->_archiveFileName = $archiveFileName;
        $this->_files = [];
    }

    public function add($fileName)
    {
        $this->_files[] = $fileName;
        return $this; // allows to chain calls
    }

    public function zip()
    {
        // zip the files into archive specified
        // by $_archiveFileName
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

$archive = new ZipArchive('path/to/archive.zip');
$archive->add('file1')->add('file2')->zip();
Run Code Online (Sandbox Code Playgroud)

更重要的是,您现在可以以 OOP 方式使用 zip 功能。

例如,你可以有一个基类Archive和子类,如ZipArchiveTarGzArchive等。

现在,您可以创建特定子类的实例并将其传递给其他代码,这些代码甚至不知道文件是要压缩还是 tag.gz 压缩。例如:

if ($config['archive_type'] === 'targz') {
   // use tar.gz if specified
   $archive = new TarGzArchive($path);
} else { 
   // use zip by default
   $archive = new ZipArchive($path);
}
$backup = new Backup($archive /*, other params*/);
$backup->run();
Run Code Online (Sandbox Code Playgroud)

现在$backup对象将使用指定的归档类型。在内部,它不知道也不关心文件将如何归档。您甚至可以拥有一个CopyArchive将文件简单地复制到另一个位置的类。

这样做很容易,因为您的存档支持是以 OOP 方式编写的。您有负责特定事物的小对象,您可以创建并组合它们并获得您想要的结果。

如果你只有一堆静态方法而不是真正的类,你将被迫编写过程式代码。

所以我不建议使用静态方法来实现应用程序的实际功能。

静态方法可能有助于支持日志记录、调试、测试和类似的事情。就像你想计算创建的对象数量一样,你可以使用类级别的静态计数器,在构造函数中增加它,你可以有一个静态方法来读取计数器并打印它或写入日志文件。