我有一个(抽象的)父类应该在构造期间提供功能。子类可以覆盖构造函数中使用的属性:
class Parent extends MiddlewareTest
{
// abstract channel properties
protected $title = NULL;
protected $type = NULL;
protected $resolution = NULL;
function __construct() {
parent::__construct();
$this->uuid = $this->createChannel($this->title, $this->type, $this->resolution);
}
}
class Child extends Parent
{
// channel properties
protected $title = 'Power';
protected $type = 'power';
protected $resolution = 1000;
}
问题是当未被覆盖的 Child::__construct() 运行时($this->createChannel 被 调用时,未使用被覆盖的属性NULL 参数)。
这在 PHP 中可行吗?还是我每次都必须求助于覆盖子构造函数来提供所需的功能?
注意:我看到了Properties shared between child and parents class in php但这是不同的,因为子属性不是在构造函数中分配的,而是根据定义分配的。
更新
事实证明我的测试用例有问题。由于 MiddlewareTest 基于 SimpleTest 单元测试用例,SimpleTest 实际上 - 我没有意识到 - 通过它的自动运行实例化了 Parent 类本身,这并不是故意的。通过使 Parent 类抽象化来修复。
经验教训:构建一个干净的测试用例,并在求助之前实际运行它。
最佳答案
我不确定您的服务器上发生了什么。我不得不对 MiddlewareTest 类做出假设,修改您的类名,并添加一些简单的调试行,但使用以下代码:
<?php
/**
* I'm not sure what you have in this class.
* Perhaps the problem lies here on your side.
* Is this constructor doing something to nullify those properties?
* Are those properties also defined in this class?
*/
abstract class MiddlewareTest {
// I assume this properties are also defined here
protected $title = NULL;
protected $type = NULL;
protected $resolution = NULL;
protected $uuid = NULL;
public function __construct()
{}
protected function createChannel($title, $type, $resolution)
{
echo "<pre>" . __LINE__ . ": "; var_export(array($this->title, $this->type, $this->resolution)); echo "</pre>";
echo "<pre>" . __LINE__ . ": "; var_export(array($title, $type, $resolution)); echo "</pre>";
return var_export(array($title, $type, $resolution), true);
}
}
// 'parent' is a keyword, so let's just use A and B
class A extends MiddlewareTest
{
// abstract channel properties
protected $title = NULL;
protected $type = NULL;
protected $resolution = NULL;
function __construct() {
parent::__construct();
echo "<pre>" . __LINE__ . ": "; var_export(array($this->title, $this->type, $this->resolution)); echo "</pre>";
$this->uuid = $this->createChannel($this->title, $this->type, $this->resolution);
echo "<pre>" . __LINE__ . ": "; var_export($this->uuid); echo "</pre>";
}
}
class B extends A
{
// channel properties
protected $title = "Power";
protected $type = "power";
protected $resolution = 1000;
}
$B = new B();
?>
我得到这些结果:
37: array (
0 => 'Power',
1 => 'power',
2 => 1000,
)
20: array (
0 => 'Power',
1 => 'power',
2 => 1000,
)
21: array (
0 => 'Power',
1 => 'power',
2 => 1000,
)
39: 'array (
0 => \'Power\',
1 => \'power\',
2 => 1000,
)'
正如您所看到的,结果是按照它们在实例化类中定义的方式传入的值,正如预期的那样。
您能否提供有关您的 MiddlewareTest 类的一些详细信息,这可能会阐明您可能遇到此行为的原因?
你运行的是什么版本的 php?
关于PHP 继承 : child class overriding parent variable/property for use in constructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17998683/
在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型
所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass
我正在使用带有单个“帐户”表的STI模型来保存用户和技术人员的信息(即用户...8)错误:test_the_truth(用户测试):ActiveRecord::StatementInvalid:PGError:ERROR:关系“技术人员”不存在:从“技术人员”中删除...从本质上讲,标准框架不承认Technicians和Users表(或PostgreSQL称它们为“关系”)不存在,事实上,应该别名为Accounts。有什么想法吗?我对RoR比较陌生,不知道如何解决这个问题而又不完全删除STI。 最佳答案 原来问题是由于存在:./te
假设我有一个名为Flight的模块,其中包含类方法和实例方法。我可以使用include、extend或两者将其方法放入类中:classBatinclude会将Flight添加到Bat.ancestors,但extend不会。我的问题是,为什么模块与类不同?当我对Mammal进行子类化时,我总是同时获得类和实例方法。然而,当我混入一个模块时,我不能同时获得类和实例方法(除非我使用self.included钩子(Hook)或类似ActiveSupport::Concern的东西)。这种差异背后是否存在语言设计问题? 最佳答案 Modul
在Ruby(1.8.X)中为什么Object既继承了内核又包含了内核?仅仅继承还不够吗?irb(main):006:0>Object.ancestors=>[Object,Kernel]irb(main):005:0>Object.included_modules=>[Kernel]irb(main):011:0>Object.superclass=>nil请注意,在Ruby1.9中情况类似(但更简洁):irb(main):001:0>Object.ancestors=>[Object,Kernel,BasicObject]irb(main):002:0>Object.included
我正在为Rails创建我的第一个插件。我对ruby还是很陌生,我想知道是否有可能获得继承类?例如,我正在尝试创建一个插件,在您不使用迁移时允许进行单元测试和功能测试。我要做的是初始化一个名为controller的类变量,以初始化为正在测试的Controller类型。如果我有一个基类ControllerTest:classControllerTest所以我目前坚持的是获取继承类的名称。这可能吗?如果没有,有没有人知道我可以如何着手实现它的另一种方式?提前致谢。 最佳答案 非常简单:使用“继承”回调。来自Class类的RDoc:in
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
Object#is_a?在Rails3中以最奇怪的方式失败。我将单表继承设置如下(为简洁起见进行了简化):#resource.rbclassResource在我的Controller中,我有这个:defcreate@resource=Resource.findparams[:resource_id]logger.info'@resourceclass:'+@resource.class.namelogger.info'@resourcesuperclass:'+@resource.class.superclass.namelogger.info'@resourceis_a?(Video
我正在为我未构建的应用程序编写Controller测试,因此这绝对是一个学习过程。这是我第一次遇到直接继承自AbstractController::Base的Controller。显然,它的行为与其他Controller不同。其格式大致为:classSchwadGenericController我尝试了正常测试,这是我目前要让任何事情发生的地方。require'rails_helper'describeSchwadGenericControllerdo#before(:each)do#SchwadGenericController.skip_authorize_resource#end
例如,我可以很容易地继承自String,如下所示:classMyString'thingsandstuff'但是我如何继承没有构造函数的Rational呢?例如:defMyRatNoMethodError:undefinedmethod`new'forMyRat:ClassMyRat(10).inc#=>NoMethodError:undefinedmethod`MyRat'formain:ObjectMyRat.send(:initialize,10).inc#=>TypeError:alreadyinitializedclass#???#Noneofitworks!我找不到初始化新