Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.php > #2150 > unrolled thread
| Started by | sheldonlg <sheldonlg@thevillages.net> |
|---|---|
| First post | 2011-06-14 12:49 -0400 |
| Last post | 2011-06-15 14:01 +0200 |
| Articles | 15 — 5 participants |
Back to article view | Back to comp.lang.php
An overloading question sheldonlg <sheldonlg@thevillages.net> - 2011-06-14 12:49 -0400
Re: An overloading question Denis McMahon <denis.m.f.mcmahon@gmail.com> - 2011-06-14 18:32 +0000
Re: An overloading question sheldonlg <sheldonlg@thevillages.net> - 2011-06-14 18:27 -0400
Re: An overloading question Jerry Stuckle <jstucklex@attglobal.net> - 2011-06-14 19:12 -0400
Re: An overloading question sheldonlg <sheldonlg@thevillages.net> - 2011-06-14 19:43 -0400
Re: An overloading question Jerry Stuckle <jstucklex@attglobal.net> - 2011-06-14 20:45 -0400
Re: An overloading question sheldonlg <sheldonlg@thevillages.net> - 2011-06-14 21:58 -0400
Re: An overloading question Jerry Stuckle <jstucklex@attglobal.net> - 2011-06-14 22:08 -0400
Re: An overloading question Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-06-15 14:21 +0200
Re: An overloading question sheldonlg <sheldonlg@thevillages.net> - 2011-06-15 12:55 -0400
Re: An overloading question Michael Fesser <netizen@gmx.de> - 2011-06-15 18:04 +0200
Re: An overloading question Jerry Stuckle <jstucklex@attglobal.net> - 2011-06-15 12:53 -0400
Re: An overloading question Denis McMahon <denis.m.f.mcmahon@gmail.com> - 2011-06-15 03:41 +0000
Re: An overloading question Michael Fesser <netizen@gmx.de> - 2011-06-15 18:02 +0200
Re: An overloading question Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-06-15 14:01 +0200
| From | sheldonlg <sheldonlg@thevillages.net> |
|---|---|
| Date | 2011-06-14 12:49 -0400 |
| Subject | An overloading question |
| Message-ID | <it83e6$u4e$1@dont-email.me> |
I have a problem that I am wrestling with that should be so obvious and
easy -- but it isn't. I have a base class that has a method that calls
another method in the base class with $this->thatOtherMethod. I have
another class that extends the base class and I want to have
thatOtherMethod in the extended class override the one in the base
class. The calling method in the base class is called using and
instance of the extended class pointing to that method.
Simply, here is an example:
A.class.php
--------------------------
<?php
abstract class A {
public function b() {
$this->a();
}
protected function a() {
print 'In class A';
}
}
?>
B.class.php
---------------------------
<?php
include_once 'A.class.php';
class B extends A {
public function a() {
print 'In class B';
}
}
?>
c.php
----------------------------
<?php
include 'B.class.php';
$x = new B();
$x->b();
?>
----------------------------
I want it to print out "In class B", but it prints out "In class A".
I have looked over Google quite a bit and found nothing that helped. I
have tried making the methods public, protected, keep them both the same
access, etc. and have had no luck. Suggestions?
--
Shelly
[toc] | [next] | [standalone]
| From | Denis McMahon <denis.m.f.mcmahon@gmail.com> |
|---|---|
| Date | 2011-06-14 18:32 +0000 |
| Message-ID | <4df7a92f$0$12468$bed64819@gradwell.net> |
| In reply to | #2150 |
On Tue, 14 Jun 2011 12:49:11 -0400, sheldonlg wrote:
> I have a problem that I am wrestling with that should be so obvious and
> easy -- but it isn't. I have a base class that has a method that calls
> another method in the base class with $this->thatOtherMethod. I have
> another class that extends the base class and I want to have
> thatOtherMethod in the extended class override the one in the base
> class. The calling method in the base class is called using and
> instance of the extended class pointing to that method.
>
> Simply, here is an example:
>
> A.class.php
> --------------------------
> <?php
> abstract class A {
> public function b() {
> $this->a();
> }
> protected function a() {
> print 'In class A';
> }
> }
> ?>
>
> B.class.php
> ---------------------------
> <?php
> include_once 'A.class.php';
> class B extends A {
> public function a() {
> print 'In class B';
> }
> }
> ?>
>
> c.php
> ----------------------------
> <?php
> include 'B.class.php';
> $x = new B();
> $x->b();
> ?>
> ----------------------------
>
> I want it to print out "In class B", but it prints out "In class A".
>
> I have looked over Google quite a bit and found nothing that helped. I
> have tried making the methods public, protected, keep them both the same
> access, etc. and have had no luck. Suggestions?
I think A->a() is being used as a constructor for the base class when you
instantiate the extended class.
This might (or might not) be causing confusion as to what's happening.
This code:
<?php
abstract class A {
public function x() {
print "x() In class A\n";
$this->y();
}
public function y() {
print "y() In class A\n";
}
public function a() {
print "a() In class A\n";
}
}
class B extends A {
public function y() {
print "y() In class B\n";
}
}
print "instantiate\n";
$x = new B();
print "call function\n";
$x->x();
?>
gives:
instantiate
a() In class A
call function
x() In class A
y() In class B
Not sure, though, if that solves your problem or not?
Rgds
Denis McMahon
[toc] | [prev] | [next] | [standalone]
| From | sheldonlg <sheldonlg@thevillages.net> |
|---|---|
| Date | 2011-06-14 18:27 -0400 |
| Message-ID | <it8n87$7rj$1@dont-email.me> |
| In reply to | #2153 |
On 6/14/2011 2:32 PM, Denis McMahon wrote:
> On Tue, 14 Jun 2011 12:49:11 -0400, sheldonlg wrote:
>
>> I have a problem that I am wrestling with that should be so obvious and
>> easy -- but it isn't. I have a base class that has a method that calls
>> another method in the base class with $this->thatOtherMethod. I have
>> another class that extends the base class and I want to have
>> thatOtherMethod in the extended class override the one in the base
>> class. The calling method in the base class is called using and
>> instance of the extended class pointing to that method.
>>
>> Simply, here is an example:
>>
>> A.class.php
>> --------------------------
>> <?php
>> abstract class A {
>> public function b() {
>> $this->a();
>> }
>> protected function a() {
>> print 'In class A';
>> }
>> }
>> ?>
>>
>> B.class.php
>> ---------------------------
>> <?php
>> include_once 'A.class.php';
>> class B extends A {
>> public function a() {
>> print 'In class B';
>> }
>> }
>> ?>
>>
>> c.php
>> ----------------------------
>> <?php
>> include 'B.class.php';
>> $x = new B();
>> $x->b();
>> ?>
>> ----------------------------
>>
>> I want it to print out "In class B", but it prints out "In class A".
>>
>> I have looked over Google quite a bit and found nothing that helped. I
>> have tried making the methods public, protected, keep them both the same
>> access, etc. and have had no luck. Suggestions?
>
> I think A->a() is being used as a constructor for the base class when you
> instantiate the extended class.
>
> This might (or might not) be causing confusion as to what's happening.
>
> This code:
>
> <?php
>
> abstract class A {
>
> public function x() {
> print "x() In class A\n";
> $this->y();
> }
>
> public function y() {
> print "y() In class A\n";
> }
>
> public function a() {
> print "a() In class A\n";
> }
>
> }
>
> class B extends A {
>
> public function y() {
> print "y() In class B\n";
> }
>
> }
>
> print "instantiate\n";
>
> $x = new B();
>
> print "call function\n";
>
> $x->x();
>
> ?>
>
> gives:
>
> instantiate
> a() In class A
> call function
> x() In class A
> y() In class B
>
> Not sure, though, if that solves your problem or not?
>
> Rgds
>
> Denis McMahon
I modified B to give it an explicit constructor. It still didn't work.
Why did your example print out that last line. It was never called.
Why did it use it as a constructor? That doesn't seem to make sense.
--
Shelly
[toc] | [prev] | [next] | [standalone]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2011-06-14 19:12 -0400 |
| Message-ID | <it8ps7$su3$1@dont-email.me> |
| In reply to | #2162 |
On 6/14/2011 6:27 PM, sheldonlg wrote:
> On 6/14/2011 2:32 PM, Denis McMahon wrote:
>> On Tue, 14 Jun 2011 12:49:11 -0400, sheldonlg wrote:
>>
>>> I have a problem that I am wrestling with that should be so obvious and
>>> easy -- but it isn't. I have a base class that has a method that calls
>>> another method in the base class with $this->thatOtherMethod. I have
>>> another class that extends the base class and I want to have
>>> thatOtherMethod in the extended class override the one in the base
>>> class. The calling method in the base class is called using and
>>> instance of the extended class pointing to that method.
>>>
>>> Simply, here is an example:
>>>
>>> A.class.php
>>> --------------------------
>>> <?php
>>> abstract class A {
>>> public function b() {
>>> $this->a();
>>> }
>>> protected function a() {
>>> print 'In class A';
>>> }
>>> }
>>> ?>
>>>
>>> B.class.php
>>> ---------------------------
>>> <?php
>>> include_once 'A.class.php';
>>> class B extends A {
>>> public function a() {
>>> print 'In class B';
>>> }
>>> }
>>> ?>
>>>
>>> c.php
>>> ----------------------------
>>> <?php
>>> include 'B.class.php';
>>> $x = new B();
>>> $x->b();
>>> ?>
>>> ----------------------------
>>>
>>> I want it to print out "In class B", but it prints out "In class A".
>>>
>>> I have looked over Google quite a bit and found nothing that helped. I
>>> have tried making the methods public, protected, keep them both the same
>>> access, etc. and have had no luck. Suggestions?
>>
>> I think A->a() is being used as a constructor for the base class when you
>> instantiate the extended class.
>>
>> This might (or might not) be causing confusion as to what's happening.
>>
>> This code:
>>
>> <?php
>>
>> abstract class A {
>>
>> public function x() {
>> print "x() In class A\n";
>> $this->y();
>> }
>>
>> public function y() {
>> print "y() In class A\n";
>> }
>>
>> public function a() {
>> print "a() In class A\n";
>> }
>>
>> }
>>
>> class B extends A {
>>
>> public function y() {
>> print "y() In class B\n";
>> }
>>
>> }
>>
>> print "instantiate\n";
>>
>> $x = new B();
>>
>> print "call function\n";
>>
>> $x->x();
>>
>> ?>
>>
>> gives:
>>
>> instantiate
>> a() In class A
>> call function
>> x() In class A
>> y() In class B
>>
>> Not sure, though, if that solves your problem or not?
>>
>> Rgds
>>
>> Denis McMahon
>
> I modified B to give it an explicit constructor. It still didn't work.
> Why did your example print out that last line. It was never called. Why
> did it use it as a constructor? That doesn't seem to make sense.
>
Unfortunately, PHP doesn't really implement OO constructs very well - in
fact they to a pretty piss poor job of it. One of the problems is with
virtual functions, as you found. A good OO language would work like you
want, but PHP doesn't - the constructor for A will, in this case, only
call a function in A. In C++, Smalltalk, Java and most other OO
languages, you could define y() as virtual and the constructor for A
would call the function y() in B.
But if you created a constructor in B properly, it should call B:y().
I'd suggest checking your code again - you might have made a mistake.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
[toc] | [prev] | [next] | [standalone]
| From | sheldonlg <sheldonlg@thevillages.net> |
|---|---|
| Date | 2011-06-14 19:43 -0400 |
| Message-ID | <it8rmh$6is$1@dont-email.me> |
| In reply to | #2165 |
On 6/14/2011 7:12 PM, Jerry Stuckle wrote:
> On 6/14/2011 6:27 PM, sheldonlg wrote:
>> On 6/14/2011 2:32 PM, Denis McMahon wrote:
>>> On Tue, 14 Jun 2011 12:49:11 -0400, sheldonlg wrote:
>>>
>>>> I have a problem that I am wrestling with that should be so obvious and
>>>> easy -- but it isn't. I have a base class that has a method that calls
>>>> another method in the base class with $this->thatOtherMethod. I have
>>>> another class that extends the base class and I want to have
>>>> thatOtherMethod in the extended class override the one in the base
>>>> class. The calling method in the base class is called using and
>>>> instance of the extended class pointing to that method.
>>>>
>>>> Simply, here is an example:
>>>>
>>>> A.class.php
>>>> --------------------------
>>>> <?php
>>>> abstract class A {
>>>> public function b() {
>>>> $this->a();
>>>> }
>>>> protected function a() {
>>>> print 'In class A';
>>>> }
>>>> }
>>>> ?>
>>>>
>>>> B.class.php
>>>> ---------------------------
>>>> <?php
>>>> include_once 'A.class.php';
>>>> class B extends A {
>>>> public function a() {
>>>> print 'In class B';
>>>> }
>>>> }
>>>> ?>
>>>>
>>>> c.php
>>>> ----------------------------
>>>> <?php
>>>> include 'B.class.php';
>>>> $x = new B();
>>>> $x->b();
>>>> ?>
>>>> ----------------------------
>>>>
>>>> I want it to print out "In class B", but it prints out "In class A".
>>>>
>>>> I have looked over Google quite a bit and found nothing that helped. I
>>>> have tried making the methods public, protected, keep them both the
>>>> same
>>>> access, etc. and have had no luck. Suggestions?
>>>
> Unfortunately, PHP doesn't really implement OO constructs very well - in
> fact they to a pretty piss poor job of it. One of the problems is with
> virtual functions, as you found. A good OO language would work like you
> want, but PHP doesn't - the constructor for A will, in this case, only
> call a function in A. In C++, Smalltalk, Java and most other OO
> languages, you could define y() as virtual and the constructor for A
> would call the function y() in B.
I could define the method in A as abstract (and the class). It would
then require that it be implemented in B. However, I am not the only
application using A, and so doing that would require all the other apps
to also implement it in an extended class. That is a no-no and is one
of the reasons for using B in the first place.
>
> But if you created a constructor in B properly, it should call B:y().
I did create a constructor in B properly.
> I'd suggest checking your code again - you might have made a mistake.
>
No mistakes that I could find.
--
Shelly
[toc] | [prev] | [next] | [standalone]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2011-06-14 20:45 -0400 |
| Message-ID | <it8vca$nt9$2@dont-email.me> |
| In reply to | #2166 |
On 6/14/2011 7:43 PM, sheldonlg wrote:
> On 6/14/2011 7:12 PM, Jerry Stuckle wrote:
>> On 6/14/2011 6:27 PM, sheldonlg wrote:
>>> On 6/14/2011 2:32 PM, Denis McMahon wrote:
>>>> On Tue, 14 Jun 2011 12:49:11 -0400, sheldonlg wrote:
>>>>
>>>>> I have a problem that I am wrestling with that should be so obvious
>>>>> and
>>>>> easy -- but it isn't. I have a base class that has a method that calls
>>>>> another method in the base class with $this->thatOtherMethod. I have
>>>>> another class that extends the base class and I want to have
>>>>> thatOtherMethod in the extended class override the one in the base
>>>>> class. The calling method in the base class is called using and
>>>>> instance of the extended class pointing to that method.
>>>>>
>>>>> Simply, here is an example:
>>>>>
>>>>> A.class.php
>>>>> --------------------------
>>>>> <?php
>>>>> abstract class A {
>>>>> public function b() {
>>>>> $this->a();
>>>>> }
>>>>> protected function a() {
>>>>> print 'In class A';
>>>>> }
>>>>> }
>>>>> ?>
>>>>>
>>>>> B.class.php
>>>>> ---------------------------
>>>>> <?php
>>>>> include_once 'A.class.php';
>>>>> class B extends A {
>>>>> public function a() {
>>>>> print 'In class B';
>>>>> }
>>>>> }
>>>>> ?>
>>>>>
>>>>> c.php
>>>>> ----------------------------
>>>>> <?php
>>>>> include 'B.class.php';
>>>>> $x = new B();
>>>>> $x->b();
>>>>> ?>
>>>>> ----------------------------
>>>>>
>>>>> I want it to print out "In class B", but it prints out "In class A".
>>>>>
>>>>> I have looked over Google quite a bit and found nothing that helped. I
>>>>> have tried making the methods public, protected, keep them both the
>>>>> same
>>>>> access, etc. and have had no luck. Suggestions?
>>>>
>
>> Unfortunately, PHP doesn't really implement OO constructs very well - in
>> fact they to a pretty piss poor job of it. One of the problems is with
>> virtual functions, as you found. A good OO language would work like you
>> want, but PHP doesn't - the constructor for A will, in this case, only
>> call a function in A. In C++, Smalltalk, Java and most other OO
>> languages, you could define y() as virtual and the constructor for A
>> would call the function y() in B.
>
> I could define the method in A as abstract (and the class). It would
> then require that it be implemented in B. However, I am not the only
> application using A, and so doing that would require all the other apps
> to also implement it in an extended class. That is a no-no and is one of
> the reasons for using B in the first place.
>
>>
>> But if you created a constructor in B properly, it should call B:y().
>
> I did create a constructor in B properly.
>
>> I'd suggest checking your code again - you might have made a mistake.
>>
>
> No mistakes that I could find.
>
Id you created it properly, then the constructor in B should be calling
b::y().
I still suggest you have a mistake in your code.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
[toc] | [prev] | [next] | [standalone]
| From | sheldonlg <sheldonlg@thevillages.net> |
|---|---|
| Date | 2011-06-14 21:58 -0400 |
| Message-ID | <it93k1$dkn$1@dont-email.me> |
| In reply to | #2167 |
On 6/14/2011 8:45 PM, Jerry Stuckle wrote: > Id you created it properly, then the constructor in B should be calling > b::y(). > > I still suggest you have a mistake in your code. No, both constructors are there but are empty. Now here is the really weird thing. I decided to experiment with a simplified example and so copied the entire files into a test area via a copy/paste. I then eliminated all methods that were not called, eliminated all includes that were no longer needed in the classes, and modified the important routines to only do the printing and the one calling routine in the class to only call the prescribed method and not do any other work. So, besides the constructors (which were empty) the base class had two methods and the overload class had one (with the name as the final method invoked in the base class). The only typing I did was putting print statements in the final invoked methods to identify which one was doing the output. I expected the same result as the I had been getting. However, what happened was that the output was from the overloaded method, not the base method. Now I am totally baffled. -- Shelly
[toc] | [prev] | [next] | [standalone]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2011-06-14 22:08 -0400 |
| Message-ID | <it946e$gij$1@dont-email.me> |
| In reply to | #2168 |
On 6/14/2011 9:58 PM, sheldonlg wrote: > On 6/14/2011 8:45 PM, Jerry Stuckle wrote: >> Id you created it properly, then the constructor in B should be calling >> b::y(). >> >> I still suggest you have a mistake in your code. > > No, both constructors are there but are empty. > > Now here is the really weird thing. I decided to experiment with a > simplified example and so copied the entire files into a test area via a > copy/paste. I then eliminated all methods that were not called, > eliminated all includes that were no longer needed in the classes, and > modified the important routines to only do the printing and the one > calling routine in the class to only call the prescribed method and not > do any other work. So, besides the constructors (which were empty) the > base class had two methods and the overload class had one (with the name > as the final method invoked in the base class). The only typing I did > was putting print statements in the final invoked methods to identify > which one was doing the output. > > I expected the same result as the I had been getting. However, what > happened was that the output was from the overloaded method, not the > base method. > > Now I am totally baffled. > Which indicates there is some problem with your original code. It could be anything - including misplaced /*...*/ comments, for instance. But I looked again at your code, and I'm confused, In class A you have public function b(). And in class B you have public function a(). Which is it? Also, you are aware, aren't you, that this follows the old style PHP constructors (which are still valid) where the constructor's name is the name of the class (instead of __construct() ). -- ================== Remove the "x" from my email address Jerry Stuckle JDS Computer Training Corp. jstucklex@attglobal.net ==================
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-06-15 14:21 +0200 |
| Message-ID | <1532095.qVoOGUtdWV@PointedEars.de> |
| In reply to | #2168 |
sheldonlg wrote:
> On 6/14/2011 8:45 PM, Jerry Stuckle wrote:
>> Id you created it properly, then the constructor in B should be calling
>> b::y().
>>
>> I still suggest you have a mistake in your code.
>
> No, both constructors are there but are empty.
>
> […] I […] copied the entire files into a test area […]. I then eliminated
> all methods that were not called, eliminated all includes that were no
> longer needed in the classes, and modified the important routines to only
> do the printing and the one calling routine in the class to only call the
> prescribed method […]. So, besides the constructors (which were empty)
> the base class had two methods and the overload class had one (with the
> name as the final method invoked in the base class). The only typing I
> did was putting print statements in the final invoked methods to identify
> which one was doing the output.
>
> […] what happened was that the output was from the overloaded method, not
> the base method. […]
Talk is cheap. Show me the code.
-- Linus Torvalds (2000-08-25)
<http://www.catb.org/~esr/faqs/smart-questions.html#beprecise> ff.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
[toc] | [prev] | [next] | [standalone]
| From | sheldonlg <sheldonlg@thevillages.net> |
|---|---|
| Date | 2011-06-15 12:55 -0400 |
| Message-ID | <itao5l$nof$1@dont-email.me> |
| In reply to | #2168 |
Problem solved! It was a case of a little stupidity on my part. I put the new overloaded method into the wrong overloading class. Ergo, it was never reached when I ran the application because it wasn't there. In the example, it went to the right place and printed as coming from the overloaded method. Sometimes........ Anyway, when I put it in the proper file, it functioned exactly as I had originally anticipated (and meant to program). Thanks to all who devoted time and made suggestions. I am sorry to have wasted your time. -- Shelly
[toc] | [prev] | [next] | [standalone]
| From | Michael Fesser <netizen@gmx.de> |
|---|---|
| Date | 2011-06-15 18:04 +0200 |
| Message-ID | <cblhv6d7hpa1gf7p5curfarqegijv098hv@mfesser.de> |
| In reply to | #2165 |
.oO(Jerry Stuckle)
>Unfortunately, PHP doesn't really implement OO constructs very well - in
>fact they to a pretty piss poor job of it. One of the problems is with
>virtual functions, as you found. A good OO language would work like you
>want, but PHP doesn't - the constructor for A will, in this case, only
>call a function in A.
What do you mean?
<?php
class A {
public function __construct() {
$this->y();
}
public function y() {
print __METHOD__."\n";
}
}
class B extends A {
public function y() {
print __METHOD__."\n";
}
}
$a = new A();
$b = new B();
?>
$ php -f constructor.php
A::y
B::y
Pretty much what I expect.
>In C++, Smalltalk, Java and most other OO
>languages, you could define y() as virtual and the constructor for A
>would call the function y() in B.
In PHP non-private methods are always virtual and in the above example
the constructor in A calls the method in B.
Micha
[toc] | [prev] | [next] | [standalone]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2011-06-15 12:53 -0400 |
| Message-ID | <itao2v$mhc$1@dont-email.me> |
| In reply to | #2195 |
On 6/15/2011 12:04 PM, Michael Fesser wrote:
> .oO(Jerry Stuckle)
>
>> Unfortunately, PHP doesn't really implement OO constructs very well - in
>> fact they to a pretty piss poor job of it. One of the problems is with
>> virtual functions, as you found. A good OO language would work like you
>> want, but PHP doesn't - the constructor for A will, in this case, only
>> call a function in A.
>
> What do you mean?
>
> <?php
> class A {
> public function __construct() {
> $this->y();
> }
>
> public function y() {
> print __METHOD__."\n";
> }
> }
>
> class B extends A {
> public function y() {
> print __METHOD__."\n";
> }
> }
>
> $a = new A();
> $b = new B();
> ?>
>
> $ php -f constructor.php
> A::y
> B::y
>
> Pretty much what I expect.
>
>> In C++, Smalltalk, Java and most other OO
>> languages, you could define y() as virtual and the constructor for A
>> would call the function y() in B.
>
> In PHP non-private methods are always virtual and in the above example
> the constructor in A calls the method in B.
>
> Micha
Ah, you're right, Micha. This was finally fixed. It didn't used to
work that way :)
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denis.m.f.mcmahon@gmail.com> |
|---|---|
| Date | 2011-06-15 03:41 +0000 |
| Message-ID | <4df829d0$0$32280$bed64819@gradwell.net> |
| In reply to | #2162 |
On Tue, 14 Jun 2011 18:27:20 -0400, sheldonlg wrote:
>> This code:
>>
>> <?php
>>
>> abstract class A {
>>
>> public function x() {
>> print "x() In class A\n";
>> $this->y();
>> }
>>
>> public function y() {
>> print "y() In class A\n";
>> }
>>
>> public function a() {
>> print "a() In class A\n";
>> }
>>
>> }
>>
>> class B extends A {
>>
>> public function y() {
>> print "y() In class B\n";
>> }
>>
>> }
>>
>> print "instantiate\n";
>>
>> $x = new B();
>>
>> print "call function\n";
>>
>> $x->x();
>>
>> ?>
>>
>> gives:
>>
>> instantiate
>> a() In class A
>> call function
>> x() In class A
>> y() In class B
>>
>> Not sure, though, if that solves your problem or not?
> Why did your example print out that last line. It was never called.
> Why did it use it as a constructor? That doesn't seem to make sense.
OK, the calls as I understand it in my code.
First I print "instantiate"
Next, "$x = new B();" causes $x to be created, which instantiates b,
which extends a, which causes A::a() to be called as a constructor
function, which prints "a() In class A".
Then I print "call function"
Finally, "$x->x();" calls A::x() which prints the line "x() In class A"
and then calls $this->y() which finds B::y() which prints the line "y()
In class B".
I'm not sure if your complaint is about the sequence of call of the
constructor functions during instantiation of $x, or the call chain after
instantiation, which is why I gave the functions called after
instantiation different names (x and y) to the constructor function in
class A.
I believe that in your code, A::a() was being called as a constructor at
instantiation, and A::b() was calling B::a() after instantiation. That's
certainly suggested by:
<?php
abstract class A {
public function a() {
print "a() In class A\n";
}
public function b() {
print "b() In class A\n";
print "b() In class A calling \$this->a()\n";
$this->a();
print "b() In class A returned from \$this->a()\n";
}
}
class B extends A {
public function a() {
print "a() In class B\n";
}
}
print "instantiate\n";
$x = new B();
print "call function\n";
$x->b();
?>
giving:
instantiate
a() In class A
call function
b() In class A
b() In class A calling $this->a()
a() In class B
b() In class A returned from $this->a()
Note that A::a() is called as constructor during instantiation of $x
A::b() calling $this->a() after instantiation of $x calls B::a() and not
A::a().
Your initial complaint was about A::a() being called, is it possible that
the A::a() call that you observed was from instantiation and not the call
to $x->b()?
Rgds
Denis McMahon
[toc] | [prev] | [next] | [standalone]
| From | Michael Fesser <netizen@gmx.de> |
|---|---|
| Date | 2011-06-15 18:02 +0200 |
| Message-ID | <3ilhv6hokjelo95b31fajeqdcpnd6ae1nk@mfesser.de> |
| In reply to | #2162 |
.oO(sheldonlg)
>On 6/14/2011 2:32 PM, Denis McMahon wrote:
>
>> This code:
>>
>> <?php
>>
>> abstract class A {
>>
>> public function x() {
>> print "x() In class A\n";
>> $this->y();
>> }
>>
>> public function y() {
>> print "y() In class A\n";
>> }
>>
>> public function a() {
>> print "a() In class A\n";
>> }
>>
>> }
>>
>> class B extends A {
>>
>> public function y() {
>> print "y() In class B\n";
>> }
>>
>> }
>>
>> print "instantiate\n";
>>
>> $x = new B();
>>
>> print "call function\n";
>>
>> $x->x();
>>
>> ?>
>>
>> gives:
>>
>> instantiate
>> a() In class A
>> call function
>> x() In class A
>> y() In class B
>>
>> Not sure, though, if that solves your problem or not?
>>
>> Rgds
>>
>> Denis McMahon
>
>I modified B to give it an explicit constructor. It still didn't work.
> Why did your example print out that last line. It was never called.
The command $x->x() would call B::x(), but there's no such method. So
the inherited method A::x() is called, which then calls $this->y(). And
since $this refers to an instance of class B, B::y() is called, leading
to the last line of output.
Micha
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-06-15 14:01 +0200 |
| Message-ID | <2975511.SPkdTlGXAF@PointedEars.de> |
| In reply to | #2150 |
sheldonlg wrote:
> I have a problem that I am wrestling with that should be so obvious and
> easy -- but it isn't. I have a base class that has a method that calls
> another method in the base class with $this->thatOtherMethod. I have
> another class that extends the base class and I want to have
> thatOtherMethod in the extended class override the one in the base
> class. The calling method in the base class is called using and
> instance of the extended class pointing to that method.
>
> Simply, here is an example:
>
> A.class.php
> --------------------------
> <?php
> abstract class A {
> public function b() {
> $this->a();
> }
> protected function a() {
> print 'In class A';
> }
> }
> ?>
>
> B.class.php
> ---------------------------
> <?php
> include_once 'A.class.php';
> class B extends A {
> public function a() {
> print 'In class B';
> }
> }
> ?>
>
> c.php
> ----------------------------
> <?php
> include 'B.class.php';
> $x = new B();
> $x->b();
> ?>
> ----------------------------
>
> I want it to print out "In class B", but it prints out "In class A".
>
> I have looked over Google quite a bit and found nothing that helped. I
> have tried making the methods public, protected, keep them both the same
> access, etc. and have had no luck. Suggestions?
Yes. Both your testing method and your posting leave much to be desired:
You should have avoided the `include's in the test code, thereby removing
them from the equation and making it easier for people to test your code.
They are deprecated for class loading anyway (at least by PEAR standards;
use an autoloader instead). [But if you must use includes in this context,
you should use `require_once' instead.]
You should have added at least one output statement to *each* method, and
between the global statements. [You should have used `echo' instead of
`print', since you are not using print's return value.]
You should not have named the method case-insensitively the same as the
class, as that can make a constructor out of the method. [But if that was
your intention, you should have used exactly the same name – considering
letter case – or (better since PHP 5) __construct.]
You should have said which PHP client (version, type) you have been testing
with.
Finally, in retrospect of my results below, you should have been more
precise as to the output you are getting.
Using a variant of your code that meets these criteria –
$ cat overloading.php
<?php
abstract class A {
public function b() {
echo "A::b()\n";
$this->a();
}
protected function a() {
echo "A::a()\n";
}
}
class B extends A {
public function a() {
echo "B::a()\n";
}
}
echo "instantiation\n";
$x = new B();
echo "method call\n";
$x->b();
?>
–, I cannot confirm your observations here exactly:
$ php overloading.php
instantiation
PHP Fatal error: Call to protected A::a() from invalid context in
****/overloading.php on line 21
PHP Stack trace:
PHP 1. {main}() ****/overloading.php:0
$ php --version
PHP 5.3.3-7+squeeze1 with Suhosin-Patch (cli) (built: Mar 18 2011 17:22:52)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
with XCache v1.3.1, Copyright (c) 2005-2010, by mOo
with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH
But with the Apache 2.0 module of PHP 5.3.3-7+squeeze1 on the same computer,
I am not getting this error for the same code; instead I get the following
output (taken from the View Source window in the browser, Iceape 2.0.14):
instantiation
method call
A::b()
B::a()
If the visibility of A::a() is changed to `public' –
$ cat overloading2.php
<?php
abstract class A {
public function b() {
echo "A::b()\n";
$this->a();
}
public function a() {
echo "A::a()\n";
}
}
class B extends A {
public function a() {
echo "B::a()\n";
}
}
echo "instantiation\n";
$x = new B();
echo "method call\n";
method call
A::b()
B::a()
$x->b();
?>
– I get the following with the CLI:
$ php overloading2.php
instantiation
A::a()
method call
A::b()
B::a()
But with the Apache 2.0 module, I get:
instantiation
method call
A::b()
B::a()
A possible explanation for the CLI behavior is that, because B has no
constructor, and A::b() is not inherited as constructor for B, but B is to
be instantiated, the constructor of its superclass A, A::a(), is called
instead (regardless whether that class is declared abstract, as it would not
be instantiated). This reasoning would be consistent with the fact that it
is a fatal error when that constructor, A::a(), is not public. [It
certainly has *nothing* to do that PHP would not being able to call methods
of instantiated classes properly, i.e. does not implement "virtual" methods.
Although it does have OO deficiencies, PHP can do that well. And *no* OOPL
I know lets classes inherit constructors.]
If that applies, then the reason why you are not getting an error, and I am
not getting an error with the Apache 2.0 module, could be that (perhaps
through php.ini settings) the Apache 2.0 module enforces other (in my case:
stricter) rules than the CLI, since the PHP versions are the same here.
This reasoning would be consistent with the fact that, regardless whether
A::a() is public or not, it is not called when using the Apache 2.0 module;
we can assume B is considered to have an implicit empty constructor,
B::__construct(), then (as A cannot be instantiated). Then B::a() is called
because A::b() can be and is inherited by B from A (it sort of becomes
B::b() for instances of B), and A/B::b() calls B::a() accordingly,
regardless whether A::a() it is public or not (as A::a() is not called in
the first place).
[Suppose a php.ini setting is the reason for this difference, I would be
grateful if someone pointed me to the relevant documentation.]
While that would explain why you are not getting an error, it would not
explain why – as you stated – *only* A::a() would be called in any case.
A possible explanation for that would be that you were using a different,
perhaps older, version of PHP. In that case upgrading PHP might be a good
idea.
HTH
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.php
csiph-web