Szukaj…


Wprowadzenie

Java i C ++ są podobnymi językami. Ten temat służy jako szybki przewodnik dla inżynierów Java i C ++.

Uwagi

Klasy zdefiniowane w innych konstrukcjach #

Zdefiniowany w innej klasie

C ++

Klasa zagnieżdżona [ref] (wymaga odniesienia do otaczającej klasy)

class Outer {
   class Inner {
      public:
         Inner(Outer* o) :outer(o) {}

      private:
         Outer*  outer;
   };
};

Jawa

[niestatyczna] Klasa zagnieżdżona (znana również jako klasa wewnętrzna lub klasa członka)

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

Zdefiniowane statycznie w innej klasie

C ++

Statycznie zagnieżdżona klasa

class Outer {
   class Inner {
      ...
   };
};

Jawa

Static Nested Class (vel Static Member Class) [ref]

class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
}

Zdefiniowane w ramach metody

(np. obsługa zdarzeń)

C ++

Klasa lokalna [ref]

void fun() {
   class Test {
      /* members of Test class */
   };
}

Zobacz także wyrażenia Lambda

Jawa

Klasa lokalna [ref]

class Test {
    void f() {
        new Thread(new Runnable() {
            public void run() {
                doSomethingBackgroundish();
            }
        }).start();
    }
}

Przesłonięcie a przeciążenie

Następujące punkty zastąpienia i przeciążenia dotyczą zarówno C ++, jak i Java:

  • Przesłonięta metoda ma taką samą nazwę i argumenty jak metoda podstawowa.
  • Przeciążona metoda ma tę samą nazwę, ale różne argumenty i nie polega na dziedziczeniu.
  • Dwie metody o tej samej nazwie i argumentach, ale o innym typie zwrotu są nielegalne. Zobacz podobne pytania Stackoverflow dotyczące „przeciążenia innym rodzajem zwrotu w Javie” - Pytanie 1 ; pytanie 2

Wielopostaciowość

Polimorfizm to zdolność obiektów różnych klas powiązanych przez dziedziczenie do różnej reakcji na to samo wywołanie metody. Oto przykład:

  • klasa podstawowa Kształt z obszarem jako metoda abstrakcyjna
  • dwie klasy pochodne, Kwadrat i Okrąg, wdrażają metody obszarowe
  • Odwołaj się do punktów odniesienia kształtu do kwadratu i obszaru

W C ++ polimorfizm jest włączany metodami wirtualnymi. W Javie metody są domyślnie wirtualne.

Porządek budowy / zniszczenia

Porządek budowy / zniszczenia

Oczyszczanie obiektów

W C ++ dobrym pomysłem jest deklarowanie destruktora jako wirtualnego, aby mieć pewność, że wywołanie destruktora podklasy zostanie wywołane, jeśli wskaźnik klasy podstawowej zostanie usunięty.

W Javie metoda finalizacji jest podobna do destruktora w C ++; jednak finalizatory są nieprzewidywalne (polegają na GC). Najlepsza praktyka - użyj metody „close”, aby jawnie oczyścić.

protected void close() {
    try {
       // do subclass cleanup
    }
    finally {
       isClosed = true;
       super.close();
    }
}

protected void finalize() {
    try {
       if(!isClosed) close();
    }
    finally {
       super.finalize();
    }
}

Metody i klasy abstrakcyjne

Pojęcie C ++ Jawa
Metoda abstrakcyjna
zadeklarowane bez implementacji
czysta wirtualna metoda
virtual void eat(void) = 0;
metoda abstrakcyjna
abstract void draw();
Klasa abstrakcyjna
nie można utworzyć instancji
nie można utworzyć instancji; ma co najmniej 1 czystą wirtualną metodę
class AB {public: virtual void f() = 0;};
nie można utworzyć instancji; może mieć metody nieabstrakcyjne
abstract class GraphicObject {}
Berło
brak pól instancji
brak słowa kluczowego „interfejs”, ale może naśladować interfejs Java z udogodnieniami klasy abstrakcyjnej bardzo podobny do klasy abstrakcyjnej, ale 1) obsługuje wielokrotne dziedziczenie; 2) brak pól instancji
interface TestInterface {}

Modyfikatory dostępności

Modyfikator C ++ Jawa
Publiczny - dostępny dla wszystkich bez specjalnych notatek bez specjalnych notatek
Chroniony - dostępny przez podklasy dostępne również dla znajomych dostępne również w ramach tego samego pakietu
Prywatny - dostępny dla członków dostępne również dla znajomych bez specjalnych notatek
domyślna domyślna klasa jest prywatna; Struktura domyślna to public dostępne dla wszystkich klas w tym samym pakiecie
inny Przyjaciel - sposób na udzielenie dostępu prywatnym i chronionym członkom bez dziedziczenia (patrz poniżej)

Przykład znajomego w C ++

class Node {
  private:
    int key;  Node *next;
    // LinkedList::search() can access "key" & "next"
    friend int LinkedList::search();
};

Problem z przerażającym diamentem

Problemem z diamentami jest dwuznaczność, która powstaje, gdy dwie klasy B i C dziedziczą po A, a klasa D dziedziczy zarówno po B, jak i C. Jeśli istnieje metoda w A, którą B i C zastąpiły, a D jej nie zastąpi, to która wersja metody dziedziczy D: wersja B lub C? (z Wikipedii )

Problem z przerażającym diamentem

Podczas gdy C ++ zawsze był podatny na problem z diamentem, Java była wrażliwa aż do Java 8. Pierwotnie Java nie obsługiwała wielokrotnego dziedziczenia, ale wraz z pojawieniem się domyślnych metod interfejsu klasy Java nie mogą dziedziczyć „implementacji” z więcej niż jednej klasy .

java.lang.Object Klasa

W Javie wszystkie klasy dziedziczą, pośrednio lub jawnie, od klasy Object. Każde odwołanie Java może być rzutowane na typ obiektu.

C ++ nie ma porównywalnej klasy „Object”.

Kolekcje Java i kontenery C ++

Kolekcje Java są tożsame z kontenerami C ++.

Schemat blokowy kolekcji Java

Schemat blokowy kontenerów C ++

Typy całkowite

Bity Min Max Typ C ++
(na LLP64 lub LP64)
Typ Java
8 -2 (8-1) = -128 2 (8-1) -1 = 127 zwęglać bajt
8 0 2 (8) -1 = 255 niepodpisany char -
16 -2 (16-1) = -32 768 2 (16-1) -1 = 32 767 krótki krótki
16 0 (\ u0000) 2 (16) -1 = 65 535 (\ uFFFF) bez znaku krótkie char (niepodpisany)
32 -2 (32-1) = -2,147 miliarda 2 (32-1) -1 = 2,147 miliarda int int
32 0 2 (32) -1 = 4,295 miliarda unsigned int -
64 -2 (64-1) 2 (16-1) -1 długo* długo długo
64 0 2 (16) -1 bez znaku długi *
długo bez znaku
-

* Interfejs API Win64 jest tylko 32-bitowy

Dużo więcej typów C ++

Członkowie klasy statycznej

Elementy statyczne mają zakres klasy w przeciwieństwie do zakresu obiektu

Przykład C ++

// define in header
class Singleton {
   public:
      static Singleton *getInstance();

   private:
      Singleton() {}
      static Singleton *instance;
};

// initialize in .cpp
Singleton* Singleton::instance = 0;

Przykład Java

public class Singleton {
    private static Singleton instance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Klasy zdefiniowane w innych konstrukcjach

Zdefiniowany w innej klasie

C ++

Klasa zagnieżdżona [ref] (wymaga odniesienia do otaczającej klasy)

class Outer {
   class Inner {
      public:
         Inner(Outer* o) :outer(o) {}

      private:
         Outer*  outer;
   };
};

Jawa

[niestatyczna] Klasa zagnieżdżona (znana również jako klasa wewnętrzna lub klasa członka)

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

Zdefiniowane statycznie w innej klasie

C ++

Statycznie zagnieżdżona klasa

class Outer {
   class Inner {
      ...
   };
};

Jawa

Static Nested Class (vel Static Member Class) [ref]

class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
}

Zdefiniowane w ramach metody

(np. obsługa zdarzeń)

C ++

Klasa lokalna [ref]

void fun() {
   class Test {
      /* members of Test class */
   };
}

Jawa

Klasa lokalna [ref]

class Test {
    void f() {
        new Thread(new Runnable() {
            public void run() {
                doSomethingBackgroundish();
            }
        }).start();
    }
}

Przekazywanie według wartości i przekazywanie przez odniesienie

Wielu twierdzi, że Java jest TYLKO przekazywana według wartości, ale jest bardziej dopracowana. Porównaj następujące przykłady C ++ i Java, aby zobaczyć wiele wariantów przekazywania wartości (aka kopiowanie) i przekazywania według referencji (alias).

Przykład C ++ (pełny kod)

  // 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;
  }

Przykład Java (pełny kod)

   // 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);
   }

Dziedziczenie a kompozycja

C ++ i Java są językami obiektowymi, dlatego poniższy schemat stosuje się do obu.

Dziedziczenie a przykładowy skład

Outcasting Downcasting

Uwaga na używanie „downcastingu” - downcasting obniża hierarchię dziedziczenia z klasy podstawowej do podklasy (tj. Przeciwieństwo polimorfizmu). Zasadniczo używaj polimorfizmu i przesłonięcia zamiast instanceof i downcastingu.

Przykład C ++

// explicit type case required
Child *pChild =  (Child *) &parent;

Przykład Java

if(mySubClass instanceof SubClass) {
   SubClass mySubClass = (SubClass)someBaseClass;
   mySubClass.nonInheritedMethod();
}

Metody i klasy abstrakcyjne

Metoda abstrakcyjna

zadeklarowane bez implementacji

C ++

czysta wirtualna metoda

virtual void eat(void) = 0;

Jawa

metoda abstrakcyjna

abstract void draw();

Klasa abstrakcyjna

nie można utworzyć instancji

C ++

nie można utworzyć instancji; ma co najmniej 1 czystą wirtualną metodę

class AB {public: virtual void f() = 0;};

Jawa

nie można utworzyć instancji; może mieć metody nieabstrakcyjne

abstract class GraphicObject {}

Berło

brak pól instancji

C ++

nic porównywalnego z Javą

Jawa

bardzo podobny do klasy abstrakcyjnej, ale 1) obsługuje wielokrotne dziedziczenie; 2) brak pól instancji

interface TestInterface {}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow