Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Проблема с инициализацией переменной (http://www.flasher.ru/forum/showthread.php?t=179482)

Maestro13 15.05.2012 23:11

Проблема с инициализацией переменной
 
переменная a:boolean = false определена в классе class_parent. Конструктор класса class_child расширяющий class_parent:
a = true;
super();
так вот. трейс после конструктора показывает true

хотя, если я не ошибаюсь при вызове конструктора суперкласса происходит инициализация прееменных супер класса. Тоесть переменная должна переопределиться в false.

Если я ошибаюсь, объясните как происходит порядок инициализации, или дайте ссылку, где об этом можно почитать

silin 15.05.2012 23:33

Код AS3:

public class Parent 
{
        public var a:Boolean = false;
        trace("Parent: init members");
        public function Parent()
        {
                trace( "Parent: ctor" );
 
        }
 
}

Код AS3:

public class Child extends Parent 
{
        trace("Child: init members");
        public function Child()
        {
                trace( "Child: ctor" );
                super();
 
        }
}

Код AS3:

var test:Child = new Child();
/*
Parent: init members
Child: init members
Child: ctor
Parent: ctor
*/


expl 16.05.2012 00:20

Цитата:

Код AS3:

public class Parent 
{
        public var a:Boolean = false;
        trace("Parent: init members");
        public function Parent()
        {
                trace( "Parent: ctor" );
 
        }
}


@silin
trace("Parent: init members"); будет вызвано 1 раз, сколько бы экземпляров не создавали. Т.е. это статическая инициализация, не уверен, что это корректная демонстрация порядка инициализации _нестатических_ переменных

Попробуем выкрутиться:
Код AS3:

class A {
        protected var a:Bool = new Bool(false);
        public function A() {
                trace("A {");
                trace("a: " + a);
                trace("}");
        }               
}
class B extends A {               
        public function B() {
                trace("B {");
                trace("Выполняем a = new Bool(true):");
                a = new Bool(true);
                trace("Выполняем super():");
                super();
                trace("a: " + a);
                trace("}");
        }
}
class Bool {       
        private var _value:Boolean;
        public function Bool(value:Boolean) {
                _value = value;
                trace("new Bool(" + value + ")");
        }
        public function toString():String {
                return "[Bool(" + _value + ")]";
        }
}
/*
B {
Выполняем a = new Bool(true):
new Bool(true)
Выполняем super():
new Bool(false)
A {
a: [Bool(false)]
}
a: [Bool(false)]-????????
}
*/

Выводит таки false?

Так, а если просто Boolean?
Код AS3:

class A {
        protected var a:Boolean = false;
        public function A() {
                trace("A {");
                trace("a: " + a);
                trace("}");
        }               
}
class B extends A {               
        public function B() {
                trace("B {");
                trace("Выполняем a = new Bool(true):");
                a = true;
                trace("Выполняем super():");
                super();
                trace("a: " + a);
                trace("}");
        }
}
/*
B {
Выполняем a = new Bool(true):
Выполняем super():
A {
a: true
}
a: true 0_o
}
*/

Теперь уже я ничего не понимаю :o

Maestro13 16.05.2012 00:28

Вот такой пример:
Код AS3:

package  
{
 
        public class A
        {
                protected var t:Boolean = true;
                trace("A init");
                public function A()
                {
                        trace("A constr",t);
                }
 
        }
 
}


Код AS3:

package  
{
 
        public class B extends A
        {
                trace("B init");
                public function B()
                {
                        t = false;
                        trace("B constr",t);
                        super();
                }
 
        }
 
}



Код AS3:

var b:B=new B();

Результат такой:
A init
B init
B constr false
A constr true

А если сделать наоборот protected var t:Boolean = false; а потом переопределить ее в true в дочернем классе то результат будет такой:

A init
B init
B constr true
A constr true

Почему в одном случае она переопределяется, а в другом нет?

expl 16.05.2012 00:50

Может после super() установить нужное значение и забить?
А нужное самому суперклассу загнать в конструктор?

Но лучше, конечно, перед этим в документации поискать порядок инициализации полей, а то так и останется загадкой (мне это делать сейчас лень запрещает)

Партизан 16.05.2012 02:29

Думаю, при инициализации переменных берется только класс переменной из родительского. Для Boolean значение по умолчанию 'false'. После вызова родительского конструктора, переменной задается значение, если значение задано до вызова super(), то значение родительского класса игнорируется(что логично в общем-то). Если super() не вызывается в конструкторе, компилятор добавляет его в первую инструкцию конструктора наследника.

Код AS3:

public class A 
        {
                protected var a:String = 'from A';
                trace('init A');
 
                public function A()
                {
                        trace('cnt A');
                        a = 'from cnt A';
 
                }
 
        }
 
public class B extends A
        {
                trace('init B')
                public function B()
                {
                        trace('cnt B, set a, a=', a);
                        a = 'cnt B'
                        trace('a from B cnt, a=', a);
                        super();                       
                }
 
        }
 
var b:B = new B();
trace('')
var c:B = new B();
 
/*
init A
init B
cnt B, set a, a= null
a from B cnt, a= cnt B
cnt A
 
cnt B, set a, a= null
a from B cnt, a= cnt B
cnt A
*/


Gaen 16.05.2012 04:34

Именно поэтому я инициализирую переменные в конструкторе.

Партизан 16.05.2012 04:45

А вот *** там.... Сорри ввел в некоторое заблуждение.
Родительский конструктор изменяет переменную даже после ее "переопределения" в потомке. Если трейсануть после super() в B классе, результатом будет:
Код:

cnt A
from cnt A

нДА.... Действительно непредсказуемо :)
Adobe: В противном случае ссылка super может повести себя не так, как предполагалось. пусть и про ссылку, но по теме.

silin 16.05.2012 11:02

>> Почему в одном случае она переопределяется, а в другом нет? (пост #4)
такое есть предположение: инициализация дефолтовым значением (false в этом случае) просто опускается, ну и не переопределяется ничего
вот и для целых такая же картина
Код AS3:

public class A
{
        protected var n:int = 0;// на любое другое(кроме дефолтового нуля) поменяет
        public function A()
        {
                trace("A constr", n);
        }
}

Код AS3:

public class B extends A 
{
        public function B()
        {
                n = 1;
                trace("B constr",n);
                super();
        }
}

имо, не стоит играться с этими вещами, во избежание таких фокусов, короче super в самый вверх и все будет строго, ага

Добавлено через 18 минут
или как вариант инициализировать так чтоб компилятор 'не знал' чем и не своевольничал, типа
Код AS3:

public class A
{
        protected var t:Boolean = initProp();
 
        public function A()
        {
                trace("A constr", t);
        }
        private function initProp():Boolean
        {
                return false;
        }
}

только опять же: а оно вам надо?


Часовой пояс GMT +4, время: 13:48.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.