Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class overrides a field of a parent class #1944

Open
Simbiat opened this issue May 1, 2024 · 0 comments
Open

Class overrides a field of a parent class #1944

Simbiat opened this issue May 1, 2024 · 0 comments

Comments

@Simbiat
Copy link

Simbiat commented May 1, 2024

Subject Details
Plugin Php Inspections (EA Extended)
Language level PHP 8.3

Question

I have an abstract class like this (a bit simplified to remove all the fluff)

<?php
declare(strict_types = 1);

namespace Simbiat\Abstracts;

abstract class Page
{
    #Current breadcrumb for navigation
    protected array $breadCrumb = [];
    #Sub service name
    protected string $subServiceName = '';
    #Time of last data modification (defaults to current time on initialization)
    protected int $lastModified = 0;

    public final function __construct()
    {
        #Check that subclass has set appropriate properties
        foreach (['subServiceName', 'breadCrumb'] as $property) {
            if(empty($this->{$property})) {
                throw new \LogicException(get_class($this) . ' must have a non-empty `'.$property.'` property.');
            }
        }
        #Set last modified data
        $this->lastModified = time();
    }

        #Generation of the page data
        abstract protected function generate(array $path): array;

I then have a child class like this:

<?php
declare(strict_types = 1);

namespace Simbiat\usercontrol\Pages;

/**
 * Page to unsubscribe email addresses from messages
 */
class Unsubscribe extends Page
{
    #Current breadcrumb for navigation
    protected array $breadCrumb = [
        ['href' => '/uc/unsubscribe', 'name' => 'Unsubscribe']
    ];
    #Sub service name
    protected string $subServiceName = 'unsubscribe';
    
    /**
     * Actual page generation based on further details of the $path
     * @param array $path URL path
     *
     * @return array
     */
    protected function generate(array $path): array
    {
        #Doing stuff, not relevant to the main question
        $outputArray = [];
        return $outputArray;
    }
}

In child class fields $breadCrumb and $subServiceName are highlighted with Class overrides a field of a parent class warning. Based on documentation for the warning I have a few options:

  1. Rename property. Can't do that, that because they are used in a bunch of functions in the abstract class
  2. Move property initialization into the constructor. Can't do that, since my constructor is final, and I can't override it. Setting up the fields in the final constructor is also not an option, because then I would need to carry the values of respective fields as arguments anywhere the child class is initialized. And my goal is to have those expected values in the respective child class itself. Kind of like customization of defaults, I guess.
  3. use @property annotation to re-define type-hints. Not sure if this makes sense even, since I only need to override the value, but I tried adding @property array $breadCrumb to child class PHPDoc (under class description), and it did not do anything.

Am I doing something wrong or am I missing something? Is there a better way? Abstract class is meant to define the structure and basic functionality of the page entities, and then each child class is supposed to implement all of them without changes, but override default values of some attributes (when needed) and implement a custom generation logic. Is there a better way to do that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant