Область видимости объекта базового класса

[DAN]

Старожил PHPClub
Область видимости объекта базового класса

Народ, что-то я совсем не понимаю такое поведение классов:
PHP:
class simple{
	function simple() {
		var_dump($this);
	}
}

class complex extends simple {}

$obj = new simple();
$obj = new complex();
Может объясните, как объект-родитель становится объектом-потомком?
Хотелось бы также увидеть аналогичный примерчик на С++.

PHP 4.3.10
PHP 5.1.0b2
 

[DAN]

Старожил PHPClub
Получаю то же, что и Светлана.
Ожидаю object(simple)#1 (0) {} в обоих случаях.
 

svetasmirnova

маленький монстрик
>Ожидаю object(simple)#1 (0) {} в обоих случаях.
Хм... Даже не знаю как объяснить. Попробую.
А когда ты делаешь так:
PHP:
function foo() {
echo 'foo';
return 'foo';
}
function bar() {
echo 'bar';
return 'bar';
}
$foo = foo();
$foo = bar();
Что ожидаешь получить?
 

[DAN]

Старожил PHPClub
Потому что объект базового класса не может вдруг стать объектом производного.
Это нарушает все принципы инкапсуляции.
PHP:
class simple{
	function simple() {
		$this->foo();
	}
}

class complex extends simple {
	function foo() {
		echo "complex::foo() is called from simple::simple()";
	}
}

$obj = new complex();
$obj = new simple();
Как это понимать?
 

tony2001

TeaM PHPClub
[DAN]
ты явно что-то путаешь.
как понимать ЧТО?
что у simple нет метода foo(), о чем тебе сообщает errmsg?
так нет его, родимого, действительно.
 

[DAN]

Старожил PHPClub
В конструкторе базового класса (simple) указатель this ссылается на объект производного класса (complex). В частности я имею возможность вызывать методы производного класса из базового класса. Вот это я не могу понять.
Может кто примерчик на С++ все-таки приведет, для ясности?
 

tony2001

TeaM PHPClub
>В частности я имею возможность вызывать методы производного класса из базового класса.
не имеешь ты такой возможности, в том-то и дело.
это в чайлде, из наследованного МЕТОДА базового класса, ты можешь вызывать методы класса-чайлда.

>Может кто примерчик на С++ все-таки приведет, для ясности?
ага, щаз.
 

[DAN]

Старожил PHPClub
Для прояснения вопроса. Я прекрасно понимаю, что объект производного класса также является и объектом базового класса. Но каким образом указатель на производный класс попадает в базовый класс, тем самым внося весь функционал производных классов в базовый?
 

tony2001

TeaM PHPClub
>Я прекрасно понимаю, что объект производного класса также является и объектом базового класса.
??
с каких пор?

>Но каким образом указатель на производный класс попадает в базовый класс, тем
>самым внося весь функционал производных классов в базовый?
бл№..
никто никуда не попадает.
откуда ты это берешь вообще?

$this всегда указывает на сам объект (если метод не статически вызывается, но это не тот случай), соотв-но, в наследованных методах $this будет указывать на instance потомка.
 

ForJest

- свежая кровь
Как я понимаю - единственная проблема в том, что PHP не отслеживает наличие вызываемого метода. Но это логично, т.к. PHP это интерпритатор :).

[DAN] такая конструкция тебя устроит?
PHP:
class simple{ 
    function simple() { 
        $this->foo(); 
    } 
    function foo() {
    }
} 

class complex extends simple { 
    function foo() { 
        echo "complex::foo() is called from simple::simple()"; 
    } 
} 

$obj = new complex(); 
$obj = new simple();
-~{}~ 23.09.05 01:22:

В C++ конструкция, которую привёл ты невозможна, т.к. компилятор C++ на этапе компиляции не найдёт декларации метода foo в simple.
 

[DAN]

Старожил PHPClub
>с каких пор?
С тех самых, когда производный класс унаследовал от базового.

> $this всегда указывает на сам объект
о чем и речь. Но тогда почему происходит следующее:
PHP:
class simple{
	var	$var	= '<br>simple';
	function foo(){
		echo $this->var;
	}
}
class complex extends simple {
	var	$var	= '<br>complex';
	function foo(){
		echo $this->var;
		parent::foo();
	}
}

$obj	= new complex();
$obj->foo();
Получается, что область видимости simple::var уходит в никуда, а ее заменяет complex::var причем в БАЗОВОМ классе ( который simple).

-~{}~ 23.09.05 02:27:

ForJest, нет, потому как ну не врублюсь я, как базовый класс может оперировать элементами производного класса? Мы же явно указатель на производный класс не передаем базовому!
 

ForJest

- свежая кровь
[DAN]
ты себя запутываешь
PHP:
<?
class simple
{ 
    var    $var = '<br>simple'; 
} 
class complex extends simple 
{ 
    var  $var = '<br>complex'; 
} 

var_dump(new complex()); 
var_dump(new simple()); 
?>
 

[DAN]

Старожил PHPClub
ForJest, то, что ты привел в пример, понятно :) Простое переопределение элементов базового класса в производном.
Но вот полиморфности я не наблюдаю.
Я хочу, чтобы, оперируя элементами базового класса из методов базового класса я работал именно с элементами базового класса, а не производного.
Я не прав? Ткните в ман!
 

ForJest

- свежая кровь
[DAN]
с методами или полями?

-~{}~ 23.09.05 01:44:

Когда ты создаёшь объект базового класса - ты работаешь с его областью видимости. И базовый класс не видит foo, т.к. у него его нету. Когда ты сделал extends то ты получаешь в результате:
PHP:
class complex  { 
    function simple() { 
        $this->foo(); 
    } 
    function foo() { 
        echo "complex::foo() is called from simple::simple()"; 
    } 
}
по-моему это довольно тривиальная конструкция, чтобы её непонимать.

-~{}~ 23.09.05 01:45:

точнее получается
PHP:
class complex  { 
    function complex(){
        $this-> simple(); //т.к. конструктор автоматически вызывает конструктор предка
    }
    function simple() { 
        $this->foo(); 
    } 
    
    function foo() { 
        echo "complex::foo() is called from simple::simple()"; 
    } 
}
 

[DAN]

Старожил PHPClub
С методами более-менее понятно.
Если метод определен в базовом классе то именно он и будет вызываться из базового класса. А вот свойства перекрываются напрочь.
Вот пример для пхп5, который показывает отжидаемый мной результат:
PHP:
class simple{
	private $var = '<br/>simple';
	
	function test(){
		echo "<br/>From base class:";		
		echo $this->var;
	}
}


class complex extends simple
{
	public $var	= '<br/>complex ';
	
	function test()
	{
		echo "<br/>From inherited class:";		
		echo $this->var;
		parent::test();
	}
}

$obj = new complex();
$obj->test();
в то время как пхп4 упорно не показывает свойство базового класса, к которому идет доступ из метода базового класса:
PHP:
class simple{
	var $var = '<br/>simple';
	
	function test(){
		echo "<br/>From base class:";		
		echo $this->var;
	}
}


class complex extends simple
{
	var $var	= '<br/>complex ';
	
	function test()
	{
		echo "<br/>From inherited class:";		
		echo $this->var;
		parent::test();
	}
}

$obj = new complex();
$obj->test();
 

svetasmirnova

маленький монстрик
Я хочу, чтобы, оперируя элементами базового класса из методов базового класса я работал именно с элементами базового класса, а не производного.
Я не прав? Ткните в ман!

Не прав. Хочешь работать с элементами базового класса: не наследуй и не создавай экземпляр производного. Экземпляр класса не может быть местами экземпляром базового (-ых) класса, а местами производного. Экземпляр всегда один.
 
Сверху