2009-09-29 15 views

Odpowiedz

5

Zakładam, że masz na myśli klasy statyczne, takie jak w .net (i nie "statyczne" jak w tradycyjnym Delphi/Native) - a odpowiedź brzmi "nie".

+2

Może to pomoże ci zrozumieć, dlaczego: Klasy statyczne są często używane do enkapsulacji w sposób podobny do jednostek w Delphi. –

+2

Wolałbym nie zakładać. Czy możesz sprawić, by było oczywiste, co znaczy * ty * przez * statyczny *? –

4

Nie jestem do końca pewien, co rozumiesz przez "klasę statyczną". Możesz zadeklarować klasę, która ma tylko metody klasy, więc te metody można wywołać bez tworzenia instancji klasy.

TSomeClass.SomeMethod; 

Czy tego chcesz?

2

Nie.

W zależności od potrzeb, jeśli dla potrzeb kodu, w niektórych przypadkach można go zamienić na obiekt wzoru Singleton.

W celu zapoznania się z tą implementacją, polecam this guide, która obejmuje prawie każdą wersję delphi, ale jeśli używasz Delphi 2010, możesz również użyć nowego class Constructors/Destructors w celu uzyskania lepszych wyników.

1

Można także utworzyć nową jednostkę o nazwie uDG_Utils na przykład, zdefiniować klasę, zdefiniować globalną zmienną dla tej klasy, aw sekcji inicjalizacji i finalizacji zarządzać konstruktorem klasy i destruktorem. Teraz wszystko, co musisz zrobić, to nazwać go mySuperDuperClass.SuperMethod ...

1

Można utworzyć klasę, która zawiera tylko statyczne metody. Jeśli musisz utrzymywać pewien stan, to zmienne stanu powinny być przekazywane jako parametry var. Nie ma sposobu, aby „właściwie” dostęp do zmiennych statycznych inne niż posiadające zestaw zmiennych globalnych w dziale realizacji klasy poza zakresem klasy, na przykład:

UNIT TestUnit; 

INTERFACE 

Type 
    TStaticClass = Class 
    public 
    procedure Foo(var Bar:String); static; 
    end; 

IMPLEMENTATION 

var 
    LastBar : String; // the last bar 
    LastRes : string; // the last result 

Procedure TStaticClass.Foo(var Bar:String); 
begin 
    if Bar <> LastBar then 
    LastRes := SomeCPUExpensiveProcess(Bar); 
    LastBar := Bar; 
    Bar := LastRes; 
end; 

INITIALIZATION 
    LastBar := ''; 
    LastRes := SomeCPUExpensiveProcess(''); 
END. 
-1

(Tak, wiem, że ten wątek jest stary, ale pomyślałem, że opublikuję to dla potomności.)

Zwrócono uwagę, że funkcje klasowe i procedury klasowe implementują metody statyczne. Dodam jednak, że następnym zauważalnym zachowaniem klasy statycznej (w porównaniu z klasą Delphi) jest to, że klasa statyczna nie może być utworzona.

Klasy Delphi otrzymują publiczny domyślny (bez parametrów) konstruktor, jeśli nie zostanie określony, więc można utworzyć instancję dowolnej klasy. Jeśli jawnie zadeklarujesz jeden lub więcej konstruktorów, ten konstruktor nie zostanie dostarczony.

Możesz usunąć wszystkie konstruktory, deklarując konstruktor w prywatnej lub chronionej sekcji swojej klasy. To usunie twojego konstruktora z zakresu konsumenta. Teraz jest tylko jeden konstruktor, nie jest widoczny i nie można utworzyć instancji klasy.

Przykład:

type 
    TMyStaticClass = class(TObject) 
    private 
    // Hide the default constructor, suppressing hint H2219. 
    {$HINTS OFF} constructor Create; {$HINTS ON} 
    public 
    class procedure Method1; // A static method 
    end; 

implementation 

constructor TMyStaticClass.Create; 
begin 
    // Do nothing. This cannot be called. 
end; 

class procedure TMyStaticClass.Method1(); 
begin 
    // Do something here. 
end; 

Jeśli masz jedną z nowszych wersjach Delphi, można również rozważyć uszczelnianie klasę po prostu być nieco bardziej właściwe. Klasa potomna MOŻNA utworzyć instancję, jeśli Twój konstruktor jest chroniony, a nie prywatny.


Edit

Oto alternatywa, inspirowany przez Kena, nowsze wersje Delphi (które obsługują klas zamkniętych), który nie ponosi wskazówkę kompilatora. To wciąż nie jest doskonałe rozwiązanie, ale oto jest.

unit Unit1; 

interface 

type 
    TMyStaticClass = class sealed (TObject) 
    protected 
    constructor Create; 
    public 
    class procedure Method1; // A static method 
    end; 

implementation 

constructor TMyStaticClass.Create; 
begin 
    // Do nothing. This cannot be called. 
end; 

class procedure TMyStaticClass.Method1(); 
begin 
    // Do something here. 
end; 

end. 
+2

Fakt, że musisz wyłączyć podpowiedzi, powinien Ci powiedzieć, że to kiepski kod. –

+0

Pyta o funkcję, która nie jest obsługiwana, więc żadne rozwiązanie nie będzie idealne. Co do podpowiedzi, zwykle zgadzam się i nie akceptuję wyłączania podpowiedzi. Wskazówki zazwyczaj mają rację i wskazują błędy, które mogą być poważne i nieuchwytne. Ale przyjrzyj się bliżej tej sprawie. 1- Kod generuje wskazówkę NIE w Delphi 7. Czy jest to zły kod w Delphi 2010, ale nie w Delphi 7? Być może. 2- Ostrzeżenie jest "zadeklarowane, ale nigdy nie używane". Jeśli zmienisz prywatny na chroniony i przypieczętujesz klasę w 2010 roku, opcja .Create jest nadal ukryta, ale podpowiedź zniknie. Czy to czyni lepiej? ... –

+0

... Nie myślę. Ale pozwól mi być jasnym; Nie wydaje mi się, że jesteś w błędzie, tylko że ten konkretny przypadek jest możliwym wyjątkiem i uważam, że jest to mniejsze zło, takie jak odrzucenie wyjątku w publicznym konstruktorze, aby zapobiec tworzeniu instancji. W każdym razie, nawet ten, twój punkt jest ważny i nie chcę zniechęcić nikogo do rozważenia go. –

5

chciałbym użyć klasy abstrakcyjnej (nie mylić z abstrakcyjnej metody w klasie), aby zapobiec jego wystąpienia jest zamiast obniżania konstruktora chronione:

TMyClass = class abstract 
public 
    class procedure DoStuff; static; 
end; 

To wymusi wzór singletonowy i zapobiegać okresowi tworzenia.

8

Wygląda poszukiwaniu użytkownika za „funkcje klasy”:

type 
TSomeClass = class 
class procedure MyFunction(...); 

To jest jak metoda statyczna, więc nazywają go:

TSomeClass.MyFunction(...); 
Powiązane problemy