Java Language
Comparación de C ++
Buscar..
Introducción
Java y C ++ son lenguajes similares. Este tema sirve como una guía de referencia rápida para los ingenieros de Java y C ++.
Observaciones
Clases definidas dentro de otras construcciones #
Definido dentro de otra clase
C ++
Clase anidada [ref] (necesita una referencia para encerrar clase)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
Clase anidada [no estática] (clase interna o clase miembro)
class OuterClass {
...
class InnerClass {
...
}
}
Definido estáticamente dentro de otra clase
C ++
Clase anidada estática
class Outer {
class Inner {
...
};
};
Java
Clase anidada estática (también conocida como clase de miembro estática) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Definido dentro de un método
(por ejemplo, manejo de eventos)
C ++
Clase local [ref]
void fun() {
class Test {
/* members of Test class */
};
}
Ver también expresiones Lambda.
Java
Clase local [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Anulando vs Sobrecarga
Los siguientes puntos de Anulación frente a Sobrecarga se aplican tanto a C ++ como a Java:
- Un método anulado tiene el mismo nombre y argumentos que su método base.
- Un método sobrecargado tiene el mismo nombre pero diferentes argumentos y no se basa en la herencia.
- Dos métodos con el mismo nombre y argumentos pero diferente tipo de devolución son ilegales. Consulte las preguntas relacionadas sobre Stackoverflow sobre "sobrecarga con diferentes tipos de retorno en Java" - Pregunta 1 ; Pregunta 2
Polimorfismo
El polimorfismo es la capacidad de los objetos de diferentes clases relacionadas por herencia para responder de manera diferente a la misma llamada de método. Aquí hay un ejemplo:
- Clase base Forma con área como método abstracto
- Dos clases derivadas, Cuadrado y Círculo, implementan métodos de área.
- Forma los puntos de referencia a Plaza y área se invoca.
En C ++, el polimorfismo es habilitado por métodos virtuales. En Java, los métodos son virtuales por defecto.
Orden de Construcción / Destrucción
Limpieza de objetos
En C ++, es una buena idea declarar un destructor como virtual para garantizar que se llamará al destructor de la subclase si se elimina el puntero de la clase base.
En Java, un método de finalización es similar a un destructor en C ++; sin embargo, los finalizadores son impredecibles (dependen de GC). Práctica recomendada: utilice un método "cerrado" para la limpieza explícita.
protected void close() {
try {
// do subclass cleanup
}
finally {
isClosed = true;
super.close();
}
}
protected void finalize() {
try {
if(!isClosed) close();
}
finally {
super.finalize();
}
}
Métodos y clases abstractas
Concepto | C ++ | Java |
---|---|---|
Método abstracto declarado sin implementación | método virtual puro virtual void eat(void) = 0; | método abstracto abstract void draw(); |
Clase abstracta no puede ser instanciado | no puede ser instanciado; tiene al menos 1 método virtual puro class AB {public: virtual void f() = 0;}; | no puede ser instanciado; puede tener métodos no abstractos abstract class GraphicObject {} |
Interfaz campos sin instancia | ninguna palabra clave de "interfaz", pero puede imitar una interfaz de Java con instalaciones de una clase abstracta | muy similar a la clase abstracta, pero 1) admite herencia múltiple; 2) campos sin instancia interface TestInterface {} |
Modificadores de accesibilidad
Modificador | C ++ | Java |
---|---|---|
Público - accesible por todos | sin notas especiales | sin notas especiales |
Protegido - accesible por subclases | también accesible por amigos | También accesible dentro del mismo paquete |
Privado - accesible por los miembros | también accesible por amigos | sin notas especiales |
defecto | la clase por defecto es privada; La estructura por defecto es pública | Accesible por todas las clases dentro del mismo paquete. |
otro | Amigo: una forma de otorgar acceso a miembros privados y protegidos sin herencia (ver más abajo) |
Ejemplo de C ++ Friend
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};
El temido problema del diamante
El problema del diamante es una ambigüedad que surge cuando dos clases B y C heredan de A, y la clase D hereda de B y C. Si hay un método en A que B y C se han invalidado, y D no lo reemplaza, entonces ¿Qué versión del método hereda D: la de B o la de C? (de Wikipedia )
Si bien C ++ siempre ha sido susceptible al problema diamante, Java fue susceptible hasta Java 8. Originalmente, Java no admitía herencia múltiple, pero con la llegada de los métodos de interfaz predeterminados, las clases Java no pueden heredar la "implementación" de más de una clase. .
clase java.lang.Object
En Java, todas las clases heredan, ya sea implícita o explícitamente, de la clase Object. Cualquier referencia de Java se puede convertir al tipo de objeto.
C ++ no tiene una clase de "Objeto" comparable.
Colecciones Java y Contenedores C ++
Las colecciones de Java son sinónimas con los contenedores de C ++.
Diagrama de flujo de colecciones Java
Diagrama de flujo de contenedores C ++
Tipos enteros
Bits | Min | Max | Tipo C ++ (en LLP64 o LP64) | Tipo de Java |
---|---|---|---|---|
8 | -2 (8-1) = -128 | 2 (8-1) -1 = 127 | carbonizarse | byte |
8 | 0 | 2 (8) -1 = 255 | sin firmar | - |
dieciséis | -2 (16-1) = -32,768 | 2 (16-1) -1 = 32,767 | corto | corto |
dieciséis | 0 (\ u0000) | 2 (16) -1 = 65,535 (\ uFFFF) | corto sin firmar | char (sin firmar) |
32 | -2 (32-1) = -2.147 mil millones | 2 (32-1) -1 = 2.147 millones | En t | En t |
32 | 0 | 2 (32) -1 = 4.295 mil millones | sin firmar int | - |
64 | -2 (64-1) | 2 (16-1) -1 | largo* | largo largo |
64 | 0 | 2 (16) -1 | sin firmar largo * sin firmar mucho tiempo | - |
*
Win64 API es solo de 32 bits
Miembros de la clase estática
Los miembros estáticos tienen un alcance de clase en lugar de un objeto.
Ejemplo de C ++
// define in header
class Singleton {
public:
static Singleton *getInstance();
private:
Singleton() {}
static Singleton *instance;
};
// initialize in .cpp
Singleton* Singleton::instance = 0;
Ejemplo de Java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
Clases definidas dentro de otras construcciones
Definido dentro de otra clase
C ++
Clase anidada [ref] (necesita una referencia para encerrar clase)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
Clase anidada [no estática] (clase interna o clase miembro)
class OuterClass {
...
class InnerClass {
...
}
}
Definido estáticamente dentro de otra clase
C ++
Clase anidada estática
class Outer {
class Inner {
...
};
};
Java
Clase anidada estática (también conocida como clase de miembro estática) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Definido dentro de un método
(por ejemplo, manejo de eventos)
C ++
Clase local [ref]
void fun() {
class Test {
/* members of Test class */
};
}
Java
Clase local [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Pasar por valor y Pasar por referencia
Muchos argumentan que Java SÓLO es paso por valor, pero tiene más matices que eso. Compare los siguientes ejemplos de C ++ y Java para ver los muchos sabores de paso por valor (también conocido como copia) y paso por referencia (también conocido como alias).
Ejemplo de C ++ (código completo)
// passes a COPY of the object
static void passByCopy(PassIt obj) {
obj.i = 22; // only a "local" change
}
// passes a pointer
static void passByPointer(PassIt* ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
// passes an alias (aka reference)
static void passByAlias(PassIt& ref) {
ref.i = 44;
}
// This is an old-school way of doing it.
// Check out std::swap for the best way to do this
static void swap(PassIt** pptr1, PassIt** pptr2) {
PassIt* tmp = *pptr1;
*pptr1 = *pptr2;
*pptr2 = tmp;
}
Ejemplo de Java (código completo)
// passes a copy of the variable
// NOTE: in java only primitives are pass-by-copy
public static void passByCopy(int copy) {
copy = 33; // only a "local" change
}
// No such thing as pointers in Java
/*
public static void passByPointer(PassIt *ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
*/
// passes an alias (aka reference)
public static void passByAlias(PassIt ref) {
ref.i = 44;
}
// passes aliases (aka references),
// but need to do "manual", potentially expensive copies
public static void swap(PassIt ref1, PassIt ref2) {
PassIt tmp = new PassIt(ref1);
ref1.copy(ref2);
ref2.copy(tmp);
}
Herencia vs Composición
C ++ y Java son lenguajes orientados a objetos, por lo que el siguiente diagrama se aplica a ambos.
Despreciación por desvalorización
Tenga cuidado con el uso de "downcasting" - Downcasting es derribar la jerarquía de herencia de una clase base a una subclase (es decir, opuesta al polimorfismo). En general, use polimorfismo y reemplazo en lugar de instanceof y downcasting.
Ejemplo de C ++
// explicit type case required
Child *pChild = (Child *) &parent;
Ejemplo de Java
if(mySubClass instanceof SubClass) {
SubClass mySubClass = (SubClass)someBaseClass;
mySubClass.nonInheritedMethod();
}
Métodos y clases abstractas
Método abstracto
declarado sin implementación
C ++
método virtual puro
virtual void eat(void) = 0;
Java
método abstracto
abstract void draw();
Clase abstracta
no puede ser instanciado
C ++
no puede ser instanciado; tiene al menos 1 método virtual puro
class AB {public: virtual void f() = 0;};
Java
no puede ser instanciado; puede tener métodos no abstractos
abstract class GraphicObject {}
Interfaz
campos sin instancia
C ++
nada comparable a Java
Java
muy similar a la clase abstracta, pero 1) admite herencia múltiple; 2) campos sin instancia
interface TestInterface {}