从外部类访问私人功能

时间:2011-11-15 08:49:48

标签: php oop private

我正在学习OO的东西,并且遇到了这个:

class n{

    private function f($v){
        return $v*7;
    }

    function c(){
       return $this->f(5);
    }
}

$o = new n;
echo $o->c(); //returns 35

如果我仍然可以从课外访问它,那是否超出了声明函数private的目的?这不应该被完全阻止吗?我错过了什么吗?请帮忙清理。感谢

9 个答案:

答案 0 :(得分:7)

公共函数用于对该类的实例执行操作。说,Save()

Save()的内部运作对来电者来说并不重要;他只是想保存它而不关心它是如何发生的。

作为一种风格问题,您可能会或可能不想在该方法中实际执行保存。它可能取决于设计选择或对象的属性。参见:

class FooObject
{

    private $_source;

    public function Save()
    {

        if ($this->_source == "textfile")
        {
            $this->saveToTextfile();
        }
        elseif ($this->_source == "database")
        {
            $this->saveToDatabase();
        }
    }

    private function saveToTextfile()
    {
        // Magic
    }

    private function saveToDatabase()
    {
        // Magic
    }
}

您不希望任何人直接调用私有方法,因为它们仅供内部使用。但是,公共方法可以间接调用私有方法。

答案 1 :(得分:5)

您错过了重点,即从外部调用private方法。您从外部调用public方法(缺少可见性修饰符= public),然后从那里类中调用private方法。

答案 2 :(得分:4)

声明事物private只是将它们隐藏在公共界面中。您完全有权在代码片段中执行操作;即根据“隐藏的”私有内部方法实现公共接口。

如果您正在编写库,则可能会使公共接口定义明确,并尝试最小化版本之间的更改(以便用户无需维护其代码)。但是你可以随心所欲地修改内部内容,而不会给用户带来任何费用。

答案 3 :(得分:2)

即使您的代码也无法调用您的功能,请致电

$this->f(5);

通过致电

c()

您将无法使用其他参数调用f(),至少在您发布的代码中是这样。

但不,从公共方法调用私有方法不是代码气味

我的意思是,如果不是从公共方法调用,你还会在哪里调用它们?

答案 4 :(得分:1)

private方法意味着它会执行与外部世界无关的内部事务(在课堂外)。

答案 5 :(得分:1)

您无法直接从外部拨打$o->f(),这是private应该保护的全部内容。如果在调用堆栈中的任何位置包含任何 private方法时无法调用public方法,则根本无法调用它。 您的类的某些方法需要从外部调用;然后可以在内部拨打电话。

答案 6 :(得分:1)

您的代码是正确的,但是如果您未指定方法权限(即:public,private或protected),则会为其分配public的默认行为。所以你的函数c()实际上是公共的,这就是为什么你可以从类外部调用它。

如果您将其切换为私人或受保护,您将收到预期的错误。

答案 7 :(得分:0)

如果你的类不是唯一一个(包含启动机制调用的main()方法),那么在调用“chain”的地方必须有一个类外调用者,否则它的方法应该是从未打过电话。

答案 8 :(得分:0)

    <?php
//Accessing private method in php with parameter
    class Foo {
        private function validateCardNumber($number)
        {   
            echo $number;
        }
    }
    $method = new ReflectionMethod('Foo', 'validateCardNumber');
    $method->setAccessible(true);

    echo $method->invoke(new Foo(), '1234-1234-1234');
    ?>