Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2013.12.08;
Скачать: [xml.tar.bz2];

Вниз

class property и виртуальные методы   Найти похожие ветки 

 
vuk ©   (2011-10-24 23:44) [0]

Delphi XE. Пытаюсь сделать class property с возможностью перегрузки в наследнике. Получаю следующее - аксессоры могут быть только class static, что не дает возможности их перегрузить. Пытаюсь изнутри этих методов обращаться к классовым виртуальным методам, но получается фигня, потому, что обратиться к методам потомка не выходит.

Есть какой-либо выход из такой ситуации?

P.S. Я догадываюсь, конечно, что это потому, что у class static нет self.


 
vuk ©   (2011-10-24 23:55) [1]

Для иллюстрации "фигни":

program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils;

type
 TClass1 = class
 protected
   class procedure ClassVirtual; virtual;
 public
   class procedure Test; static;
 end;

 TClass2 = class(TClass1)
 protected
   class procedure ClassVirtual; override;
 end;

{ TClass1 }

class procedure TClass1.ClassVirtual;
begin
 writeln("TClass1.ClassVirtual");
end;

class procedure TClass1.Test;
begin
 ClassVirtual;
end;

{ TClass2 }

class procedure TClass2.ClassVirtual;
begin
 writeln("TClass2.ClassVirtual");
end;

begin
 try
   TClass2.Test;
 except
   on E: Exception do
     Writeln(E.ClassName, ": ", E.Message);
 end;
 readln;
end.


 
DVM ©   (2011-10-25 00:03) [2]


> vuk ©  

class procedure TClass1.Test;
begin
ClassVirtual;
end;

У тебя Test статическая, в нее не передается ссылка на класс (не Self, ссылка на экземпляр, а ссылка на класс). Внутри этого метода нет никакой информации о том, к какому классу он относится. Это просто синтаксис. Test не связан с классом никак, кроме как синтаксически.


 
DVM ©   (2011-10-25 00:10) [3]


> DVM ©   (25.10.11 00:03) [2]

Это я к чему, после компиляции, имхо, эта статическая классовая процедура будет тем же самым, что например:

procedure TClass1.Test;
begin
TClass1.ClassVirtual;
end;


 
DVM ©   (2011-10-25 00:11) [4]


> procedure TClass1.Test;
> begin
> TClass1.ClassVirtual;
> end;

я хотел сказать:

procedure Test;
begin
TClass1.ClassVirtual;
end;


 
vuk ©   (2011-10-25 00:18) [5]

Ну я это, собственно, и так подозреваю, что это из-за отсутствия self у class static. Вопрос возникает. Полученный результат - это оно так и надо или же это баг такой?


 
vuk ©   (2011-10-25 00:22) [6]

Из help:

Class Static Methods
Like class methods, class static methods can be accessed without an object reference. Unlike ordinary class methods, class static methods have no Self parameter at all. They also cannot access any instance members. (They still have access to class fields, class properties, and class methods.) Also unlike class methods, class static methods cannot be declared virtual.


 
DVM ©   (2011-10-25 00:43) [7]


> Полученный результат - это оно так и надо

я не вижу тут бага никакого


 
jack128_   (2011-10-25 08:00) [8]


> P.S. Я догадываюсь, конечно, что это потому, что у class
> static нет self.

тогда откуда вопрос?? Очевидно - ничего нельзя сделать. Нет Self"а - нет полиморфизма.

> Полученный результат - это оно так и надо или же это баг
> такой?

ИМХО - это баг языка.


 
vuk ©   (2011-10-25 10:52) [9]

to jack128_   (25.10.11 08:00) [8]:

> Нет Self"а - нет полиморфизма.

Это понятно, нет ручек - нет мультиков. А хочется. :)


> ИМХО - это баг языка.

Вот тут согласен!


 
DVM ©   (2011-10-25 11:23) [10]


> vuk ©   (25.10.11 10:52) [9]


> Вот тут согласен!

Да почему это баг?

Допустим, есть отдельно стоящая свободная процедура (как я уже писал), внутри которой мы обращаемся к классовому методу заранее известного класса:

procedure Test;
begin
 TClass1.ClassVirtual;
end;


Ясное дело, что будет вызван метод именно класса TClass1, а не какого либо его предка или потомка, по другому и быть не может.

Статический классовый метод это именно такая процедура, просто синтаксис ее объявления позволяет поместить ее внутрь класса и все.
Любые обращения из нее к классовым методам и классовым полям класса в котором она находится можно делать без указания имени класса (даже несмотря на то, что в нее ссылка на класс не передается), но не более того.
При компиляции все будет преобразовано в вид аналогичный приведенному выше.


 
Плохиш ©   (2011-10-25 11:50) [11]

Какой смысл перегружать статические методы?
Весь сокровенный смысл статических членов класса - это группирование глобальных переменных/функций, ну и ещё для всяких религиозных языков громко рассказывать, что в них нет глобальных переменных и это круто.


 
vuk ©   (2011-10-25 12:34) [12]

to Плохиш ©   (25.10.11 11:50) [11]:

> Какой смысл перегружать статические методы?

Я вроде в начале написал, чего именно я хотел - полиморфное свойство, которое будет работать на уровне метакласса. Методы и конструкторы-то работают. А вот свойства - нифига. И я вроде бы не хочу чего-то странного...


 
oxffff ©   (2011-10-25 13:01) [13]


> vuk ©   (24.10.11 23:55) [1]
> Для иллюстрации "фигни":


Работает as designed.


 
oxffff ©   (2011-10-25 13:02) [14]


> vuk ©   (25.10.11 12:34) [12]
> to Плохиш ©   (25.10.11 11:50) [11]:
>
> > Какой смысл перегружать статические методы?
>
> Я вроде в начале написал, чего именно я хотел - полиморфное
> свойство, которое будет работать на уровне метакласса.


Я  в коде не увидел слова property.


 
vuk ©   (2011-10-25 13:06) [15]

to oxffff ©   (25.10.11 13:02) [14]:

> Я  в коде не увидел слова property.

Ну так я ж написал - аксессорами class property могут быть только static методы. Дальше - демонстрация того, что используя их нельзя реализовать полиморфное поведение.


 
oxffff ©   (2011-10-25 13:14) [16]


> vuk ©   (25.10.11 13:06) [15]


Здесь не вполне удачно выбрано именование.
Поскольку

class procedure Test; static;
является глобальной обычной процедурой в рамках всего семейства классов.
Поэтому ее использование некорректно. для этого нужно переписать так.

TClassClass = class of TClass;

class procedure Test(classintance:TClassClass);static;
begin
classintance.ClassVirtual();
end;


 
oxffff ©   (2011-10-25 13:16) [17]


> oxffff ©   (25.10.11 13:14) [16]
>
> > vuk ©   (25.10.11 13:06) [15]
>
>
> Здесь не вполне удачно выбрано именование.


Реально путаница для class и class static c точки зрения функционирования.


 
vuk ©   (2011-10-25 13:17) [18]

to oxffff ©   (25.10.11 13:14) [16]:

> Поэтому ее использование некорректно. для этого нужно переписать
> так.

В аксессор свойства я дополнительный параметр передать не смогу.


 
oxffff ©   (2011-10-25 13:20) [19]


> vuk ©   (25.10.11 13:17) [18]


Тогда просто не нужно объявлять его как static и будет полное счастье.

Объяви просто

class procedure Test;


 
vuk ©   (2011-10-25 13:20) [20]

to oxffff ©   (25.10.11 13:16) [17]:

> Реально путаница для class и class static c точки зрения
> функционирования.

С точки зрения функционирования путаница не там, а в привязке class property к class static в качестве аксессоров.


 
oxffff ©   (2011-10-25 13:22) [21]

Здесь аналогия

На уровне экземпляра

procedure
procedure   virtual;

На уровне метакласса

class procedure
class procedure virtual;

На следующем за  метаклассом уровне

class procedure static


 
oxffff ©   (2011-10-25 13:24) [22]


> vuk ©   (25.10.11 13:20) [20]
> to oxffff ©   (25.10.11 13:16) [17]:
>
> > Реально путаница для class и class static c точки зрения
>
> > функционирования.
>
> С точки зрения функционирования путаница не там, а в привязке
> class property к class static в качестве аксессоров.


Я о том, что слово class перед procedure у static и вводит людей в заблуждение.


 
vuk ©   (2011-10-25 14:57) [23]

to oxffff ©   (25.10.11 13:22) [21]:

> На уровне экземпляра
>
> procedure
> procedure   virtual;

не хватает propery


> На уровне метакласса
>
> class procedure
> class procedure virtual;

class propery должно быть здесь (IMHO)


 
oxffff ©   (2011-10-25 15:45) [24]


> vuk ©   (25.10.11 14:57) [23]
> to oxffff ©   (25.10.11 13:22) [21]:
>
> > На уровне экземпляра
> >
> > procedure
> > procedure   virtual;
>
> не хватает propery


Речь идет о методах.


> > На уровне метакласса
> >
> > class procedure
> > class procedure virtual;
>
> class propery должно быть здесь (IMHO)
>
>


Этого можно достичь на

> > class procedure
> > class procedure virtual;


 
vuk ©   (2011-10-25 16:07) [25]

to oxffff ©   (25.10.11 15:45) [24]:

> Этого можно достичь на

Можно, но property было бы удобнее.


 
han_malign   (2011-10-25 18:20) [26]


> Это просто синтаксис. Test не связан с классом никак, кроме как синтаксически.

- семантика...


 
DVM ©   (2011-10-25 23:23) [27]


> han_malign  

возможно, всегда путаю эти термины



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2013.12.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.003 c
2-1361480816
ttt
2013-02-22 01:06
2013.12.08
Удаление спец. символов


15-1371297794
_oxffff
2013-06-15 16:03
2013.12.08
Javapocalypse


1-1317893740
Бездомный
2011-10-06 13:35
2013.12.08
Чтобы локальные переменные в функциях


15-1371668899
Jeer
2013-06-19 23:08
2013.12.08
Памяти наших Учителей посвящается..


2-1361414339
ixen
2013-02-21 06:38
2013.12.08
dataset не фильтрует время





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский