Красиво сделать не получится. Но можно сделать так, чтобы хотя бы на тестах оно упало и показало, что нельзя так делать.
<?php
class Node
{
protected function func1() {
print "NODE PARENT; ";
}
}
class NodeA extends Node
{
public function FUNC2() {
print "NODE A; ";
}
// Используем метод родителя внутри этого класса
public function func1Overrided() {
print "From parent: " . parent::func1();
}
// Переопределяем метод так, чтобы его нельзя было использовать
protected function func1() {
throw new \Exception("Нельзя вызывать этот метод из NodeB");
}
}
class NodeB extends Node
{
// Функция инициализации
public function onInit(NodeA $a): void
{
// Сделал так, чтобы не мокать api )
(function (?NodeA $a) {
$a->FUNC2(); // Метод успешно вызывется так как он public
$a->func1(); // Метод теперь кидает исключение, использовать не получится
})($a);
}
}
$nodeA = new NodeA;
$nodeA->func1Overrided(); // Работает вызов метода funс1 из родителя
$nodeB = new NodeB;
$nodeB->onInit($nodeA); // Выдаёт ошибку, нельзя использовать метод func1 из класса NodeB
Но у меня для вас совет: старайтесь как можно меньше использовать наследование. Из моего опыта могу сказать, что всякий раз, когда я с помощью наследования пытаюсь решить хоть сколько-нибудь сложную задачу, постоянно вылазят такие подводные камни, что жить не хочется. Используйте композицию и интерфейсы, и вам не придётся заниматься подобной ерундой.
Вот минимально-инвазивное решение, которое позволит и наследование сохранить (если оно прям ну вот сильно надо), и решить проблему при помощи композиции, основанной на трейте.
<?php
// Делаем общий трейт для всех классов
trait Func1 {
private function func1() {
print "FUNC1; ";
}
}
class Node
{
// Включаем трейт
use Func1;
}
class NodeA extends Node
{
// Включаем трейт
use Func1;
public function FUNC2() {
print "FUNC 2 NODEA; ";
}
}
class NodeB extends Node
{
// Включаем трейт
use Func1;
// Функция инициализации
public function onInit(NodeA $a): void
{
// Добавить зависимость
(function (?NodeA $a) {
$a->FUNC2(); // Метод успешно вызывется так как он public
$a->func1(); // Метод использовать не получится, т.к. он private
})($a);
}
}
$nodeA = new NodeA;
$nodeB = new NodeB;
$nodeB->onInit($nodeA); // Выдаёт ошибку, нельзя использовать метод func1 из класса NodeB