【问题标题】:Accessing methods from children class in PHP object从 PHP 对象中的子类访问方法
【发布时间】:2013-12-03 12:37:44
【问题描述】:

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

一些代码:

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());
    }

谢谢。

【问题讨论】:

  • 是否有任何代码显示您尝试访问此方法的方式?
  • 请给我们看一个最小的代码示例。
  • 你能发布一些例子吗?另外,php.net/manual/en/language.oop5.traits.php 浮现在脑海中。
  • 请稍等,我发现了其他可能导致问题的原因。对不起这是我的错。无论如何,@GolezTrol,如果您发表评论,我会选择它,如果它真的像那样工作,因为它回答了我担心的根源。谢谢大家。
  • 我已经做到了,给出的答案描述了方法调用与继承在 PHP 中的工作方式。我希望它已经足够并且可以帮助您找到您的问题,因为坦率地说,我无法通过您发布的代码 sn-p 来判断问题到底是什么。

标签: php class inheritance methods


【解决方案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);

【讨论】:

    【解决方案2】:

    在普通的面向对象继承中,您所要求的不是预期的,但显然在 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,那么当代码完全死掉时,请求 A 被认为是非常糟糕的编程习惯。你应该真正避免这种情况。

    【讨论】:

    • 这不是真的。一般来说,当你调用一个存在于 A 中并在 B 中被覆盖的方法时,应该调用被覆盖的方法。如果你试图调用一个只存在于 B 中的方法,PHP 只会调用它。只要它包含方法,它就不会关心你传递了什么。类型提示只是在调用函数时检查基本类型,但在代码中没有进一步使用(不幸的是)。最重要的是,如果你调用一个不存在的方法,PHP 会抛出一个错误而不是返回 null。
    • 你的第一句话是正确的,但无关紧要;他没有压倒一个方法。关于另外两个;有可能他的错误以某种方式被抑制(@?),因为我们没有我们不知道的最少代码。但一般来说,对于 OOP,这样的调用不应该返回,yes 应该抛出错误。
    • 那么,它是否像@GolezTrol 在第二句话中所说的那样有效?
    • 确实如此;显然 PHP 类检查很松散!上面的示例程序表明您所描述的确实有效。 @GolezTroi 是正确的,如果他发表回复,我肯定会投票。
    猜你喜欢
    • 2015-12-28
    • 2019-03-16
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    相关资源
    最近更新 更多