How to call function lmn() without touching class B from class A
class A extends B{
public function abc(){
return "abc";
}
...
}
class B{
public function xyz(){
return "xyz";
}
...
}
class C{
protected function lmn(){
return "lmn";
}
...
}
please guide me for this
You can make some kind of proxy class that extends from C and provides a public method for access:
class ProcyForC extends C {
public function getLmn() {
return $this->lmn();
}
}
echo (new ProxyForC())->getLmn();
Related
Suppose I have the following :
<?php
class Final extends Intermediate {
public function final_level() {
$this->low_level();
$this->inter_level();
}
}
class Intermediate extends Lib1 {
public function inter_level() {
$this->low_level();
}
}
class Lib1 {
public function low_level1();
public function low_level2();
}
class Lib2 {
public function low_level1();
public function low_level2();
}
I would like to change the Intermediate class to extend Lib1 or Lib2, depending on some conditions, without duplicating Intermediate and Final code content.
All low_level functions are the same for both Lib.
In the end, I would like to have a Final1 class that use Lib1 (and Final2 that use Lib2).
How could I achieve this ?
You cannot achieve this via inheritance but you can via delegation
With this approach you delegate the implementation of some methods to a 'delegate' object rather than a base class.
Here it is an example:
<?php
class Final extends Intermediate {
public function __construct(Lib delegate) {
parent::__construct(delegate);
}
public function final_level() {
$this->low_level();
$this->inter_level();
}
}
class Intermediate implements Lib { //here you implement an interface rather than extending a class
private Lib delegate;
public function __construct(Lib delegate) {
$this->delegate = delegate;
}
public function inter_level() {
$this->low_level();
}
public function low_level() {
//delegate!
$this->delegate->low_level();
}
}
class Lib1 implements Lib{
public function low_level(); //implementation #1
}
class Lib2 implements Lib {
public function low_level(); //implementation #2
}
interface Lib {
public function low_level();
}
now you can create your final1 and final2 object in this way:
$final1 = new Final(new Lib1());
$final2 = new Final(new Lib2());
or, if you prefer, you can create the Final1 and Final2 classes extending from Final:
class Final1 extends Final {
public function __construct()
{
parent::__construct(new Lib1());
}
}
class Final2 extends Final {
public function __construct()
{
parent::__construct(new Lib2());
}
}
$final1 = new Final1();
$final2 = new Final2();
I have an abstract class, in which I want to call method, from a class that is declared in the child (extending) class. An example looks like this:
The abstract class:
abstract class NumberGenerator
{
protected function generate($input){
return MyClass::MyMethod($input);
}
}
My child/extending class:
use TomsFolder\MyClass;
use MyFolder\NumberGenerator;
class TomsNumberGenerator extends NumberGenerator
{
public function generate(string $applicantId): string
{
return $this->generate();
}
}
Another child/extending class:
use DavesFolder\MyClass;
use MyFolder\NumberGenerator;
class DavesNumberGenerator extends NumberGenerator
{
public function generate(string $applicantId): string
{
return $this->generate();
}
}
So I want to call MyClass::MyMethod in NumberGenerator. However it is only imported in TomsNumberGenerator.
The reason I want to do it like is because, I have classes like DavesNumberGenerator which calls a different MyClass.
When I try this, I get 'MyClass is not found in NumberGenerator'. Is there any way to make this work?
Try putting the namespace use statement before the actual class:
NumberGenerator.php
use MyFolder\MyClass;
abstract class NumberGenerator
{
protected function generate($input){
return MyClass::MyMethod($input);
}
}
EDIT
Try this:
NumberGenerator.php
abstract class NumberGenerator
{
protected function generate($class_name, $input){
return call_user_func($class_name . '::MyMethod', $input);
}
}
TomsNumberGenerator.php
use TomsFolder\MyClass;
use MyFolder\NumberGenerator;
class TomsNumberGenerator extends NumberGenerator
{
public function generate(string $applicantId): string
{
return $this->generate(get_class(new MyClass()), $applicantId);
}
}
You have to use interface for this.
You can do the following
Create MyClassInterface
interface MyClassInterface {
public function MyMethod();
}
Implement this interface in some classes
class MyClass1 implements MyClassInterface {
public function MyMethod() {
// implementation
}
}
class MyClass2 implements MyClassInterface {
public function MyMethod() {
// implementation 2
}
}
Add abstract method to NumberGenerator
abstract class NumberGenerator {
abstract protected function GetMyClass(): MyClassInterface;
protected function generate($input){
return $this->GetMyClass()->MyMethod($input);
}
}
Implement GetMyClass function inside child classes
class TomsNumberGenerator extends NumberGenerator
{
protected function GetMyClass(): MyClassInterface {
return new MyClass1();
}
}
class DavesNumberGenerator extends NumberGenerator
{
protected function GetMyClass(): MyClassInterface {
return new MyClass2();
}
}
PS If you want to use static, you can change abstract inside NumberGenerator class, to change string. In this case, your generate will look like this:
protected function generate($input){
return call_user_func($this->GetMyClass() . '::MyMethod', [$input]);
}
I am very new to OOP. And i've read that a derived class can access the public and protected members of base class.
A.php
<?php
namespace App\Http\Controllers;
class A extends Controller
{
public $x=5;
public function index()
{...}
}
and B.php
<?php
namespace App\Http\Controllers;
class B extends A
{
public function index()
{
print_r($x);
}
}
why is $x not accessed from derived class?
I have this route:
Route::get('/B/index','B#index');
I got the error:
undefined variable x.
Make the following changes in your code:
class B extends A
{
public function get()
{
echo $this->x; // will echo the value in variable $x;
}
}
$obj = new B;
$obj->get();
Please change code as bellow. it will show result.
class A
{
public $x=5; //or protected $x=5;
public function index()
{
echo "A";
}
}
class B extends A
{
public function index()
{
echo $this->x;
}
}
$classB = new B();
$classB->index();
you can use :http://phptester.net/ to test online
I Hope help you
How do you access a child method eg.?
class A
{
public function Start()
{
// Somehow call Run method on the B class that is inheriting this class
}
}
class B extends A
{
public function Run()
{
...
}
}
$b = new B();
$b->Start(); // Which then should call Run method
Class A should not try to call any methods that it itself does not define. This will work just fine for your scenario:
class A {
public function Start() {
$this->Run();
}
}
However, it will fail terribly should you actually do this:
$a = new A;
$a->Start();
What you're trying to do here sounds very much like a use case for abstract classes:
abstract class A {
public function Start() {
$this->Run();
}
abstract function Run();
}
class B extends A {
public function Run() {
...
}
}
The abstract declaration will precisely prevent you from shooting your own foot by trying to instantiate and Start A without extending and defining required methods.
If B is inherited from A then B will be like:
class B extends A
{
public function Start()
{
...
}
public function Run()
{
...
}
}
So as Run() and Start() are in the same class, we can call Run() in Start() directly.
public function Start()
{
Run();
}
I have a base class A:
class A {
public static function a() {
...
}
public static function b() {
...
}
}
and an extended class B
class B extends A {
public static function a() {
...
}
public static function c() {
...
}
}
I would like to be able to call all the methods using B::
How would I call A::b, using B::?
You should be able to accomplish this as easily as:
class B extends A {
public static function a() {
parent::a();
}
}
See the docs