首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >继承中的__set和__get重载

继承中的__set和__get重载
EN

Stack Overflow用户
提问于 2014-10-21 06:51:03
回答 2查看 2.4K关注 0票数 3

我正在使用PHP实现OOP设计。我想知道PHP如何为其神奇的方法(如__get和__set )处理继承。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo
{
    protected $property1;

    public function __get($name)
    {
        if ($name == "property1")
        {
            // do some logic
            return $result; // may be null
        }
        return;
    }

    public function __set($name, $value)
    {
        if ($name == "property1")
        {
            // do some logic
            return $result; // may be null
        }
        result;
    }
}

现在用于扩展Foo

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Bar extends Foo
{
    protected $property2;

    public function __get($name)
    {
        if (($result = parent::__get($name)) !== null)
            return $result; // may be null
        if ($name == "property2")
        {
            // do some logic
            return $result; // may be null
        }
        return;
    }

    public function __set($name, $value)
    {
        if (($result = parent::__set($name, $value)) !== null)
            return $result; // may be null
        if ($name == "property2")
        {
            // do some logic
            return $result; // may be null
        }
        return;
    }
}

当PHP将null作为一个函数的结果返回时,没有什么可返回的.这可能导致parent::__get()parent::__set()是否真实返回null,还是返回时不带值,从而导致开销。

现在,如果PHP首先考虑static::_get()static::__set(),并在失败时退回到parent版本,则可以将其简化为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Bar extends Foo
{
    protected $property2;

    public function __get($name)
    {
        if ($name = "property2")
        {
            // do some logic
            return $result; // may be null
        }
        return;
    }

    public function __set($name, $value)
    {
        if ($name = "property2")
        {
            // do some logic
            return $result; // may be null
        }
        return;
    }
}

我无法在当前实现上测试它,因为上下文中的类操作生产、活动数据库。哪个是正确的实现?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-21 07:27:04

只使用魔术方法作为代理方法。您的代码将更加简洁,您不需要处理继承带来的问题。

简单的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo
{
    protected $property1;

    public function setProperty1($property1)
    {
        // do some logic
        $this->property1 = $property1;
        return $this;
    }

    public function getProperty1()
    {
        // do some logic
        return $this->property1;
    }

    public function __get($name)
    {
        $method = 'get' . ucfirst($name);
        if (method_exists($this, $method)) {
            return $this->$method();
        }
    }

    public function __set($name, $value)
    {
        $method = 'set' . ucfirst($name);
        if (method_exists($this, $method)) {
            $this->$method($value);
        }
    }
}

class Bar extends Foo
{
    protected $property2;

    public function setProperty2($property2)
    {
        // do some logic
        $this->property2 = $property2;
        return $this;
    }

    public function getProperty2()
    {
        // do some logic
        return $this->property2;
    }
}

示例呼叫:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$bar = new Bar;
$bar->property1 = 'foo';
$bar->property2 = 'bar';
var_dump($bar);
票数 3
EN

Stack Overflow用户

发布于 2014-10-21 07:25:36

我已经成功地创建了一个孤立的环境并测试了这两种方法。

方法1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo
{
    protected $property1;

    public function __get($name)
    {
        if ($name == "name")
        {
            echo "been here @line(" . __LINE__ . ") Foo::__get('$name') <br/>";
            $result = $this->property1;
            return $result; // may be null
        }
        return;
    }

    public function __set($name, $value)
    {
        if ($name == "name")
        {
            echo "been here @line(" . __LINE__ . ") Foo::__set('$name', '$value') <br/>";
            $result = $this->property1 = $value;
            return $result; // may be null
        }
        return;
    }
}

class Bar extends Foo
{
    protected $property2;

    public function __get($name)
    {
        if ($name == "place")
        {
            echo "been here @line(" . __LINE__ . ") Bar::__get('$name') <br/>";
            $result = $this->property2;
            return $result; // may be null
        }
        return;
    }

    public function __set($name, $value)
    {
        if ($name == "place")
        {
            echo "been here @line(" . __LINE__ . ") Bar::__set('$name', '$value') <br/>";
            $result = $this->property2 = $value;
            return $result; // may be null
        }
        return;
    }
}

$bar = new Bar;

$bar->name = 'Alice';
$bar->place = 'Wonderland';

echo "done that: '{$bar->name} in {$bar->place}'";

上述代码的结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
been here @line(59) Bar::__set('place', 'Wonderland') 
been here @line(43) Bar::__get('place') 
done that: ' in Wonderland'

这显然不是答案。

方法2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo
{
    protected $property1;

    public function __get($name)
    {
        if ($name == "name")
        {
            echo "been here @line(" . __LINE__ . ") Foo::__get('$name') <br/>";
            $result = $this->property1;
            return $result; // may be null
        }
        return;
    }

    public function __set($name, $value)
    {
        if ($name == "name")
        {
            echo "been here @line(" . __LINE__ . ") Foo::__set('$name', '$value') <br/>";
            $result = $this->property1 = $value;
            return $result; // may be null
        }
        return;
    }
}

class Bar extends Foo
{
    protected $property2;

    public function __get($name)
    {
        if (($result = parent::__get($name)) !== null)
        {
            echo "been here @line(" . __LINE__ . ") parent::__get('$name') <br/>";
            return $result; // may be null
        }
        if ($name == "place")
        {
            echo "been here @line(" . __LINE__ . ") Bar::__get('$name') <br/>";
            $result = $this->property2;
            return $result; // may be null
        }
        return;
    }

    public function __set($name, $value)
    {
        if (($result = parent::__set($name, $value)) !== null)
        {
            echo "been here @line(" . __LINE__ . ") parent::__set('$name', '$value') <br/>";
            return $result; // may be null
        }
        if ($name == "place")
        {
            echo "been here @line(" . __LINE__ . ") Bar::__set('$name', '$value') <br/>";
            $result = $this->property2 = $value;
            return $result; // may be null
        }
        return;
    }
}

$bar = new Bar;

$bar->name = 'Alice';
$bar->place = 'Wonderland';

echo "done that: '{$bar->name} in {$bar->place}'";

其结果是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
been here @line(22) Foo::__set('name', 'Alice') 
been here @line(54) parent::__set('name', 'Alice') 
been here @line(59) Bar::__set('place', 'Wonderland') 
been here @line(11) Foo::__get('name') 
been here @line(38) parent::__get('name') 
been here @line(43) Bar::__get('place') 
done that: 'Alice in Wonderland'

这是处理继承时重载__get和__set魔术函数的正确答案,但这有开销。这是一个解决办法,但有没有更好的解决办法?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26489665

复制
相关文章
java中关于set()和get()方法的理解和使用
java中 当定义了一个私有的成员变量的时候,如果需要访问或者获取这个变量的时候,就可以编写set或者get方法去调用。
用户7886150
2020/12/07
4K0
详解JavaScript的get和set方法
一、get 方法 1、功能 get 关键字将对象属性与函数进行绑定,当属性被访问时,对应函数被执行。 // 语法一 {get prop() { ... } } // 语法二 {get [expression]() { ... } } 2、实例:语法一 const obj = { log: ['example','test'], get latest() { if (this.log.length == 0) return undefined; return this.log[thi
Learn-anything.cn
2021/12/21
4.3K0
用Lombok甩掉get()和set()
代码里面,见到的最多的就是实体Dao(Domain)了。这里的实体主要分为2种,一种是数据库访问层的实体Domain,直接用来定义某个数据库表的实体,里面定义的每个字段都跟数据库表中的每个字段一一对应。也是系统跟数据交互而用来存储数据的“介质”。另一种是代码里为了方便,把多个参数或变量定义为一个实体,一般用来:方法传参、接口对外对象、设计模式等。
程序大视界
2022/09/22
5190
用Lombok甩掉get()和set()
理解 class 用法和 get set 的使用
说明 了解 es6+ 的 class 的使用 了解其中 set 和 get 的使用情况 适用:es6+ 初学者 class es7 类的使用 一 class extends super class 声明创建一个基于原型继承的具有给定名称的新类。 你也可以使用类表达式定义类。但是不同于类表达式,类声明不允许再次声明已经存在的类,否则将会抛出一个类型错误。 申明一个类,Polygon, 然后 Square 来继承 Polygon,只能在构造函数中使用 super()。并且必须在使用 this 关键字前调
西南_张家辉
2021/02/02
6920
jquery当中如何Set和Get文本
例 1.3(SetGetinnerHtml.html) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> </TITLE> <script src="jquery.js"></script> <SCRIPT LANGUAGE="JavaScript"> <!-- function getHTML() {   /* $("#info").html(); 代码1是返回指定元素的innerHTML值; $("#info").html("mark"); 代码2则是将mark这串字符设置到指定元素中 */     var message = $("#info").html();     alert(message) } function setHTML() {       $("#info").html("马克"); } //--> </SCRIPT> </HEAD> <BODY> <div id="info">mark</div> <INPUT TYPE="BUTTON" ONCLICK="getHTML()" value="获取"> <INPUT TYPE="BUTTON" ONCLICK="setHTML()" value="设置"> </BODY> </HTML>
马克java社区
2021/02/01
8450
jquery当中如何Set和Get文本
PHP魔术方法之__set()和__get()
先来看一段代码: class Article{ //私有成员属性 private $title = '标题'; //受保护的成员属性 protected $author = '作者'; //公有成员属性 public $introduce = '简介'; } $article = new Article(); var_dump($article -> title); var_dump($article -> author); var_dump($arti
Marser
2018/06/25
1.1K0
TypeScript-继承和函数、函数声明和重载
🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗
杨不易呀
2023/09/28
3140
TypeScript-继承和函数、函数声明和重载
python的__get__、__set
内容:     描述符引导         摘要         定义和介绍         描述符协议         调用描述符         样例         Properties         函数和方法         静态方法和类方法 摘要     定义并展示如何调用描述符,展示自定义描述符和几个内置的python描述符,包括函数、属性、静态方法和类方法,通过给出一个Python的示例应用来展示描述符是如何工作的.     熟练掌握描述符不仅让你拥有python使用的额外技巧,并且可以加深对Python内部如何工作的理解,提升对程序设计的能力,而且体会到python的设计优雅之处 定义和介绍     一般来说,描述符是带有“绑定行为”的对象属性,它的属性访问已经被描述符协议中的方法覆盖了.这些方法是__get__(),__set__(),和__delete__().     如果一个对象定义了这些方法中的任何一个,它就是一个描述符.     默认的属相访问是从对象的字典中 get, set, 或者 delete 属性,;例如a.x的查找顺序是:     a.x -> a.__dict__['x'] -> type(a).__dict__['x'] -> type(a)的基类(不包括元类),如果查找的值是对象定义的描述方法之一,python可能会调用描述符方法来重载默认行为,     发生在这个查找环节的哪里取决于定义了哪些描述符方法     注意,只有在新式类中描述符才会起作用(新式类继承type或者object class)     描述符是强有力的通用协议,属性、方法、静态方法、类方法和super()背后使用的就是这个机制,描述符简化了底层的c代码,并为Python编程提供了一组灵活的新工具 描述符协议
py3study
2020/01/19
1.3K0
PHP中 对象自动调用的方法:__set()、__get()、__tostring()
 (1)__get($property_name):获取私有属性$name值时,此对象会自动调用该方法,将属性name值传给参数$property_name,通过这个方法的内部
shirayner
2018/08/10
2.6K0
Python中类的继承、多层继承和多继承
继承的语法为在类名后的小括号()中写入要继承的父类名,如果要继承多个类则中间用逗号分隔。
Python碎片公众号
2021/02/26
5.5K0
Python中类的继承、多层继承和多继承
js中set和map的区别_list和set
Map对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。构造函数Map可以接受一个数组作为参数。
全栈程序员站长
2022/10/04
3.1K0
JavaScript实现java中的|接口|继承|抽象类|继承|多态|对象|工厂模式|重写|重载|
//定一个接口方法, var Interface = function(name,methods){ if(arguments.length != 2){ throw new Error('this instance interface constructor arguments must be 2 length!'); } this.name = name ; this.methods = [] ; for(var i = 0,len = methods.length ; i <len ;
前朝楚水
2018/04/02
1.3K0
getparameter()_eclipse如何自动生成get和set方法
1.利用getParameter和getParameterValues方式获取数据 为了方便理解,我们新建一个regAction01.jsp页面(regAction01.jsp页面名称对应reg01.jsp中的form表单的action值)从reg01.jsp中获取提交过来的数据
全栈程序员站长
2022/10/29
8360
getparameter()_eclipse如何自动生成get和set方法
React Native set get 方法
就可以直接 model.testData = 'test'; 设置 console.log(model.testData); 获取
onety码生
2018/11/21
9150
通过PropertyDescriptor反映射调用set和get方法
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/10
5610
PHP魔术方法__get && __set
当我们试图获取一个不可达属性时(比如private),类会自动调用__get函数。
如梦初醒_-
2022/10/26
8500
java中重载和重写的区别
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
全栈程序员站长
2022/09/08
6880
myeclipse   set get带注释的方法
1:在myeclipse/eclisp中搜索找到org.eclipse.jdt.ui_*.jar(*是版本号)
用户1499526
2019/07/15
9980
Java中的多态(重载和重写)
方法重写与方法重载之间的关系:重载发生在同一个类内部的两个方法或多个方法。重写发生在父类和子类之间。
你的明明呐丶
2022/06/27
6000
Java中的多态(重载和重写)
点击加载更多

相似问题

重载coffeescript get set方法

23

关于PHP魔术方法__get和__set的继承

23

重载Set()和Get()的圆括号运算符

20

[] c++中get和set操作的操作符重载

23

类继承、复制构造函数和set/get函数

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文