write('Введите степень полинома : '); readln(degree);
P := TPolinom.Create(degree);
P.ReadCoeffs;
test := P.C;
TPolinom.PrintCoeffs(test); // <---------------- Вот так нельзя делать ?!
P.Destroy;
readln; end.
volvo
12.10.2006 15:09
А что, собственно, тебя смущает? Ты данные какого экземпляра хочешь напечатать? Из твоей конструкции этого не видно... Вот так - видно:
P.PrintCoeffs(test);
klem4
12.10.2006 15:16
Нет, я хочу вызвать именно метод класса, а не его бъекта, вот как напирмер вызов конструктора
TPlonom.Create(n);
klem4
12.10.2006 15:45
Вот такое в FPC наверняка ведь можно сделать ?
Код
using System; using System.Collections.Generic; using System.Text;
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { TMyClass A = new TMyClass(); TMyClass B = new TMyClass(); TMyClass C = new TMyClass();
Console.WriteLine(TMyClass.GetN()); // result == 3 } }
class TMyClass { public TMyClass() { n++; }
public static int GetN() { return n; }
private static int n; } }
Что-то я запутался. Тут всетаки работа со статическим полем и методом.
volvo
12.10.2006 15:55
Ты про это:
TPolinom = class public constructor Create(const n: Word); destructor Destroy;
procedure ReadCoeffs; CLASS procedure PrintCoeffs(const c: TCoeffs);
function GetDerivative(const c: TCoeffs): TCoeffs; function GetCoeffs: TCoeffs; property C: TCoeffs read GetCoeffs;
private coeffs: TCoeffs; end;
... TPolinom.PrintCoeffs(test); ...
?
klem4
12.10.2006 15:57
Ага а что это значит ?)))
volvo
12.10.2006 16:05
Цитата(ref.pdf)
6.3.3 Class methods Class methods are methods that do not have an instance, but which follow the scoping and inheritance rules of a class. They can be called from inside a regular method, but can also be called using a class identifier:
klem4
12.10.2006 16:13
Все время забываю про этот мануал
Класс
Спасибо !
Altair
15.10.2006 13:47
А в чем смысл вызова метода класса ? Ведь класс является множеством объектов, связанных общностью структуры и поведения. Любой объект является экземпляром класса и имеет индивидуальность, в отличии от класса. Зачем обращаться к сущности, не имеющей индивидуальности ?
klem4
15.10.2006 15:55
Вот ты не прав. Зачем - то же умные люди дали нам возможность так писать программы ... Да и примеров таких методов не мало. Сущность без индивидуальности... это ты куда-то не туда копать начал, мне кажется
volvo
15.10.2006 16:09
Олег, тривиальная задача: посчитать, сколько экземпляров моего класса создано в программе... Твое решение без Class Methods ?
Altair
15.10.2006 22:03
Цитата
это ты куда-то не туда копать начал, мне кажется
Вообще-то индивидульность объекта - одно из фундаментальных принципов ООП....
Цитата
Олег, тривиальная задача: посчитать, сколько экземпляров моего класса создано в программе... Твое решение без Class Methods ?
Спасибо! Идея ясна... т.е. если я верно понял, таким-же образом, например, можно проверить, что создаваемый объект будет с уникальными свойствами, да ?
Иллюстрация: Есть класс ТочкаНаПлоскости. И допустим конструктор при инициализации объекта - экземпляра класса ТочкаНаПлоскости, задает координаты точки случайно... Тогда, что бы например, при инициализации проверить что точка не совпадет ни с какой другой можно использовать метод класса, который проверит есть ли экземпляры с такими свойствами...
Иллюстрация верна ?
volvo
15.10.2006 23:42
Цитата
можно использовать метод класса, который проверит есть ли экземпляры с такими свойствами...
То, что выделено красным - несовместимо...
Понимаешь, в чем дело... В Class Method-е ты не можешь обращаться к данным класса/НЕ-классовым методам/свойствам... По одной простой причине: в момент, когда ты вызываешь Class Method у тебя может не быть ни одного экземпляра класса. То есть, проверить что-либо, касаемое экземпляров именно этого класса у тебя не выйдет.
Вот еще один классический пример использования: НДС (ну, или любой другой налог), взимаемый за, скажем, услугу, описываемую типом T, изначально равен 17%... В какой-то момент этот налог увеличивается. При инициализации нового экземпляра класса мы должны увидеть новое значение налога, и при обработке информации, связанной с T (!!!), тоже будет рассматриваться новое значение. Что делаем?
{$mode ObjFPC} unit unit_1;
interface
type T = class constructor init();
class procedure set_VAT(vat_value: double); end;
implementation
var VAT: double = 0.17;
constructor T.init(); begin writeln('VAT = ', VAT:10:5); end;
class procedure T.set_VAT(vat_value: double); begin VAT := vat_value; end;
end.
Используем так:
uses unit_1;
var obj_1, obj_2: T;
begin obj_1 := T.init(); T.set_VAT(0.19); obj_2 := T.init(); ... end.
Я знаю, что ты скажешь: "А почему бы не просто функция (вообще вне класса), которая будет изменять переменную? Или вообще напрямую изменять переменную, безо всяких функций... Зачем навороты?" Так?
Не так... То, что напрямую - это нарушается принцип упрятывания информации, значит придется работать-таки через какой-то интерфейс. Простая функция? Да ни в коем случае... Я же сказал, что VAT - это налог за услугу T, а если будет 2 услуги? T и R, например? Налог на T один, на R - другой... Почему не просто метод в классе T? Потому, что у меня может не быть ни одного экземпляра инициализировано, а придется менять VAT. Создавать временный экземпляр, а потом удалять его - глупо.
Поэтому делаем Class Procedure, и программа становится прозрачной... Даже если у меня уже и есть инициализированные экземпляры класса T, я предпочту сделать НЕ так:
obj_1.set_VAT(0.19);
, а вот так:
T.set_VAT(0.19);
, потому, что налог распространяется НЕ на один какой-то экземпляр услуги, а на весь ее тип !!!
Понимаешь, в чем вся идея? Ты пользуешься Class Method-ами тогда, когда тебе нужно сделать что-то, что характерно НЕ для экземпляра, а в целом для класса...
klem4
30.01.2007 15:00
А можно на fpc написать именно аналог кода приведенного мною на шарпе ? Чтобы для всех экземпляров существовала единая статическая переменная - счетчик, которая находилась бы внутнри описания класса ?
Или на обжэкт паскале такое нельзя замутить ?
Добавлено через 5 мин. 42 сек. В сети пока везде нахожу только один и тотже пример на подобии приведенного volvo (размещать счетчик ну или просто какую-то общую переменную в имплементейшн разделе модуля)
Inside a class method, the self identifier points to the VMT table of the class. No fields, properties or regular methods are available inside a class method. Accessing a regular property or method will result in a compiler error. The reverse is possible: a class method can be called from a regular method. ... Class methods cannot be used as read or write specifiers for a property.
Именно поэтому приходится работать не с полями класса, а с внешней (по отношению к классу) переменной...
volvo
30.01.2007 17:01
Хотя, естественно, обмануть компилятор можно:
{$mode ObjFPC} type T = class
constructor init();
class function count(access: boolean): integer; class function get_count(): integer;
end;
constructor T.init(); begin count(true); end;
class function T.count(access: boolean): integer; const counter: integer = 0; begin if access then inc(counter); count := counter; end;
class function T.get_count(): integer; begin get_count := count(false); end;
{ main } const n = 10; var arr: array[1 .. n] of T; i: integer;
begin for i := 1 to 7 do arr[i] := T.init();
writeln(T.get_count(), ' init calls ...'); end.
klem4
30.01.2007 17:52
Здорово
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.