PHP - 继承

Dan*_*nar 1 php oop inheritance

我目前正在学习OOP概念.我使用过CodeIgniter,我知道它有OOP概念,但我不明白它是如何工作的.我只是使用文档中的方法.

我现在在继承部分.

这是我的代码:

<?php

class Artist {
    public $name;
    public $genre;
    public $test = 'This is a test string';

    public function __construct(string $name, string $genre) {
        $this->name = $name;
        $this->genre = $genre;
    }
}

class Song extends Artist {
    public $title;
    public $album;

    public function __construct(string $title, string $album) {
        $this->title = $title;
        $this->album = $album;
    }

    public function getSongArtist() {
        return $this->name;
    }
}

$artist = new Artist('Joji Miller', 'Lo-Fi');
$song = new Song('Demons', 'In Tounges');

echo $song->getSongArtist(); // returns nothing
Run Code Online (Sandbox Code Playgroud)

据我所知,继承将让我从父类访问属性和方法.

在我的例子中,我实例化了艺术家.所以现在我有Joji Miller作为艺术家的名字.

现在,如果我实例化Song类,我认为我可以访问艺术家名称,因为我正在扩展Artist类.但它只是空洞的.

你能帮我理解为什么它没有得到艺术家的名字吗?

希望我能清楚地解释自己.谢谢..

ter*_*ško 9

嘿.从CodeIgniter学习"oop原则"就像去朝鲜学习民主一样.你已经学会了错误的东西.

extends关键字应该被理解为"是特例".正如class Admin extends User意味着,管理实体是一般用户更专业的情况.

那就是你错了.歌曲不是艺术家的子类型.

相反,这首歌有一位执行它的艺术家.如:

$artist = new Artist('Freddie Mercury');
$song = new Song('Another One Bites the Dust', $artist);

echo $song->getArtist()->getName();
Run Code Online (Sandbox Code Playgroud)

另一个不好的做法,你似乎已经选择了:停止将类变量定义为public.这打破了封装.相反,应使用方法分配这些值,因为这样您就可以进行顶级跟踪,格式化和验证这些值.


Vla*_*pak 5

首先,在你的情况下,你没有最好的继承的例子......它会导致混乱......

我宁愿建议你有与所有后代相关的基类行为,就像这里一样.
基类:

<?php

class SomethingWithName
{
    private $name;
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    public function getName(): string
    {
        return $this->name;
    }
}
Run Code Online (Sandbox Code Playgroud)

你的课程:

class Artist extends SomethingWithName
{
    private $genre;
    public function __construct(string $name, string $genre)
    {
        parent::__construct($name);
        $this->genre = $genre;
    }
    public function getGenre(): string
    {
        return $this->genre;
    }
}

class Song extends SomethingWithName
{
    private $album;
    private $artist;
    public function __construct(string $name, string $album, Artist $artist)
    {
        parent::__construct($name);
        $this->album = $album;
        $this->artist = $artist;
    }
    public function getAlbum(): string
    {
        return $this->album;
    }
    public function getArtist(): Artist
    {
        return $this->artist;
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

$a = new Artist('Joji Miller', 'Lo-Fi');
$s = new Song('Demons', 'In Tounges', $a);
var_export([
    $s->getName(), // Demons
    $s->getAlbum(), // In Tounges
    $s->getArtist()->getName(), // Joji Miller
    $s->getArtist()->getGenre(), // Lo-Fi
]);
Run Code Online (Sandbox Code Playgroud)