How to declare a constructor in the parent class so that it is absent in the child classes. I rummaged in the docks, and somehow I could not answer my question. For example:

class A{ private function __construct(){ echo 'Only class A'; } } class B extends A{ //падает с ошибкой Call to private A::__construct() from invalid contex } $b = new B(); print_r(get_class_methods($b)); // нужен пустой array() 
  • If you put the question this way and do not accept the answer comrade @cheops, then the only way to get an empty array return by calling the get_class_methods () function on an instance of the child class and hiding the method of (any) parent from the heirs, do not declare the method (in particular the constructor) at all. Otherwise, you do not understand the inheritance in php. - uorypm

2 answers 2

The constructor should be declared private.

 <?php class A{ private function __construct(){ echo 'Only class A'; } } class B extends A{ function __construct(){} } $b = new B(); print_r(get_class_methods($b)); // пустой array() 
  • This is so logical. I did not bother to check myself, apparently due to late night. Thank you for not being too lazy to answer. - Alexandr Karpulix
  • @AlexandrKarpulix so you would mark the answer as correct - strangeqargo
  • @cheops But then I checked it again and found that in your example everything is not so smooth, because it requires declaring an empty constructor in the child class; I could do this without its privacy in the parent, simply by redefining the method. If the constructor is not declared, then php will fall with the error "PHP Fatal error: Call to private A :: __ construct () from invalid context" Therefore, there is still something to think about. In addition, I edited the question. I think I did it right and right. I still consider the question open. - Alexandr Karpulix
  • You asked about the designer, about it and edited it. In this example, the successor constructor (in php) replaces the private constructor of the parent class. You can easily fill it with functionality (including duplicating the actions of the parent / complementary parent) so that it performs the actions you need - strangeqargo
  • I will mark your question with an answer if I do not find another explanation. Thank you for your attention to the problem. I appreciate it very much. - Alexandr Karpulix

Inheritance in programming implies an extension of the functional, and not vice versa. Thus, during inheritance, we can add new properties and methods to the inheriting classes, but we cannot remove something defined in the ancestor class. The maximum that we can do is to define a method or property as private, as already written by @cheops , however this does not mean the private element will not be inherited, it will simply not be available for direct reference in the heir classes, but will be inherited in any case.

If you have a situation when you need to prohibit the inheritance of individual elements - this may mean one of two things: either the ancestor class is not correctly selected, or an error in designing the inheritance tree.

For completeness, it is worth noting that in some languages ​​individual elements may not be inherited, BUT, such elements of classes and their features during inheritance are determined by the language specification, they are constant for all classes in a given language, and this behavior cannot be controlled from code. As an example, I can give the lack of inheritance of static class elements in C #.

UPD: A constructor, like a destructor, is an infrastructural method and, despite what is defined in the class code, is not fully a method of this class, because it cannot be accessed through either the instance or the class itself. The only way to contact the constructor is with special language instructions for placing a new object. In different languages, the behavior of constructors when inheriting is different, for example, C # consistently calls the constructors of all base classes, so the child class may not have its own constructor. But in fact, the constructor is not inherited.

As for the comparison of inheritance, as the principle of the OOP with the inheritance in life, this is a common misconception, which is discussed with varying degrees of detail in any less serious book on the PLO. In general, in life you can find a lot of examples of inheritance, which cannot be reproduced by means of program inheritance, in different cases go out of the situation in different ways, for example, by defining a set of interfaces instead of an inheritance tree.

@strangeqargo

... You can add functions (there will be more functions in the inheriting class), but this does not mean that the heir will have more capabilities than the ancestor. if you inherit a car: vehicle, the car will be "more specific" than the vehicle and cannot swim / fly / teleport, although the vehicle can.

You are right, but only in part. Yes, in the base class we define only the перемещение method common for the whole transport, and this will be the very generalization without specifics you are talking about, BUT, when it comes to the actual movement of the object, we will need specifics how to drive, on what principle fly, what forces teleport. And in this case, to say that the class vehicle can more than car not entirely correct, yes, theoretically, it can do everything, but until the corresponding derived classes are created to implement this or that, or even all of the movement functions, it actually cannot . Moreover, this example should rather be attributed to the principle of polymorphism, since No one will forbid me to define a flight as one of the possible options for moving a car.

@Alexandr Karpulix

For example, soft clay. It has a property that helps to take its any form. All products from it are her direct heir, having the same chemical composition and, possibly, color. But her softness is available only in her parent class, the products are hard.

The softness in this case is a property and not a method, this is the difference. A piece of clay can be put in the oven and change this property, it will become hard, remaining the same piece of clay, as well as the unfired pot will remain soft as the source material, while remaining a specific clay product. Properties can determine the applicability of a particular object in a particular case, do not change the essence of the object. If the pot is intended for storing liquid, then it is not important whether it is soft or solid, it will fulfill its task. Again, in this case, you should not consider the pot as a derivative of clay. Clay, pot material. No one bothers to hollow out the same pot of wood. At the same time, it will cease to be clay, but it will remain a pot, which means the material is a property.

PS: I apologize for the lecture%)

  • one
    I would also add that this, in addition, will violate the Barbara Liskov principle of substitution - a clear sign that the class hierarchy is not built correctly. - Igor Karpenko 10:10
  • The constructor itself is a very specific case. In addition, inheritance in programming (and in life) implies a change (both expansion and contraction) of the functional. You can add functions (there will be more functions in the inheriting class), but this does not mean that the heir will have more capabilities than the ancestor. if you inherit a car: vehicle, the car will be "more specific" than the vehicle and cannot swim / fly / teleport, although the vehicle can. - strangeqargo
  • one
    Thank you so much for the clarification. I have already corrected something in the project. I myself thought, where in life you can find such a private property, and found it. For example, soft clay. It has a property that helps to take its any form. All products from it are her direct heir, having the same chemical composition and, possibly, color. But her softness is available only in her parent class, the products are hard. However, softness can and would be available to them, but for this you will need your own method. This is me to the fact that there may not necessarily be an "error in the design of the inheritance tree." - Alexandr Karpulix
  • one
    The php.net site states: Note: Constructors in parent classes are not automatically called if the descendant class is defined by its own constructor. To call a constructor declared in the? Parent class, call the parent :: __ construct () method inside the descendant class constructor. If the constructor is not defined in the descendant class, then it can be inherited from the parent class as a normal method (if it is not defined as private). I think it’s all due to the fact that if you don’t declare the constructor, you will attempt to call the constructor of the parent. - Alexandr Karpulix
  • one
    @strangeqargo ok, convinced that the designers are generally a separate topic, and almost all of them work in their own way, with their cockroaches. - rdorn