Sök…


Introduktion

Java och C ++ är liknande språk. Detta ämne fungerar som en snabbreferensguide för Java- och C ++ -ingenjörer.

Anmärkningar

Klasser definierade inom andra konstruktioner #

Definieras inom en annan klass

C ++

Nested Class [ref] (behöver en referens till slutande klass)

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

      private:
         Outer*  outer;
   };
};

Java

[icke-statisk] Nested Class (alias Inner Class eller Members Class)

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

Statiskt definierade inom en annan klass

C ++

Static Nested Class

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

Java

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

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

Definieras inom en metod

(t.ex. händelsehantering)

C ++

Lokal klass [ref]

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

Se även Lambda-uttryck

Java

Lokal klass [ref]

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

Överbestyrning vs överbelastning

Följande åsidosättande vs överbelastningspunkter gäller både C ++ och Java:

  • En åsidosatt metod har samma namn och argument som dess basmetod.
  • En överbelastad metod har samma namn men olika argument och förlitar sig inte på arv.
  • Två metoder med samma namn och argument men olika returtyp är olagliga. Se relaterade Stackoverflow-frågor om "överbelastning med annan returtyp i Java" - Fråga 1 ; fråga 2

polymorfism

Polymorfism är förmågan för objekt från olika klasser relaterade till arv att svara på samma sätt på samma metodsamtal. Här är ett exempel:

  • basklass Form med område som en abstrakt metod
  • två härledda klasser, Square och Circle, implementerar områdesmetoder
  • Formhänvisning till torget och området åberopas

I C ++ aktiveras polymorfism med virtuella metoder. I Java är metoderna virtuella som standard.

Order för konstruktion / förstörelse

Order för konstruktion / förstörelse

Objektrensning

I C ++ är det en bra idé att förklara en förstörare som virtuell för att säkerställa att underklassens förstörare kommer att kallas om pekaren i basklassen raderas.

I Java är en slutföringsmetod liknande en destruktor i C ++; finaliserare är emellertid oförutsägbara (de litar på GC). Bästa praxis - använd en "nära" metod för att uttryckligen rensa.

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

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

Abstrakta metoder och klasser

Begrepp C ++ Java
Abstrakt metod
deklarerats utan genomförande
ren virtuell metod
virtual void eat(void) = 0;
abstrakt metod
abstract void draw();
Abstrakt klass
kan inte instanseras
kan inte instanseras; har minst en ren virtuell metod
class AB {public: virtual void f() = 0;};
kan inte instanseras; kan ha icke-abstrakta metoder
abstract class GraphicObject {}
Gränssnitt
inga instansfält
inget "gränssnitt" nyckelord, men kan härma ett Java-gränssnitt med faciliteter i en abstrakt klass väldigt lik abstrakt klass, men 1) stöder flera arv; 2) inga instansfält
interface TestInterface {}

Tillgänglighetsmodifierare

modifier C ++ Java
Allmänt - tillgängligt för alla inga specialanmärkningar inga specialanmärkningar
Skyddad - tillgängligt med underklasser också tillgängligt för vänner också tillgängligt inom samma paket
Privat - tillgängligt för medlemmar också tillgängligt för vänner inga specialanmärkningar
standard klassinställningen är privat; struct default är offentligt tillgängligt för alla klasser inom samma paket
Övrig Friend - ett sätt att ge tillgång till privata och skyddade medlemmar utan arv (se nedan)

C ++ vänsexempel

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

Det fruktade diamantproblemet

Diamantproblemet är en tvetydighet som uppstår när två klasser B och C ärver från A och klass D ärver från både B och C. Om det finns en metod i A som B och C har åsidosatt, och D inte åsidosätter det, då vilken version av metoden ärver D: den av B eller den av C? (från Wikipedia )

Det fruktade diamantproblemet

Även om C ++ alltid har varit mottagligt för diamantproblemet, var Java mottaglig tills Java 8. Ursprungligen stödde Java inte flera arv, men med tillkomsten av standardgränssnittsmetoder kan Java-klasser inte ärva "implementering" från mer än en klass .

java.lang.Object Class

I Java ärver alla klasser, antingen implicit eller uttryckligt, från Objekt-klassen. Alla Java-referenser kan kastas till Objekttypen.

C ++ har inte en jämförbar klass "Objekt".

Java-samlingar och C ++ -behållare

Java-samlingar är symonyma med C ++ Containers.

Java Collections Flowchart

C ++ Containers Flödesschema

Heltalstyper

bits min Max C ++ Typ
(på LLP64 eller LP64)
Java-typ
8 -2 (8-1) = -128 2 (8-1) -1 = 127 röding bitgrupp
8 0 2 (8) -1 = 255 unsign char -
16 -2 (16-1) = -32,768 2 (16-1) -1 = 32,767 kort kort
16 0 (\ u0000) 2 (16) -1 = 65,535 (\ uFFFF) osignerad kort röding (ej signerad)
32 -2 (32-1) = -2,147 miljarder 2 (32-1) -1 = 2,147 miljarder int int
32 0 2 (32) -1 = 4,295 miljarder osignerad int -
64 -2 (64-1) 2 (16-1) -1 lång* lång lång
64 0 2 (16) -1 osignerad lång *
osignerad lång länge
-

* Win64 API är bara 32 bitar

Massor av fler C ++ -typer

Statiska klassmedlemmar

Statiska medlemmar har klassomfång i motsats till objektomfång

C ++ Exempel

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

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

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

Java- exempel

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

Klasser definierade inom andra konstruktioner

Definieras inom en annan klass

C ++

Nested Class [ref] (behöver en referens till slutande klass)

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

      private:
         Outer*  outer;
   };
};

Java

[icke-statisk] Nested Class (alias Inner Class eller Members Class)

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

Statiskt definierade inom en annan klass

C ++

Static Nested Class

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

Java

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

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

Definieras inom en metod

(t.ex. händelsehantering)

C ++

Lokal klass [ref]

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

Java

Lokal klass [ref]

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

Pass-by-value & Pass-by-reference

Många hävdar att Java ENDAST är pass-by-value, men det är mer nyanserat än så. Jämför följande C ++ och Java-exempel för att se de många smakerna av pass-by-value (alias kopia) och pass-by-reference (alias).

C ++ Exempel (komplett 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;
  }

Java-exempel (komplett 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);
   }

Arv kontra komposition

C ++ & Java är båda objektorienterade språk, så följande diagram gäller för båda.

Arv mot kompositionsexempel

Outcast Downcasting

Akta dig för att använda "downcasting" - Downcasting kastar ned arvhierarkin från en basklass till en underklass (dvs. motsatt av polymorfism). Använd i allmänhet polymorfism och åsidosättande istället för instans av & nedkastning.

C ++ Exempel

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

Java-exempel

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

Abstrakta metoder och klasser

Abstrakt metod

deklarerats utan genomförande

C ++

ren virtuell metod

virtual void eat(void) = 0;

Java

abstrakt metod

abstract void draw();

Abstrakt klass

kan inte instanseras

C ++

kan inte instanseras; har minst en ren virtuell metod

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

Java

kan inte instanseras; kan ha icke-abstrakta metoder

abstract class GraphicObject {}

Gränssnitt

inga instansfält

C ++

inget jämförbart med Java

Java

väldigt lik abstrakt klass, men 1) stöder flera arv; 2) inga instansfält

interface TestInterface {}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow