从PHP对象中的子类访问方法

时间:2013-11-19 19:29:34

标签: php class inheritance methods

我有两个A和B类,其中B扩展A并添加一些方法。我有一个C类,其方法接受A作为参数以进行泛化。问题是,一旦进入方法,我想访问对象上的类B的方法,但我无法这样做。当我转储对象并知道它保存数据时,不要得到错误,但在返回时返回null。 对不起,如果它看起来很荒谬,但我正在尝试使用你期望在正常继承中使用的bahaviour。也许是我错过了什么,这是我的错,但不知道这里发生了什么。 如果你知道怎么做,请帮助我。

一些代码:

public function createProject(AssociatedProjectInterface $project_data){
        if(!is_a($project_data, 'class\path\GithubProject')){
            throw new InvalidArgumentException('The argument needs to be of type: GithubProject.');
        }


        $repo = $this->client->api('repo')->create(
            $project_data->getTitle(),
            $project_data->getDescription(),
            null,
            !$project_data->getIsPrivate(),
            null,
            $project_data->getIssuesEnabled(),
            $project_data->getWikiEnabled());
    }

感谢。

2 个答案:

答案 0 :(得分:1)

请注意,PHP的类型检查非常松散。它调用传递的类的方法。类型检查仅在调用函数时进行。因此,在下面的示例中,testType必须经过A类型的对象或A的后代。在初始检查之后,根本没有进行类型检查!因此该函数可以调用在A或B中声明的任何方法。如果在两者中声明了一个方法,则认为它被覆盖并且使用了B中的版本。

<?php

class A {
  function foo() {
    echo 'A:foo';
  }
}

class B extends A {
  function foo() {
    echo 'B:foo';
  }

  function bar() {
    echo 'B:bar';
  }
}

function testType(A $a)
{
  $a->foo(); // B:foo
  $a->bar(); // B:bar <- This will succeed even though there's no bar() in A.
}

$a = new B();
testType($a);

答案 1 :(得分:-1)

在正常的面向对象的继承中不期望您所要求的,但显然在PHP中有效。通常,如果方法需要类A的对象,则可以传递扩展A的类B的对象,但该方法将该对象视为类A的。这意味着当您调用B固有的方法时,您正在调用不存在的方法,并且应该抛出错误。

在PHP中,妈妈不在乎。作为证据,运行以下最小测试:

<?php

class A {
  public function foo() {
    echo "in foo\n";
  }
}

class B extends A {
  public function bar() {
    echo "in bar\n";
  }
}

class C {
  public function test(A $b) {
    $b->foo();//works, because foo exists in the A class definition
    $b->bar();//also works for B, but not A
  }
}

$a = new A();
$b = new B();
$c = new C();
$c->test($b);
$c->test($a);//Will throw an error because the method bar() is not found

请注意,如果代码在需要B的情况下完全死亡,那么它被认为是非常糟糕的编程习惯。你应该真的避免这种情况。