Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> И снова объекты! Как бы по красивей сделать наледование 
:(
    Опции темы
maxkazar
Дата 11.10.2004, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 26.1.2004
Где: Таганрог

Репутация: нет
Всего: нет



Как сделать наследование в объектах JScript
Я попробывал сам и вот что получилось

Код
function a()
{this.create = a_create}
 
function a_create()
{alert("a")}

function b()
{this.create = b_create}

b.prototype = new a()
 
function b_create()
{b.prototype.create()
alert("b") }  
 
var oa = new a()
oa.create()

var ob = new b()
ob.create()


при выполнении скрипта получаем следующее

Код

//Create объекта oa
a

//Cretae объекта ob
a
b


Вобщемто все работает (метод create наследуеться)... вот только мне не нравиться
что из метода необходимо сылаться через имя класса на метод класса

Код
b.prototype.create()


естли какие предложения как сделать наследование красивым)
PM MAIL ICQ   Вверх
ElectricalStorm
Дата 11.10.2004, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 547
Регистрация: 22.1.2004

Репутация: нет
Всего: 9



Цитата

естли какие предложения как сделать наследование красивым


есть

1. Вам надо хорошенько подумать над code style...
2. Смотри пример

Код

function BaseClass(from, name) {    
       this.from = from || "author";    
       var name  = name || "somebody";  
       
       // Приветствие.
       this.hello = function() {
               // закрытые свойства пишем без this
               alert("Hello, "+name+", from "+this.from);
       }
                 
       // Метод для установки значения закрытого свойства.
       this.setName = function(n) {
               name = n;
       }
       
       // Приватный метод
       function privateMethod() {
              alert("Private, "+name+", from "+this.from);    
       }
}

DerivedClass.prototype = new BaseClass();

function DerivedClass() {    
       this.helloDerived = function() {
               alert("Hello from derived");
       }
}

// Создаем объект базового класса и проверяем работу.
var obj = new BaseClass();
obj.setName("World");
obj.hello();

// Создаем объект производного класса и проверяем работу.
var objDerived = new DerivedClass();
objDerived.hello();
objDerived.helloDerived();




--------------------
Нужно знать инструмент, которым пользуешься
PM MAIL   Вверх
Sardar
Дата 11.10.2004, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(maxkazar @ 11.10.2004, 10:05)
Вобщемто все работает (метод create наследуеться)... вот только мне не нравиться что из метода необходимо сылаться через имя класса на метод класса

maxkazar код от начала и до конца правильный wink.gif
Осталось только понять что конкретно происходит. В JS нет классов(мы пока не расматриваем JS2), это обьектно-прототипный язык. Это значит что все кроме примитивных типов есть обьекты, от обьектов порождаются другие обьекты, на практике создать обьект можно только от обьекта Function. У каждого обьекта есть конструктор - обьект функция, т.е. этот код:
Код
var test=new myObject();
var test2=new test.constructor();

Создаст еще один обьект от myObject.
У функций есть свойство prototype, задающее интерфейс всем обьектам созданным от этой функции. Сказанное выше и это формирует понятие обьектно-прототипный язык. Тут есть несколько моментов:

  • если прототип функции не изменят присваиванием обьекта, а просто создавать/изменять его поля, то все изменения отражаются на всех обьектах, созданных от этой функции.
  • если полю prototype присвоили новый обьект, то все изменения над прототипом будут отражатся на созданых после обьектах и присвоенном обьекте. Обьекты созданные ранее изменения прототипа останутся не изменными.

Цитата(maxkazar @ 11.10.2004, 10:05)
естли какие предложения как сделать наследование красивым)

Я не знаю что ты считаешь красивым wink.gif но тем не менее в JS есть и свои тараканы. Например следующий код:
Код
function a(){
this.create = function(){this.bla="test";};
}
function b() {
this.create = function() {alert(this.constructor);};
}
b.prototype = new a()
var ob = new b()
ob.create();

Покажет нам что в this.constructor лежит ссылка на функцию a! Полнейший бред но это так(во всех браузерах), так что this.constructor.create(), как если бы b была бы нашим конструктором, ты не можешь. Так что тво способ верный и не стоит морочить себе голову smile.gif

Кстати JS это очень гибкий, без жестких типов язык, что бы потребовалось наследование с переопредлением методов встречаю в первый раз wink.gif
Пиши проще, для этого JS и придумывался, а наследование и типы оставь для Java.

Цитата
Вам надо хорошенько подумать над code style...

Странное замечание... wink.gif
И еще заинтересовал пример с приватным методом, как и ожидал он не работает wink.gif
На самом деле создается функция существующая в момент работы конструктора BaseClass, после его завершения функция уничтожается.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
ElectricalStorm
Дата 12.10.2004, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 547
Регистрация: 22.1.2004

Репутация: нет
Всего: 9



Sardar мне кажется Вы что-то не допонимаете

Если взять за основу мой пример то становиться все понято

Код

var test=new DerivedClass();                  // создание обьетка
alert(test.toSource());                             // посмотрим что это

// Это не создание обьекта !!! нет
// Это создание обьекта суперкласса !!!
var test2=new test.constructor();          

alert(test2.toSource());                          // посмотрим что это


и тогда абсолютно понятно почему вот такой пример работает правильно
Код

function a(){
       this.create = function(){this.bla="test";};
}

function b() {
       this.create = function() {alert(this.constructor);};
}

b.prototype = new a()
var ob = new b()
ob.create();




Цитата

Странное замечание...


что здесь странного - очень коряво написаый код

Цитата

еще заинтересовал пример с приватным методом, как и ожидал он не работает


Еще как работает.
Эту функцию можно использывать внутри класса... так же как это делается во всех ОО языках



--------------------
Нужно знать инструмент, которым пользуешься
PM MAIL   Вверх
Sardar
Дата 12.10.2004, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(ElectricalStorm @ 12.10.2004, 08:48)
Sardar мне кажется Вы что-то не допонимаете
Если взять за основу мой пример то становиться все понято

Ваш код ни о чем не говорит и не понятно что вы считаете правильным. У меня не малый опыт с JS, если я считаю какую нибудь деталь не удобной, то и правильной я ее считать не буду. Другими примерами недочетов JS например может быть отсутствие методов поиска у массивов.

Я повторяю в JavaScript нет классов(супер кллассов и т.п.), потому как нет типов для обьектов. Поле constructor должно содержать ссылку на функцию породившую обьект, что и происходит до присваивания прототипу родительской функии левого обьекта. После присваивания constructor содержит ссылку на функцию, обьект которой мы присвоили в прототипе нашей родительской функции.
Я вижу это как недостаток, т.к. нельзя например вызвать метод из унаследованного обьекта, приходится использовать имя родительской функии(как это правильно сделал maxkazar), что не красиво. Если бы constructor не изменялся, то можно было бы легко поднятся по иерархии до унаследованного обьекта. Скорее всего это недоделка нетскаповцев.
Цитата(ElectricalStorm @ 12.10.2004, 08:48)
что здесь странного - очень коряво написаый код

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

Цитата(ElectricalStorm @ 12.10.2004, 08:48)
Еще как работает. Эту функцию можно использывать внутри класса... так же как это делается во всех ОО языках


Действительно работает, впрочем ни в одном учебнике такого не видел. Доказал чисто опытным путём.

Рассмотрим код:
Код
function test() {
var a=90;
var b="test";
function incA(a) {
 b="Vingrad";
 return a++; //постинкремент, значение изменится после возврата
}
for(var i=0; i<10; i++) a=incA(a);
alert(a);
alert(b);
}
test();

Замечаем что фнутри вложенной функции нам доступны переменные из контекста выше(что было и раньше когда вы создавали функции в контексте window), переменные определенные в функции являются локальными, потому воздействие на a никак не отражется на a выше по контексту. Заменим a++ на a+1, получили требуемый результат.
Что же такое вложенная функция? После работы test мы не можем достигнуть incA: alert(window.incA+", "+test.incA);
На самом деле функция уничтожается вместе с контекстом test(), после того как та отработает. Вложенная функция incA это локальный обьект, как и любой другой обьект он должен уничтожится вместе с контекстом.

Рассмотрим что происходит при создании обьекта:
Код
function test() {
var a=90;
var b="test";
function incA(a) {
 b="Vingrad";
 return a+1;
}
for(var i=0; i<10; i++) a=incA(a);
alert(a);
alert(b);

this.accessPrivate=function() {
  alert(incA(200));
}
}
var t=new test();
alert(t.incA); //undefined
t.accessPrivate();

Оператор new создает новый контекст, и связывает его с this. Запускается функция, создается ее собственный контекст. Все вызовы/изменения с this воздействуют на контекст созданный оператором new. Обращение к функциям/переменным без this воздействует на контекст функции и высшие контексты. Значит функция incA создается в контексте функции, а этот контекст доступен внутри обьекта при обращении без this. То есть контексты: <window><test: incA><accessPrivate>выше по контексту incA, этот контекст никому не доступен, потому можно считать его приватным для нас</accessPrivate></test></window>.

ElectricalStorm спасибо за это уточнение.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
ElectricalStorm
Дата 13.10.2004, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 547
Регистрация: 22.1.2004

Репутация: нет
Всего: 9



Цитата

повторяю в JavaScript нет классов(супер кллассов и т.п.), потому как нет типов для обьектов.


Вы утверждаете что ООП в javascript нет а я говорю что есть пересказывать мануал не буду
дам ссылку

http://www.codeproject.com/aspnet/JsOOP1.asp




--------------------
Нужно знать инструмент, которым пользуешься
PM MAIL   Вверх
Sardar
Дата 13.10.2004, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(ElectricalStorm @ 13.10.2004, 08:30)
Вы утверждаете что ООП в javascript нет

Я этого не утверждал, если у вас наличие классов ассоциируется только с ООП языками(что верно wink.gif ), то вы заблуждаетесь на счет JavaScript. В JS нет типов и нет классов описывающих тип обьекта, мало того два обьекта порождённые одной функцией могут быть совершенно разными после некоторых модиффикаций над ними и тем не менее "принадлежать" родительской функции(instanceof->true). Поэтому приходится проверять наличие свойства у обьекта прежде чем его использовать. Наличие классов(типов) это большое преимущество при написании большого кода + легкое проектирование. Но JS изначально придумывался как простой скриптовый язык, классы здесь как козе баян. На JS можно писать как в директивном, так и в обьектном стиле, когда существуют обьекты сuществуйщие "сами по себе", когда большинство кода кода по созданию обьекта использует factory подход т.е. parentObject.createXXX(), parentObject.createYYY();

Не знал о возможностях инкапсуляции. Но это по сути сохранение контекста родительской функции и установка его выше по вложенности для обьекта, а я думал что контекст уничтожается. Обьекты продолжают быть хешьтаблицами с воможностью динамического создания/удаления полей, контексты это тоже хешьтаблицы.

2All советую прочесть статью, много полезного.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
maxkazar
Дата 1.11.2004, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 26.1.2004
Где: Таганрог

Репутация: нет
Всего: нет



Столкнулся со следующей проблемой

Пробую сделать следующую иерархию
A
|
B
/ \
C D

ну в коде приблизительно следующие

Код
function A() {
 this.ShowTest = fnShowTest
 var Test = Math.Random(100)

 function fnShowTest() {
    alert(ShowTest)
 }
}

B.prototype = new A()
function B() {
}

C.prototype = new B()
function C() {
}

D.prototype = new B()
function D() {
}


Так вот, если мы сделаем два класса C и D и вызовем у них метод ShowTest то получим один и тотже результат. В принципе все верно, контекс объекта A создаеться один лишь раз для объекта B, соответсвенно и для C и D((((. Опять рушиться обектный подход(((. Что делать и как быть? Ломаю голову не первый день.
PM MAIL ICQ   Вверх
Sardar
Дата 1.11.2004, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(maxkazar @ 1.11.2004, 09:05)
В принципе все верно, контекс объекта A создаеться один лишь раз для объекта B, соответсвенно и для C и D((((. Опять рушиться обектный подход(((

Где рушится? Наследование не может урезать интерфейс, только расширить ;-) В наследниках C и D имеем все от B, который в свою очердь унаследовал интерфейс от A. Что по твоему не верно?


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
maxkazar
Дата 1.11.2004, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 26.1.2004
Где: Таганрог

Репутация: нет
Всего: нет



Получаеться что пременая Test будет одна для объектов C и D т.е. если я изменю значение Test в объекте D то и изменится значение Test в объекте C!!!(((. А это неправильно
PM MAIL ICQ   Вверх
Sardar
Дата 1.11.2004, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(maxkazar @ 1.11.2004, 10:30)
если я изменю значение Test в объекте D

Переменная Test является приватной и принадлежит только А, никакими способами кроме интерфейса А ты на переменную воздействовать не можешь. В JavaScript нет классов, т.е. нет наследования от класса(от типа) как например в C++ или Java. То есть нет понятия: при создании обьекта вначале автоматом создаются все его предки.
В JavaScript есть только обьекты, порожденные некоторой функцией и имеющие интерфейс создаваемой этой функцией + интерфейс обьекта в прототипе(изначально прототип это пустой обьект). Обьект в прототипе не копируется! Значит это верно что все обьекты наследуемые B имеют одинаковые переменные A созданной для B.

А все потому что JavaScript это не Java, это обьектно прототипный язык, позволяющий писать как в директивном так и в ООП стиле. Это идеально для не больших скриптов, которыми скрипты в страничке и являются. Ты просто представь себе огрменные библиотеки классов для создания roll over эффекта :D

P.S. я пишу на JS, QVB и нa Java - все три языка относятся к различным парадигмам :)


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0553 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.