如何使用私有变量

时间:2015-06-22 17:14:07

标签: php oop

代码说明

我有两个类,网格和几何,用于维护3D数组的属性以填充空间。首先定义网格并构建3D数组。然后可以在网格对象的相同边界内创建几何形状,但不能在原始网格对象中创建。这是通过将网格传递给形状来完成的,这样它就可以使用网格的边界。

形状具有下面未显示的功能,可根据需要填充单元格。例如,你可以添加一个以指定半径为中心的球体,形状将确定要填充的单元格。然后说我真的想要一个半球,我可以清除球体中心下方的所有东西,我会有一个数组,当转换为3D空间时会绘制一个(像素化的)半球。

有些属性允许网格和几何体计算出物理空间位置,这些位置已在下面的代码中删除,因为它们不相关。

一旦形状达到最终形状,我希望能够将其合并回原始网格。因此,如果我想创建一个竖井,我会创建一个如上所述的半球对象,然后创建一个圆柱体,然后将两者都添加回原始网格中。

问题陈述

我想确保几何对象使用了要添加到的网格物体。

$mesh1 = new mesh(2,2,2);
$mesh2 = new mesh(2,2,2);

$geo = new geometry($mesh1);
$geo->fill(0,0,0,1);
$geo->fill(1,1,1,1);

$mesh1->add($geo); //should be fine;
$mesh2->add($geo); //should do nothing since $geo used $mesh1 and not $mesh2 

我知道我可以在对象上使用===运算符来确保它们是相同的,

if ($this === $geo->mesh)

但是$geo->mesh的工作是私有的。如果可能的话,我宁愿保持网格私密。公开$geo->mesh可以解决问题,但不会像我希望的那样保护$geo->mesh

我认为可能会命名网格并使其成为公共几何变量,但它并不像我想的那样干净。

public $name; //in mesh object
public $mesh_name; //in geometry object
$this->mesh_name = $mesh->name; //in geometry constructor

if ($this->name == $geo->mesh_name)
...

有没有办法检查几何使用的网格是否是相同的网格而不破坏封装或需要继承?

课程代码

class mesh
{
    private $domain;

    public $i;
    public $j;
    public $k;

    public function __construct($i, $j, $k)
    {
        $this->i = $i;
        $this->j = $j;
        $this->k = $k;
        $this->build();
    }

    public function build()
    {
        $karr = array_fill(0, $this->k, 0);
        $jarr = array_fill(0, $this->j, $karr);
        $this->domain = array_fill(0, $this->i, $jarr);
    }

    public function add(geometry $geo)
    {
        // if ($this === $geo->mesh)
        {

            for ($i = 0; $i < $this->i; $i++){
                for ($j = 0; $j < $this->j; $j++){
                    for ($k = 0; $k < $this->k; $k++){

                        if ($geo->domain[$i][$j][$k] > 0)
                            $this->domain[$i][$j][$k] = $geo->domain[$i][$j][$k]; 

    }   }   }   }   }

}

class geometry
{
    private $mesh; //would rather keep private

    public $domain;

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

    public function build()
    {
        $karr = array_fill(0, $this->mesh->k, 0);
        $jarr = array_fill(0, $this->mesh->j, $karr);
        $this->domain = array_fill(0, $this->mesh->i, $jarr);
    }

    public function fill($i, $j, $k, $value)
    {
        $this->domain[$i][$j][$k] = $value;
    }
}

1 个答案:

答案 0 :(得分:0)

使用Getters and Setters。下面的代码将允许读取$mesh_name属性,但不能由外部代码写入。

class MyObject {
    protected $mesh_name = 'foo';
    protected $accessible = ['mesh_name'];
    protected $writable = [];

    public function __get($name) {
        if( in_array($name, $this->accessible) ) [
            return $this->name;
        } else {
            // return null, throw exception, do nothing
        }
    }

    public function __set($name, $value) {
        if( in_array($name, $this->writable) ) {
            if( $this->validationMethod($value) ) {
                $this->$name = $value;
            } else {
                throw new Exception("Property $name failed validation: $value");
            }
        } else {
            throw new Exception("Property $name is not marked as writable.");
        }
    }
}

例如:

$foo = new MyObject();
echo $foo->mesh_name; // foo
$foo->mesh_name = 'bar'; // Exception("Property mesh_name is not marked as writable.");