Java Language
C ++ vergelijking
Zoeken…
Invoering
Java en C ++ zijn vergelijkbare talen. Dit onderwerp dient als beknopte naslaggids voor Java- en C ++ Engineers.
Opmerkingen
Klassen gedefinieerd binnen andere constructies #
Gedefinieerd binnen een andere klasse
C ++
Geneste klasse [ref] (heeft een verwijzing nodig naar de bijgevoegde klasse)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[niet-statisch] Geneste klasse (ook bekend als Inner Class of Member Class)
class OuterClass {
...
class InnerClass {
...
}
}
Statisch gedefinieerd binnen een andere klasse
C ++
Statische geneste klasse
class Outer {
class Inner {
...
};
};
Java
Statische geneste klasse (ook bekend als statische ledenklasse) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Gedefinieerd binnen een methode
(bijv. afhandeling van evenementen)
C ++
Lokale Klasse [ref]
void fun() {
class Test {
/* members of Test class */
};
}
Zie ook Lambda-uitdrukkingen
Java
Lokale Klasse [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Overschrijven versus overbelasten
De volgende vervangende versus overbelastingspunten zijn van toepassing op zowel C ++ als Java:
- Een overschreven methode heeft dezelfde naam en argumenten als de basismethode.
- Een overbelaste methode heeft dezelfde naam maar verschillende argumenten en is niet afhankelijk van overerving.
- Twee methoden met dezelfde naam en argumenten maar verschillend retourtype zijn illegaal. Zie gerelateerde Stackoverflow-vragen over "overbelasting met ander retourtype in Java" - Vraag 1 ; vraag 2
polymorfisme
Polymorfisme is het vermogen van objecten van verschillende klassen die gerelateerd zijn aan overerving om verschillend te reageren op dezelfde methodeaanroep. Hier is een voorbeeld:
- basisklasse Vorm met gebied als abstracte methode
- twee afgeleide klassen, Vierkant en Cirkel, implementeren gebiedsmethoden
- Vormreferentiepunten naar Vierkant en gebied worden aangeroepen
In C ++ wordt polymorfisme mogelijk gemaakt door virtuele methoden. In Java zijn methoden standaard virtueel.
Volgorde van constructie / vernietiging
Object opschonen
In C ++ is het een goed idee om een destructor als virtueel te verklaren om ervoor te zorgen dat de destructor van de subklasse wordt aangeroepen als de pointer van de basisklasse wordt verwijderd.
In Java is een voltooiingsmethode vergelijkbaar met een destructor in C ++; finalizers zijn echter onvoorspelbaar (ze vertrouwen op GC). Best practice - gebruik een "close" -methode om expliciet op te ruimen.
protected void close() {
try {
// do subclass cleanup
}
finally {
isClosed = true;
super.close();
}
}
protected void finalize() {
try {
if(!isClosed) close();
}
finally {
super.finalize();
}
}
Abstracte methoden en klassen
Concept | C ++ | Java |
---|---|---|
Abstracte methode zonder implementatie verklaard | pure virtuele methode virtual void eat(void) = 0; | abstracte methode abstract void draw(); |
Abstracte klasse kan niet worden gestart | kan niet worden geïnstantieerd; heeft minstens 1 pure virtuele methode class AB {public: virtual void f() = 0;}; | kan niet worden geïnstantieerd; kan niet-abstracte methoden hebben abstract class GraphicObject {} |
Koppel geen instantievelden | geen "interface" sleutelwoord, maar kan een Java-interface nabootsen met voorzieningen van een abstracte klasse | zeer vergelijkbaar met abstracte klasse, maar 1) ondersteunt meervoudige overerving; 2) geen instantievelden interface TestInterface {} |
Toegankelijkheid Modifiers
wijziger | C ++ | Java |
---|---|---|
Openbaar - voor iedereen toegankelijk | geen speciale opmerkingen | geen speciale opmerkingen |
Beschermd - toegankelijk voor subklassen | ook toegankelijk voor vrienden | ook toegankelijk binnen hetzelfde pakket |
Privé - toegankelijk voor leden | ook toegankelijk voor vrienden | geen speciale opmerkingen |
standaard | klasse standaard is privé; struct default is openbaar | toegankelijk voor alle klassen binnen hetzelfde pakket |
anders | Vriend - een manier om toegang te verlenen aan privé- en beschermde leden zonder overerving (zie hieronder) |
C ++ Vriend voorbeeld
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};
Het probleem met de gevreesde diamant
Het diamantprobleem is een dubbelzinnigheid die ontstaat wanneer twee klassen B en C van A erven, en klasse D van zowel B als C erft. Als er een methode in A is die B en C hebben opgeheven en D deze niet overschrijft, dan welke versie van de methode ervaart D: die van B, of die van C? (van Wikipedia )
Hoewel C ++ altijd gevoelig is geweest voor het diamantprobleem, was Java gevoelig tot Java 8. Oorspronkelijk ondersteunde Java geen meervoudige overerving, maar met de komst van standaardinterfacemethoden kunnen Java-klassen geen "implementatie" overnemen van meer dan één klasse .
java.lang.Object Class
In Java nemen alle klassen impliciet of expliciet over van de klasse Object. Elke Java-verwijzing kan naar het objecttype worden gegoten.
C ++ heeft geen vergelijkbare "Object" -klasse.
Java-collecties & C ++ Containers
Java-collecties zijn synoniem met C ++ Containers.
Java Collections Flowchart
C ++ Containers stroomdiagram
Geheel getaltypen
Bits | min | Max | C ++ Type (op LLP64 of LP64) | Java-type |
---|---|---|---|---|
8 | -2 (8-1) = -128 | 2 (8-1) -1 = 127 | verkolen | byte |
8 | 0 | 2 (8) -1 = 255 | Ongetekend char | - |
16 | -2 (16-1) = -32.768 | 2 (16-1) -1 = 32.767 | kort | kort |
16 | 0 (\ u0000) | 2 (16) -1 = 65.535 (\ uFFFF) | niet ondertekend kort | char (niet ondertekend) |
32 | -2 (32-1) = -2,147 miljard | 2 (32-1) -1 = 2.147 miljard | int | int |
32 | 0 | 2 (32) -1 = 4,295 miljard | niet ondertekend int | - |
64 | -2 (64-1) | 2 (16-1) -1 | lang* | lang Lang |
64 | 0 | 2 (16) -1 | niet ondertekend * lang niet ondertekend | - |
*
Win64 API is slechts 32 bit
Statische Klasse Leden
Statische leden hebben klassebereik in tegenstelling tot objectbereik
C ++ Voorbeeld
// define in header
class Singleton {
public:
static Singleton *getInstance();
private:
Singleton() {}
static Singleton *instance;
};
// initialize in .cpp
Singleton* Singleton::instance = 0;
Java- voorbeeld
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
Klassen gedefinieerd binnen andere constructies
Gedefinieerd binnen een andere klasse
C ++
Geneste klasse [ref] (heeft een verwijzing nodig naar de bijgevoegde klasse)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[niet-statisch] Geneste klasse (ook bekend als Inner Class of Member Class)
class OuterClass {
...
class InnerClass {
...
}
}
Statisch gedefinieerd binnen een andere klasse
C ++
Statische geneste klasse
class Outer {
class Inner {
...
};
};
Java
Statische geneste klasse (ook bekend als statische ledenklasse) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Gedefinieerd binnen een methode
(bijv. afhandeling van evenementen)
C ++
Lokale Klasse [ref]
void fun() {
class Test {
/* members of Test class */
};
}
Java
Lokale Klasse [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Pass-by-value & Pass-by-reference
Velen beweren dat Java ALLEEN pass-by-value is, maar het is genuanceerder dan dat. Vergelijk de volgende voorbeelden van C ++ en Java om de vele smaken van pass-by-value (ook wel kopie) en pass-by-referentie (ook bekend als alias) te bekijken.
C ++ Voorbeeld (volledige code)
// 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;
}
Java-voorbeeld (volledige code)
// 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);
}
Overerving versus samenstelling
C ++ en Java zijn beide objectgeoriënteerde talen, dus het volgende diagram is op beide van toepassing.
Outcast Downcasting
Pas op voor het gebruik van "downcasting" - Downcasting is het verlagen van de overervinghiërarchie van een basisklasse naar een subklasse (dat wil zeggen tegenovergesteld aan polymorfisme). Gebruik in het algemeen polymorfisme & opheffen in plaats van instantie van & downcasting.
C ++ Voorbeeld
// explicit type case required
Child *pChild = (Child *) &parent;
Java-voorbeeld
if(mySubClass instanceof SubClass) {
SubClass mySubClass = (SubClass)someBaseClass;
mySubClass.nonInheritedMethod();
}
Abstracte methoden en klassen
Abstracte methode
zonder implementatie verklaard
C ++
pure virtuele methode
virtual void eat(void) = 0;
Java
abstracte methode
abstract void draw();
Abstracte klasse
kan niet worden gestart
C ++
kan niet worden geïnstantieerd; heeft minstens 1 pure virtuele methode
class AB {public: virtual void f() = 0;};
Java
kan niet worden geïnstantieerd; kan niet-abstracte methoden hebben
abstract class GraphicObject {}
Koppel
geen instantievelden
C ++
niets vergelijkbaar met Java
Java
zeer vergelijkbaar met abstracte klasse, maar 1) ondersteunt meervoudige overerving; 2) geen instantievelden
interface TestInterface {}