Clases estaticas

Hola companeros, alguien de ustedes me podria proporcionar enlaces o explicarme en profundidad lo que son las clases estaticas, me refiero a las clases no a los miembros y metodos estaticos, por ejemplo cuando algo empieza public static class, y tambien tengo dudas cuando son estaticas internas.
Desde ya muchas gracias
Saludos a todos.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

dos cosas

Estas preguntando dos cosas: clases estaticas y metodos estaticos.

Hasta donde tengo entendido, las clases estaticas solamente tienen sentido cuando son internas. Si declaras clases internas (una clase dentro de otra clase) y la interna no es estatica, solamente puedes crear y manejar instancias de una clase interna dentro de metodos de la clase externa, porque las instancias de la clase interna dependen de la instancia externa. Pero si declaras la clase interna como static entonces puedes crear instancias de la clase interna que no dependen de una instancia de la clase externa.

Los metodos estaticos no dependen de ninguna instancia, sino de la clase misma. Solamente los puedes invocar a partir de la misma clase; si tienes tu clase Objeto que declara un metodo estatico metodo() puedes invocarlo directamente sobre la clase. Si decides invocarlo sobre una instancia, se llama de todas maneras directamente sobre la clase. Los metodos estaticos no se heredan, a diferencia de los metodos de instancia (o como se llamen; me quede con ese "de instancia" porque estuve mucho anios en ObjC donde realmente habia metodos de instancia y metodos de clase).

Imagen de fcodiaz

los metodos static's si se heredan

@ezamudio ... los métodos estáticos si se pueden heredar, obviamente funcionan de la misma forma que desde su clase padre, pero si puedo tener un método estático "metodoEstatico" en una clase A y una clase B q haga un extend a A, y llamar en una clase C a B.metodoEstatico(), incluso se puede heredar una clase estática y algo loco que se me ocurrió y funciono, que la clase estática interna heredara de su clase "contenedora" dando unos resultados algo locos, lo que me gusta de la programación es que se te ocurre algo loco lo haces, compilas y cores si funciona es que es posible:
class A

public class A {
    static class subA extends A{
        @Override
        public String toString(){
            return "Sub A";
        }
    }
    static void saludo(){

        System.out.println("saludo");
    }
}

class B

public class B extends A {
   public class classNoEstatic{
        @Override
        public String toString() {
            return "un clas interna no estatatica";
        }
    }
}

class C

public class C {
    public static void main(String[] args) {
        B.saludo();
        A.subA sb = new B.subA();
        System.out.println(sb);
        //se me ocurrio algo loko!

        B.subA.subA.subA.subA.subA.saludo();//y puedo entrar a mas subA's :S
        //B.classNoEstatic objSubB=B.classNoEstatic();//<=esto no funciona
        /**/
        /* esto tampoco funciona:
        B b = new B();
        b.classNoEstatic csubB= b.classNoestatic();
        */

    }
}

la verdad no veo mucho caso lo de las clases static's internas , mas que como una clase contenedora de otra la cual no necesito instanciar su contenedora para crear una instancia de esta lo cual estaria funcionando exactamente igual que un package, ahora lo que observe es que si se crea una clase interna no estatica no hay forma de instanciar esta subClase en otras clases, ya que en un Objeto puedo ver sus propiedades y metodos pero no ve las subClases esto hace que esa clase aunque sea public no la pueda instanciar fuera de la clase, en cambio una interna static si se puede instanciar.

Imagen de ezamudio

clases estáticas internas

Generalmente se usan cuando implementas algún API y tienes una clase interna privada cuyas instancias necesitan existir sin depender de una instancia de la clase contenedora.

En esos casos no puedes invocar variables de la clase contenedora como si fueran de la clase interna, es casi como una clase normal.

Imagen de ezamudio

Métodos estáticos

No sé cómo hiciste eso que dices de los métodos estáticos, pero no, no se heredan porque no existe "super" en un contexto de método estático. Esto no compila:

public class Padre {

  public static String metodo() {
    return "padre";
  }

}

public class Hijo extends Padre {

  public static String metodo() {
    return super.metodo() + " e hijo";
  }

}

Al compilar Hijo.java te da esto:

Hijo.java:4: non-static variable super cannot be referenced from a static context
        return super.metodo() + " e hijo";
               ^

Si lo modificas para llamar Padre.metodo() en vez de super.metodo() entonces ya funciona, pero eso ya no es herencia, porque cualquier clase puede llamar Padre.metodo() aunque no extienda Padre.

Contestando tu pregunta

La palabra static, solo puede ser usada en clases cuando esta es una clase anidada. Por ejemplo lo siguiente es inválido:

public static class SomeStatic {
}

Por lo tanto solo pueden ser utilizadas dentro de otra clase, lo siguiente es válido:

public class SomeOuterClass {
    public static class SomeStatic {
    }
}

Usar static en este contexto hace lo "mismo" que sobre un atributo o un método, en el sentido que lo puedes usar sin una instancia de la clase.

Al igual que los atributos y métodos, para ser usados, necesitan que se "mencione" la clase englobadora y al igual que los atributos y metodos pueden ser importados con import static

ejemplo:

// Outer.java
package some.outer.packagename;

public class Outer {
     public static class Nested {
         public static void toing(){
             System.out.println("ToooooOOOoooOing");
         }
         public void nonStaticMethod() {
             System.out.println("Ok, ok");
         }
     }
}
//Usage.java
package some.other.packagename;

import static some.outer.packagename.Outer.Nested; // <-- El import es: "import static" y se incluyen ambas: Outer.Nested

public class Usage {
    public static void main( String  [] args ) {
        Nested.toing(); // <-- invoking static method of nested class
        Nested nested = new Nested(); //<-- create instance just like any other "top level" class
        nested.nonStaticMethod(); // <-- invoking instance method of nested class  
    }
}

Si te fijas en el código, una clase anidada (static class) funciona igual que una clase normal: puede tener a su vez, métodos estáticos ( o de clase ) y puede tener también métodos no estáticos ( o de instancia ) igualito que cualquier otra clase.

Si quieres usarlo sin import static, debes de incluir la clase externa. Este es el equivalente:

package some.other.packagename;

import some.outer.packagename.Outer; //<-- No static import

public class UsageTwo {
    public static void main( String  [] args ) {
        Outer.Nested.toing(); // <-- invoking static method of nested class. Name of Outer class is included
        Outer.Nested nested = new Outer.Nested();  //<-- using new must include name of Outer class too
        nested.nonStaticMethod(); // <-- rest is the same
    }
}

Si notas, a diferencia de clases normales, tienes que incluir el nombre de la clase externa en este caso: Outer

Para usarlo sin import alguno ( usando el nombre completo ) sería así:

package some.other.packagename;

public class UsageThree {
    public static void main( String  [] args ) {
        some.outer.packagename.Outer.Nested.toing();
        some.outer.packagename.Outer.Nested nested = new some.outer.packagename.Outer.Nested();
        nested.nonStaticMethod();
    }
}

El nombre completo de esta clase es: some.outer.packagename.Outer.Nested

¿Por qué utilizar las clases anidadas?

Aquí se listan varias razones y se explica más acerca de las clases anidadas y de sus hermanas, las clases internas y las clases anónimas internas:

http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

Lee esa página si tienes dudas, puedes regresar acá y vemos si las podemos aclarar.

Byte!

Imagen de fcodiaz

super es como si fuera this ¬¬

@ezamudio super no va a funcionar en un método estático, ya que este es el equivalente de "this" para recuperar propiedades sobrescritas de la clase padre, y a lo que me refiero con poder heredar, es que puedo extender una clase A llevando sus métodos (incluyendo los estaticos) a la clase B y agregarle métodos tanto estáticos como normales, hasta donde se "extends" define herencia , no super este seria un "defectito de java" :S, digamos que soporta herencia de metodos estaticos a medias :S

ahora en el caso de sobre escritura de métodos/propiedades la verdad no se como podría decir que ejecutara un método sobrescrito pero con la versión padre (lo que intentas hacer) al hablar de statics nos olvidamos que manejamos objetos ya que estos solo refieren a las clases, regularmente super se usa para inicialización de un Objeto cuando su padre tiene un costructor que debe de ser invocado este tema no nos importa por que no somos parte de uno

algo que me extraña en java aunque analizado su arquitectura es razonable, es que no hay una palabra para referirse a la clase misma desde un método estático ( o no conozco y no he dado con ello), yo manejo mucho PHP, en este se utiliza la palabra "sellf" para referirse a la clase que se esta defiendo desde un método estático seria el equivalente de $this pero como sabemos this es al Objeto un metodo estatico no puede ver el Objeto por que no es parte de uno, en Java no lo he encontrado, incluso PHP si logra hacer lo que intentas, tener una herencia sobrescribir el método statico y aun tener visible el meotodo estático del padre, creo que es la primera ves que veo que PHP trae algo que java no o que no lo he visto

<?
header("content-type:text/plain");
class A {
    protected $a;
    public static function suma() {
        return 1+2;
    }
    public function __construct($a) {
        $this->a=$a;
    }

}

class B extends A {
    public static function suma() {
        return 5+6;
    }
    public function __construct($a) {
        parent::__construct($a);
        echo $this->a."\n";
    }
    public static function supersuma() {
        return parent::suma();
    }
}
new B("b");//out: b
echo B::suma()."\n";//out: 11
echo B::supersuma();//out: 3
?>

pero bueno aquí el tema es Java... pero si alguien encuentra como hacer esto, ps me dice por que no es la primera vez que busco "self" en la versión Java

y la aplicacion, creo que no es mas que una forma de encapsular clases lo que comenta @OscaRyz incluso se pueden importar las clases estáticas, creo que el único beneficio sobre un Package es que pudieran compartir propiedades static en la clase Padre, aunque creo que el mismo efecto tendría con la herencia de métodos etaticas

Aquí lo que se me ocurre, tener dos clases estaticas, y las tres compratir una propiedad:

public class A {

    protected static int b;
    public static void printB() {
        System.out.println(b);
    }

    public static class subA2 {
        protected int getB() {
            return b;
        }
    }

    public static class subA {
        protected void setB(int pb) {
            b = pb;
        }
    }
}

package b;
import b.A.subA;
public class Main {
    public static void main(String[] args) {
        subA a = new subA();
        a.setB(10);
        A.printB();//out: 10
        System.out.println( new A.subA2().getB() );//out: 10
    }
}

o Bien con herencia también funciona

package lokerasConHerencia;
/**
 *
 * @author pakos
 */

public class A {
    protected static int b;
    public static void printB() {
        System.out.println(b);
    }
}
package lokerasConHerencia;

/**
 *
 * @author pakos
 */

public class B extends A{
    protected int getB() {
            return b;
    }
}

package lokerasConHerencia;

/**
 *
 * @author pakos
 */

public class C extends A{
    protected void setB(int pb) {
            b = pb;
    }
}

package lokerasConHerencia;

/**
 *
 * @author pakos
 */

public class Main {
    public static void main(String[] args) {
        C c = new C();
        c.setB(10);
        A.printB();//out: 10
        System.out.println( new B().getB() );//out: 10
    }
}

Imagen de fcodiaz

:o esto si no se puede con herencia

:o.. buscandole mas buelta a la aplicacion de clases abstractas, ya dije que puede ser un caso en que varias clases compartan un dato lo cual también hice con una herencia, pero si este dato fuera privado no lo podria ver en los extends o amenos que fuera protected o public, la clase estaticas internan tienen acceso incluso a los elementos private que la contienen :o

Imagen de bferro

Los métodos estáticos no son "realmente métodos"

La herencia en los lenguajes orientados a objetos se refiere al comportamiento de los objetos.
Si ese comportamiento se implementa en métodos, entonces los "métodos estáticos" no son métodos, pues no se refieren al comportamiento de los objetos.
La bronca viene al decidir Java eliminar del repertorio heredado de C++, las funciones globales y en particular las funciones globales amigas de clases.
Decide Java que todo código debe ser encapsulado en clases, siendo la clase el módulo principal de su estilo de programación, y tiene entonces que buscar un mecanismo para poder llevar al programa algo valioso como las funciones amigas. Deciden entonces utilizar el término static para esos fines, siguiendo la idea de C y C++ de usar esa palabra para limitar el contexto de un bloque de código. Por ejemplo, las funciones estáticas en C, son vistas únicamente por otras funciones en l mismo módulo objeto y no aparecen en la tabla de símbolos.
Surgen entonces los métodos estáticos, que en efecto NO se heredan porque no representan comportamiento de los objetos y para ellos no aplican las reglas del polimorfismo basado en la herencia que es el úniico tipo de polimorfismo que Java soporta.

Son muchas las clases en Java que únicamente están compuestas por funciones estáticas. Y aquí entonces Java se mete en el problema de usar el concepto de clase para algo que no tiene que ver con llevar al lenguaje, entidades del dominio del problema.
Un caso típico es la clase java.lang.Math compuesta exclusivamente por funciones matemáticas "globales". Por supuesto que "se preocupan" de anunciar de que Math realmente no es una clase desde el punto de vista conceptual, y escriben su constructor privado.

Las clases estáticas llevan al lenguaje otro concepto importante. En el siguiente post me referiré a ellas.

Imagen de bferro

Clases anidadas (estáticas anidadas e interiores)

A pesar de poner en la misma bolsa (nested classes) a las clases estáticas anidadas y a las clases interiores, se trata de dos conceptos diferentes.
Cuando me refiero a ellas, prefiero usar el término clase anidada exclusivamente para las clases estáticas anidadas y el de clases interiores para las inner classes.

Las clases estáticas anidadas resuelven un problema similar al concepto de paquete en Java. Se trata de dos mecanismos de agrupación que persiguen dos objetivos: el de administrar el espacio de nombres y el de crear categorías de clases. Si el objetivo solamente fuera el de crear espacios de nombres, entonces no habría necesidad de utilizar la visibilidad de paquete o visibilidad de default que Java soporta. Aquellos elementos que no están modificados de forma explícita por un modificador de visibilidad (private, protected) tienen entonces la visibilidad de paquete, y es ahí donde entra la idea de categorizar las clases en paquetes de acuerdo a su nivel de colaboración entre ellas.
Muchas clases en diversos paquetes tienen esa visibilidad de default porque están diseñadas para colaborar exclusivamente con las clases del mismo paquete. Son "desconocidas" para el mundo externo. Entre todas forman una categoría de clases destinada a resolver un problema mayor que el que resuelven cada una de ellas y ofrecen al mundo externo alguna clase pública para utilizar la funcionalidad que implementan.

Algo similar sucede con las clases anidadas estáticas, aunque en este caso se persiguen también otros propósitos que se unen al objetivo de agrupamiento lógico.
Tres propósitos muy usados son:
Utilizar clases privadas estáticas anidadas que implementen interfaces y que la clase Outer ofrezca (mediante métodos públicos) objetos de esas clases a programas que están basados en esas interfaces. De esta manera ocultamos la implementación de esas interfaces.
Programar colaboraciones entre objetos. Digamos que el Objeto a:A necesita colaborar con el objeto b:B, y que queremos establecer la restricción que los objetos de clase B se creen exclusivamente para esa colaboración (que no quiere decir lo mismo que ellos viven en el contexto de los objetos de clase A lo que logramos con las clases interiores).
Hacerle ver al programador, mediante la sintaxis la colaboración entre clases. Es el caso de las clases estáticas anidadas públicas, que son frecuentes en el API de Java

Imagen de fcodiaz

@bferro algunas preguntas..

@bferro, entonces tengo algunas preguntas... si afirmas los métodos estáticos no son métodos., ¿cual es su termino correcto?, serian algo como funciones pero estas están encerradas en una clase, lo que me regresa al concepto de Método,

si los métodos statics o como se llamen no se heredan como se llama lo que hago en los ejemplos con extends?, y bien puedo sobreescribir el mismo método en dos clases "hijas" o que extienden a la primera si no le queremos llamar herencia y tener en dos clases distitas el mismo "método" con diferente comportamiento y mismo nombre (polimorfismo), con la excepción que le comentaba a @ezamudio de no poder referir desde la clase "hijas" a la clase base, digo si se puede hacer por que los ejemplos los codifique y corrí y funciona tal como deberían y tienen los mismos efectos que se supondrían con la teoría de herencia, entonces esto debe de tener un nombre, pero me dices que no es herencia, ¿entonces cual es su termino?, yo creo que es herencia aunque enfocada a los métodos static's ,

te pregunto esto de buena manera, la verdad soy programador "nato" solo leo la documentación que voy requiriendo, se podría decir que java lo he aprendido en semi-automático a partir de la teoría de otros lenguajes que manejo y la teoría genérica de OOP y no he leido ni un libro ni totorial de inicio a fin por que todos traen un mundo de teoria que ya domino y termino botandolos antes de la pagina 100, y lo que afirmo es por que lo estoy viendo compilar sin problemas y funcionar, tal ves esto tienen algún termino diferente, pero aquí ¿cual es este termino?

Imagen de luxspes

los metodos estaticos si son metodos

La herencia en los lenguajes orientados a objetos se refiere al comportamiento de los objetos.

Mmmm, no solo al comportamiento... tambien el estado (los miembros dato) se pueden heredar...

Si ese comportamiento se implementa en métodos, entonces los "métodos estáticos" no son métodos, pues no se refieren al comportamiento de los objetos.

Los metodos estaticos, son metodos, aunque no esten ligados directamente a una instancia de una clase (objeto), no por ser estaticos dejan de ser metodos. (Por otro lado hubiera sido mejor que Java hubiera evitado crear una aberracion como los metodo estaticos y mejor hubiera manejado una sintaxis como la de la palabra clave object de Scala, dandole asi soporte nativo al patron Singleton en el lenguage, pero esa es otra historia)

Imagen de luxspes

Polimorfirsmo: Imposible con metodos static

@bferro, entonces tengo algunas preguntas... si afirmas los métodos estáticos no son métodos., ¿cual es su termino correcto?, serian algo como funciones pero estas están encerradas en una clase, lo que me regresa al concepto de Método,

Como dije antes, los metodos estaticos si son metodos

si los métodos statics o como se llamen no se heredan como se llama lo que hago en los ejemplos con extends?,

Lo que pasa es que herencia no es nomas poner extends y que los metodos de la clase base esten disponibles en la derivada, tambien es comportamiento polimorfico, y los metodos static no tienen comportamiento polimorfico. Por eso Scala no tiene statics, por que las statics eliminan el comportamiento polimorfico, que es el objetivo principal para hacer herencia o para implementar interfaces, los metodos static son uno de los grandes errores de diseño en Java, no deberian existir, pero ni modo, estan ahi, y en muchos casos no queda de otro mas que usarlos por ya hay APIs implementadas que los usan, en mi opinion, el unico caso en el deberian utilizarse, es para implementar el patron Singleton en Java

Imagen de fcodiaz

yo los uso en el caso

bueno pues entonces, en el caso de la pseudoherencia o sigo esperando el termino técnico correcto por que se puede hacer, se puede codificar compilar y ejecutar, lo unico que no se puede hacer es llamar al metodo base por que no tengo una palabra para acceder al static de la clase base y el que hablamos en referencia de la clase y no a las instancias de estas, pero un metodo estatico se puede

- extender a otras clases
- sobreescribir los metodos/propiedades en las clases que extienden a la base
- puedo exteder a dos o tres clases, tener un mismo metodo que funcione distito en cada una y de igual tenerlo definido en la base
lo que es lo mismo en los metodos normales pero no se puede
- invocar al metodo base
- tener acceso a la clase base

creo que con esos dos detalle yo no le denaria de llamar herencia o afirmar que no se heredan, es como decir que java no es orientado a objeto por que le falta la herencia múltiple o por que implementan mal alguna otro tipo de teoría del paradigma, entiendo su punto, pero si no es herencia ¿que es?.. una aberración en el diseño, ok pero ¿como se llama?.

bueno ahora el uso, en el caso de métodos, que no solo están en el diseño de Java también en PHP aunque si podemos tener una función fuera de cualquier clase =), en este post PHP sale muy alagado frente a Java Jajaja.. perdon soy PHPero sobre Javero la vdd... y por lo generar Java se jode a PHP..

bueno les decía.. por ejemplo yo tengo una clase cliente, lo que espero yo en codificación es que al crear un cliente este tenga un nombre, una dirección, el método comprar, entrar al sistema, salir del sistema, cada que creo una instancia de cliente se define directamente a un cliente.. pero que pasa cuando necesito por ejemplo un array de clientes, no lo voy a crear en mi programa principal, no puedo crear un función fuera de una clase, es aquí cuando me acuerdo de la palabra static, y es donde decido colocar este tipo de métodos dentro de x o y clase, en mi ejemplo el método listarClientes que me retorna un Array de Clientes, lo colocaría en la clase Cliente.listarClientes() por que me regresa un conjuto de Clientes pero no necesito instaciar uno para pedir ejecutar este método, así tengo mi método en un lugar adecuado y dentro una clase que de entrada define un tanto su comportamiento y tampoco tengo una función volado por algún lugar si ningún orden,

tambien la uso para tener datos compartidos, cuando dos instancias de una misma clase tienen que referirse a un dato comun que comparten, en lugar de tener una variable global que creo es mas aberrante, se tiene una variable compartida entre las instancias de una misma clase..

en el caso de clases abstractas, no le veo sentido de uso la verdad, por que tal pareciera que no es mas que usar una clase como pakage con la única diferencia y "ventaja" que les mencione antes, el tener acceso a los métodos y propiedades privadas de la clase que los envuelven, pero de cualquier forma no concibo muy bien este tipo de anidamiento, la verdad no le veo mucho caso, contrario a las clases internas que solo son visibles y utilizadas en la misma clase

Imagen de ezamudio

DAO

Creas un ClienteDAO (preferentemente una interfaz y aparte una implementación con tu ORM favorito o en tu caso que no te gustan los frameworks, creas el tuyo propio usando JDBC puro). El DAO tiene un método listarClientes(). Donde sea que necesites obtener la lista de clientes, creas un ClienteDAO o mejor aún obtienes una referencia a un ClienteDAO existente y le invocas listarClientes() para obtener la lista.

No se considera una buena práctica que la clase Cliente tenga un método estático listarClientes(). Estás mezclando los objetos de entidad con los objetos de acceso a datos.

Las clases abstractas son bastante útiles para casos en que ya tienes definido un comportamiento base pero que es extendible a ciertas implementaciones; puedes tener una interfaz que define los métodos, una clase abstracta que implementa lo más básico y algunas cosas de conveniencia (ciertas propiedades que no defina la interfaz por ejemplo). Un programador tiene la opción de implementar la interfaz desde cero o bien de extender la clase abstracta y solamente implementar lo que le falta específico a su problema.

Lo de la herencia por lo visto no habrá manera de convencerte porque es cosa de cómo lo estás percibiendo, pero técnicamente los métodos estáticos no se heredan; cuando dices que extiendes un método estático de una clase base, realmente sólo estás implementando un método estático en tu subclase, que tiene el mismo nombre del método estático de su superclase, y para "extenderlo" invocas al método estático de la clase base en el método estático de la subclase. La cosa es que para invocar al método de la superclase tienes que usar el nombre de la clase directamente, como ya dijimos no hay "super" ni nada que se le parezca:

public class A {
  public static String metodo() { return "A"; }
}

public class B extends A {
  public static String metodo() { return A.metodo() + "B"; }
}

Eso no es herencia; así como llamas A.metodo() podrías llamar CualquierOtraClase.metodoEstatico(); si solamente ves el código de B.metodo(), no hay nada que indique que A es superclase de B. Compáralo con herencia normal:

public class A {
  public String metodo() { return getClass().getName(); }
}
public class B extends A {}

En este segundo caso, si llamas metodo() sobre un objeto de la clase A obtendrás la caden a"A", pero si lo invocas sobre un objeto de la clase B, obtendrás la cadena "B" y ni siquiera tuviste que reimplementarlo, porque se hereda. No hay manera de hacer algo así en un método estático.

Compáralo con los métodos de clase en Objective-C, que sí se pueden heredar, extender y sobreescribir (hago una mezcolanza para no tener que poner toooodo el código de ObjC):

@implementation A : NSObject

+ (NSString *)metodo {
  return [[self class] description];
}

@end

@implementation B : A

+ (NSString *)metodo {
  return [NSString stringWithFormat:@"%@ y B", [super metodo]];
}

@end

@implementation C : B

@end

Ahí la palabra reservada "super" en los métodos de clase tiene un significado similar al que tiene en los métodos de instancia, pero se refiere a la superclase. Si invocas [A metodo] vas a obtener "A"; si invocas [B metodo] vas a obtener "B y B" y si invocas [C metodo] vas a obtener "C y B". Esto es porque el método se hereda igual que un método de instancia (como cualquier método no estático en Java; si haces getClass().getName() siempre te dará el nombre de la clase en donde se invoca el código, no donde fue definido el método).

Pero en Java no hay métodos de clase, solamente estáticos, y lo único que tienen cercano a herencia es que si defines un método estático en la clase A, y luego tienes una clase B que extiende A, puedes invocar el método estático de A haciendo referencia a la clase B, es decir B.metodoEstaticoDefinidoEnA() pero eso es todo; no hay una cadena de herencia de modo que C herede de B que hereda de A y que C pueda extender un método estático definido en A sin hacer referencia directamente a la clase A.

Imagen de bferro

Sigo con los métodos estáticos

Algunas precisiones a lo comentado sobre lo estático.

1.
@fcodiaz, @luxpes: Cuando digo que los métodos estáticos NO son "realmente métodos" (noten que lo pongo entre comillas), es para expresar que si la palabra o término método, la utilizo para expresar lo que en el lenguaje usamos para implementar el comportamiento de los objetos, entonces NO son métodos los estáticos. Ya nos acostumbramos a llamarles métodos estáticos. No importa siempre que nos quede claro esto. Cada cual puede usar el término que desee.

2.
@fcodiaz: Que los métodos estáticos (o como se les quiera llamar) se encapsulan dentro de la clase es una decisión del lenguaje para lograr que funciones que no se aplican a los objetos, puedan tener acceso a la implementación de los mismos, pero nunca a través del this. Otros lenguajes lo hacen de otra manera e inclusive algunos no incluyen esas facilidades. Es el caso de las funciones amigas en C++ y otros lenguajes.

3.
@luxpes: Cuando digo que "la herencia en los lenguajes orientados a objetos se refiere al comportamiento de los objetos" se incluye por supuesto el estado de los mismos. Nuna escribimos datos miembro si ellos no se utilizan en el código que implementa el comportamiento de los objetos.

4.
@luxpes: Aunque los métodos estáticos se usan en Java para hacer a una clase Singleton, también se usan para otras cosas útiles que por supuesto que se pueden hacer de otra manera. Como comentaba con anterioridad, hay lenguajes que no soportan los métodos estáticos. Más allá de ser usados para implementar una clase Singleton, no hay otra relación entre los dos conceptos. Que Scala no use lo estático no implica que sea una aberración, aunque es opinión de cada uno. Recordemos que Java y C (que muchos consideran una aberración) siguen ocupando los primeros lugares de uso de los lenguajes de programación.

5.
@fcodiaz: NO hay herencia de métodos estáticos. No se manejan como funciones virtuales para lograr lo que la herencia persigue como objetivo principal: darle soporte al polimorfismo basado en la herencia y permitir la especialización del comportamiento de los objetos. Sigue un ejemplo:

package estatico;
public class Padre {

  public static void funcionEstatica() {
    System.out.println("funcionEstatica del Padre ");
  }

  public void funcionInstancia() {
    System.out.println("funcionInstancia del Padre ");
  }
}

class Hijo extends Padre {

  public static void funcionEstatica() {
    System.out.println("funcionEstatica del Hijo");
  }

  @Override
  public void funcionInstancia() {
    System.out.println("funcionInstancia del Hijo ");
  }
}

class Ejemplo {

  public static void main(String[] args) {
    /************************************
     * Puede usar Padre.funcionEstatica() y  Hijo.funcionEstatica()
     * sin que Ejemplo herede de esas clases;
     */

    Padre.funcionEstatica();
    Hijo.funcionEstatica();
   
    Padre hijo = new Hijo();
    /*
     * La invocación siguiente a funcionEstatica() no tiene
     * nada que ver con el objeto hijo que es de tipo Hijo
     * pero visto por el compilador por su tipo estático Padre
     */

    hijo.funcionEstatica();
    hijo.funcionInstancia();
  }
}

La ejecución da como resultado:

funcionEstatica del Padre
funcionEstatica del Hijo
funcionEstatica del Padre
funcionInstancia del Hijo

Saludos,
Bárbaro

Imagen de bferro

Los "metódos" estáticos sirven para más cosas

Los métodos estáticos sirven para otras cosas, no solamente para implementar un Singleton. A propósito de su uso como métodos de fábrica, copio algunas cosas de Effective Java de Joshua Bloch:

Consider static factory methods instead of constructors

Pros:

One advantage of static factory methods is that, unlike constructors, they have names.

A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.

A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.

A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances.

Cons:

The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.

A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.

Gracias

Gracias Ezamudio me ha quedado muy claro lo de las clases estaticas internas, es poder instanciarlas des de afuera de la clase contenedora, y las clases internas aunque sean publicas no pueden instanciarce desde afuera?, voy hacer una prueba te cuento como me va. Saludos

Gracias

Gracias por la explicacion, me has clarado muchas dudas.
Saludos

Tienes Razon

He confirmado lo que me decias, disculpa si en algun momento dude de tus conocimientos, gracias por la explicacion.

Imagen de nilier

necesito ayuda para llevar este codigo de c# a JAVA

si pueden mandarme la respuesta al correo se lo agradeceria, caresco de tiempo para entrar al foro.

En este caso Libreria es una clase, y en c# esto seria la declaracion de las propiedades estaticas de la clase

private static Libreria librer;
public static Libreria Librer
{
get
{
if (librer == null)
{
librer = new Libreria();
}
return librer;
}
set { Libreria.librer = value; }
}

Imagen de ezamudio

vete

Vete a la mierda.

(total, si no tiene tiempo de entrar al foro, no va a leer lo que le puse, no?)

Pero en caso que sí regreses: Ese código en C# parece un como para un singleton mal hecho. El patrón singleton en Java es así:

public class MiClase {
  private static MiClase instancia;
  private final static Object lock = new Object();

  public static MiClase get() {
    if (instancia == null) {
      synchronized(lock) {
        if (instancia == null) {
          instancia = new MiClase();
        }
      }
    }
    return instancia;
  }

  private MiClase(){} //para que no puedan crear más instancias
}

Se verifica null dos veces y se usa un candado para asegurar que sólo se crea una instancia incluso en ambientes multi-hilos.

Tambien esta la solucion Bill

Tambien esta la solucion Bill Pugh.

http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh

class Clase {
    private Clase(){}
    private static class Holder {
          static Clase INSTANCIA = new Clase();
    }
    public Clase getInstance() {
        return Holder.INSTANCIA;
    }
}
Imagen de ezamudio

eager

Pero esa solución es eager, es decir, crea el objeto aunque tal vez nunca se necesite en la aplicación. Pero bueno, sólo se crea una vez. El código que puse es para creación tardía, sólo si realmente alguien pide el objeto.

Crear el objeto al cargar la clase podría ser problemático si su creación requiere de recursos que tal vez no han sido cargados o inicializados aún.

No, es lazy. La clase Holder

No, es lazy.

La clase Holder no se carga porque nadie ha hecho referencia a ella. Se puede seguir trabajando con "Clase" por un tiempo largo y solo hasta que se ejecuta el metodo "getInstance()" es cuando la clase Holder se carga.

import java.util.Date;
import java.util.concurrent.TimeUnit;
public class LazySingleton {
    private LazySingleton(){
        System.out.println("singleton creado: " + new Date());
    }
    private static class Holder {
        static final LazySingleton INSTANCE = new LazySingleton();
    }

    public static LazySingleton getInstance() {
        return Holder.INSTANCE;
    }

    static {
        System.out.println("clase cargada: " + new Date());
    }

    public static void main( String ... args ) throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        LazySingleton i = LazySingleton.getInstance();
    }
}

$ java LazySingleton
clase cargada: Thu May 16 14:07:06 CDT 2013
singleton creado: Thu May 16 14:07:11 CDT 2013

Y lo mejor es que tambien es thread safe, sin tener que utilizar ningun mecanismo de sincronizacion.

Imagen de nilier

mmm vete a la mierda?? mal hecho??

mira socio primero deja aclararte algo el foro con personas como tu "merma", por otra parte no esta mal el codigo ese en c# ya lo he utilizado millones de veces, por otra parte gracias por la ayuda pero ya habia resuelto con otro codigo que elabore yo mismo ya que se me demoraban las respuestas y ando algo enredado con la tesis...
taba preguntando sobbre el codigo en java porque nunca habia programado en java el lenguaje que estudie desde que comence es c#...
este pincha tambien, ya lo probe, tanto para introducirles valores o para obtenerlos ...

private static Controlador control;
public static Controlador Control() {
if (control == null)
{
control = new Controlador();
}
return control;
}
public static void Control(Controlador aControl) {
control = aControl;
}

Imagen de nilier

mm como se hace?

es mi 1ra ves trabajando con java, necesito saber como puedo obtener del jList del visual la lista de palabras ke tiene
ejemplo, haber si logro explicarme:
jList tiene
ana
pablo
rosa
raul

quiero recorrer con un for el jList
y ke me vaya devolviendo "ana", "pablo", "rosa", "raul", asi seguan me convenga

jList tiene algun metodo para saber la lungitud, es decir, quiero saber como desplazarme por linea y como obtener los datos completos por lineas

por favor help

@niler no es por el codigo

@niler no es por el codigo sino por la frase: "mandarme la respuesta al correo se lo agradeceria, caresco de tiempo para entrar al foro"

Sobre lo que preguntas de la lista, crea un nuevo post. Eso no esta relacionado con las clases est'aticas.

Imagen de nilier

ok

mala mia tonces gracias d todas formas