java - tutorial - scala vs python




¿Cuál es la diferencia entre una clase y un tipo en Scala(y Java)? (3)

(Solo Java) Yo diría que un tipo es un conjunto de objetos. El objeto o es tipo X , si o es un miembro del conjunto X El tipo X es un subtipo de Y , si el conjunto X es un subconjunto de Y

Para cada clase C (no interfaz) hay un conjunto de objetos, creados a partir de una new C(...) . Curiosamente, rara vez nos importa este conjunto. (pero cada objeto pertenece a un conjunto como este, un hecho que puede ser útil)

Para cada clase C, hay un tipo t(C) , generalmente denominado "el tipo C", que es el conjunto de todos los objetos que se pueden crear a partir del new S(...) donde S es C o una subclase De c.

De forma similar, para cada interfaz I, hay un tipo t(I) , "el tipo I", que es el conjunto de todos los objetos que se pueden crear a partir del new S(...) donde S implementa I.

Obviamente, si la clase S es una subclase de C , el tipo S es un subtipo de tipo C. Similar para la interfaz I

Hay un tipo nulo, que es el conjunto vacío. El tipo nulo es un subtipo de todo tipo.

Hay un conjunto de todos los objetos, que es el tipo Object. Es un tipo estupendo de todo tipo.

Hasta ahora, este formalismo es bastante inútil. Un tipo es básicamente lo mismo que una clase o una interfaz, y la relación de subtipo es básicamente la relación subclase / subinterfaz. La trivialidad es algo bueno, ¡el lenguaje era comprensible! Pero al entrar en los genéricos, existen tipos más complicados y operaciones como uniones e intersecciones de tipos. Los tipos ya no son solo clases e interfaces, y las relaciones de subtipo son mucho más ricas y difíciles de entender.

Scala

¿Dónde se pueden observar las diferencias entre una clase y un tipo en Scala y por qué es importante esta distinción?

¿Es solo una consideración desde el punto de vista del diseño del lenguaje o tiene un impacto "práctico" al programar Scala?

¿O es fundamental para "asegurar los límites" del sistema de tipos ( Nothing , Null viene a mi mente)?

Java

¿Cuántas de las consideraciones / diferencias / problemas mencionados anteriormente también se pueden reconocer en Java?

(Consulte ¿Cuál es la diferencia entre Tipo y Clase? Como introducción independiente del idioma).


Cuando diga "tipo", voy a suponer que quiere decir tipo estático principalmente. Pero hablaré sobre tipos dinámicos en breve.

Un tipo estático es una propiedad de una parte de un programa que puede ser estáticamente probado (estático significa "sin ejecutarlo"). En un lenguaje estáticamente tipado, cada expresión tiene un tipo, ya sea que la escribas o no. Por ejemplo, en el Cish "int x = a * b + c - d", a, b, c y d tienen tipos, a * b tiene un tipo, a * b + c tiene un tipo y a * b + c -d tiene un tipo. Pero solo hemos anotado x con un tipo. En otros idiomas, como Scala, C #, Haskell, SML y F #, incluso eso no sería necesario.

Exactamente qué propiedades son comprobables depende del comprobador de tipos.

Una clase de estilo Scala, por otro lado, es solo la especificación para un conjunto de objetos. Esa especificación incluye cierta información de tipo e incluye una gran cantidad de detalles de implementación y representación, como cuerpos de métodos y campos privados, etc. En Scala, una clase también especifica algunos límites de módulos.

Muchos idiomas tienen tipos pero no tienen clases y muchos idiomas tienen clases pero no tienen tipos (estáticos).

Hay varias diferencias observables entre tipos y clases. List [String] es un tipo pero no una clase. En Scala List es clase, pero normalmente no es un tipo (en realidad es un tipo de mayor kinded). En C # List no es un tipo de ningún tipo y en Java es un "tipo sin formato".

Scala ofrece tipos estructurales. {def foo: Bar} significa cualquier objeto que tenga un método foo que devuelva una barra, independientemente de la clase. Es un tipo, pero no una clase.

Los tipos pueden abstraerse usando parámetros de tipo. Cuando escribes def foo [T] (x: T) = ..., entonces dentro del cuerpo de foo T hay un tipo. Pero T no es una clase.

Los tipos pueden ser virtuales en Scala (es decir, "miembros de tipo abstracto"), pero las clases no pueden ser virtuales con Scala hoy en día (aunque hay una gran manera de codificar las clases virtuales https://wiki.scala-lang.org/display/SIW/VirtualClassesDesign )

Ahora, tipos dinámicos. Los tipos dinámicos son propiedades de objetos que el tiempo de ejecución comprueba automáticamente antes de realizar ciertas operaciones. En los lenguajes de OO basados ​​en clases de tipo dinámico existe una fuerte correlación entre los tipos y las clases. Lo mismo sucede en los lenguajes de JVM como Scala y Java, que tienen operaciones que solo se pueden verificar dinámicamente, como la reflexión y la fundición. En esos idiomas, "borrado de tipo" significa más o menos que el tipo dinámico de la mayoría de los objetos es el mismo que su clase. Más o menos. Eso no es cierto para, por ejemplo, las matrices que normalmente no se borran para que el tiempo de ejecución pueda distinguir entre Array [Int] y Array [String]. Pero recuerde que mi definición amplia "tipos dinámicos son propiedades de objetos que el tiempo de ejecución automáticamente verifica". Cuando usa la reflexión, es posible enviar cualquier mensaje a cualquier objeto. Si el objeto es compatible con ese mensaje, entonces todo funciona. Por lo tanto, tiene sentido hablar de todos los objetos que pueden graznar como un pato como un tipo dinámico, a pesar de que no es una clase. Esa es la esencia de lo que las comunidades de Python y Ruby llaman "tipa de pato". Además, según mi amplia definición, incluso "zeroness" es un tipo dinámico en el sentido de que, en la mayoría de los idiomas, el tiempo de ejecución comprueba automáticamente los números para asegurarse de no dividir por cero. Hay muy pocos lenguajes que puedan demostrar esto de forma estática al hacer que el cero (o no cero) sea un tipo estático.

Finalmente, como han mencionado otros, hay tipos como int que no tienen una clase como detalles de implementación, tipos como Null y Any que son un poco especiales pero PODRÍAN tener clases y no lo hacen, y tipos como Nothing that doesn ' t incluso tiene valores, mucho menos una clase.


Un tipo puede ser útil por sí mismo, sin ninguna instancia. Un ejemplo de esto se llama "tipo fantasma". Aquí hay un ejemplo para Java: http://michid.wordpress.com/2008/08/13/type-safe-builder-pattern-in-java/

En ese ejemplo, tenemos public static class Initializer<HA, HB> , donde HA y HB toman algunos tipos (representados por las clases abstractas TRUE y FALSE ), sin tener que instanciar nunca.

Espero que esto muestre que los tipos y las clases son algo diferente, y que los tipos pueden ser útiles por sí mismos.





language-design