2009-09-29 27 views

Respuesta

5

Supongo que quiere decir clases estáticas como en .NET (y no "estático" como en Delphi/Native tradicional) - y la respuesta es no.

+2

Quizás esto lo ayude a comprender por qué: las clases estáticas se usan a menudo para encapsular de forma similar a las unidades en Delphi. –

+2

Prefiero no asumirlo. ¿Podrías por favor decir claramente qué * * quieres decir con * estático *? –

4

No estoy muy seguro de lo que quiere decir con una "clase estática". Puede declarar una clase que solo tenga métodos de clase, de modo que estos métodos se puedan invocar sin crear una instancia de la clase.

TSomeClass.SomeMethod; 

¿Eso es lo que quieres?

2

No nativo.

Dependiendo de lo que lo necesite, si para los fines de su código, en algunos casos de uso podría reemplazarlo con un objeto Singleton Pattern.

Para obtener información acerca de cómo implementar esto, recomiendo this guide, que cubre casi cualquier versión de Delphi, pero si usa Delphi 2010 también puede usar el nuevo class Constructors/Destructors para obtener mejores resultados.

1

También puede crear una nueva unidad llamada uDG_Utils, por ejemplo, definir una clase, definir una variable global para esa clase y en la sección de inicialización y finalización administrar el constructor de la clase y el destructor. Ahora todo lo que necesita hacer es llamarlo como mySuperDuperClass.SuperMethod ...

1

Puede crear una clase que contenga nada más que métodos estáticos. Si tiene que mantener algún tipo de estado, las variables de estado se deben pasar como parámetros var. No hay manera de "adecuada" acceder a las variables estáticas otros de tener un conjunto de variables globales en la sección de implementación de la clase fuera del ámbito de la clase, por ejemplo:

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

(Sí, sé que este hilo es viejo, pero pensé en publicarlo para la posteridad.)

Se ha señalado que las funciones de clase y los procedimientos de clase implementan métodos estáticos. Pero agregaré que el siguiente comportamiento notable de una clase estática (frente a una clase Delphi) es que no se puede crear una instancia de una clase estática.

Las clases Delphi obtienen un constructor predeterminado público (sin parámetros) si no especifica uno, por lo que se puede crear una instancia de cualquier clase. Si declara uno o más constructores explícitamente, este constructor no se proporciona.

Puede eliminar todos los constructores declarando un constructor en la sección privada o protegida de su clase. Esto elimina su constructor del alcance del consumidor. Ahora solo hay un constructor, no es visible y no se puede crear una instancia de la clase.

Ejemplo:

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; 

Si usted tiene una de las nuevas versiones de Delphi, se puede considerar también el sellado de la clase sólo para ser un poco más adecuada. Las clases descendientes PODRÍAN crearse instancias si su constructor está protegido en lugar de privado.


Editar

Aquí es una alternativa, inspirado por Ken, para las nuevas versiones de Delphi (que permite usar clases selladas), que no incurre en una pista compilador. Todavía no es una solución perfecta, pero aquí está.

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

El hecho de que tenga que desactivar las sugerencias debería indicarle que este es un código deficiente. –

+0

Está solicitando una característica que no es compatible, por lo que ninguna solución será perfecta. En cuanto a las sugerencias, normalmente estoy de acuerdo y no tolero desactivar las sugerencias. Los consejos suelen ser correctos y señalan errores que pueden ser serios y elusivos. Pero mira más de cerca en este caso. 1- El código no produce ninguna pista en Delphi 7. Entonces, ¿es un código deficiente en Delphi 2010 pero no en Delphi 7? Bien quizás. 2- La advertencia es "declarada pero nunca utilizada". Si cambia el privado a protegido y sella la clase en 2010, .Create todavía está oculto, pero la pista desaparece. ¿Eso lo hace mejor? ... –

+0

... tiendo a pensar que no. Pero déjame ser claro; No creo que estés equivocado, solo que este caso particular es una posible excepción y que creo que es el menor de muchos males, como lanzar una excepción en un constructor público para evitar la creación de instancias. En cualquier caso, incluso este, su punto es válido y no quiero disuadir a nadie de considerarlo. –

5

me gustaría utilizar una clase abstracta (que no debe confundirse con un método abstracto en una clase) para evitar que sea una instancia en lugar de degradar el constructor para proteger:

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

Eso hará cumplir el patrón singleton y previene cualquier período de instancias.

8

Parece que la búsqueda de usuario para "funciones de clase":

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

Esto es como método estático, por lo que, lo llaman:

TSomeClass.MyFunction(...);