OOP中的静态方法

时间:2016-01-29 16:38:42

标签: oop static

我一直都知道静态方法的定义是什么,但我总是避免在学校使用它们,因为我害怕我不知道的事情。

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

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

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

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

4 个答案:

答案 0 :(得分:11)

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

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

见这个比较:

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);
}

答案 1 :(得分:2)

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

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

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

    public static function unzipFile($fileName)
    {
        //
    }
}

事实是,这里没有任何面向对象的东西。您刚刚定义了两个函数,您需要使用像Zip::zipFile($myFile)这样的花哨语法而不仅仅是zipFile($myFile)来调用。

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

所以在这种情况下,最好只在类之外定义这些函数,作为常规函数。自5.3版以来,php中有namespaces,如果你想对你的功能进行分组,你可以使用它们。

使用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
    }
}

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

$archive = new ZipArchive('path/to/archive.zip');
$archive->add('file1')->add('file2')->zip();

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

例如,您可以拥有基类Archive和子类,例如ZipArchiveTarGzArchive等。

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

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();

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

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

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

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

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

答案 2 :(得分:0)

是的,静态类用于需要无状态计算的问题。比如加两个数字。压缩文件。等

如果您的类需要状态,您需要存储连接或其他更长的生命实体,那么您将不会使用静态。

答案 3 :(得分:0)

AFAIK。静态方法不依赖于类实例。就是这样。

举个例子: 如果你有一个只有一个数据库连接的单个线程程序,并且会对数据库进行多次查询,最好将它作为一个静态类实现(注意我指定你不会连接到几个数据库或者有几个线程)。 因此,您不需要创建多个连接对象,因为您已经知道只使用一个。而且您不需要创建多个对象。在这种情况下,单身人士也是一种选择。

还有其他例子。

如果您创建一个类来转换值。

class Convert{
    static std::string fromIntToString(int value);
}

这样,每次需要从整数转换为字符串时,您都不需要创建类转换。

std::string value = Convert::fromIntToString(10).

如果你还没有这样做,你需要通过你的程序多次实例化这个类。

我知道您可以找到其他几个例子。由你和你的场景来决定你什么时候去做。