Java Language
Сравнение C ++
Поиск…
Вступление
Java и C ++ - это схожие языки. Этот раздел служит в качестве краткого справочного руководства для разработчиков Java и C ++.
замечания
Классы, определенные в других конструкциях #
Определено в другом классе
C ++
Вложенный класс [ref] (требуется ссылка на класс включения)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Джава
[нестатический] Вложенный класс (он же внутренний класс или класс участника)
class OuterClass {
...
class InnerClass {
...
}
}
Статически определено в другом классе
C ++
Статический вложенный класс
class Outer {
class Inner {
...
};
};
Джава
Статический вложенный класс (aka Static Member Class) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Определено в рамках метода
(например, обработка событий)
C ++
Местный класс [ref]
void fun() {
class Test {
/* members of Test class */
};
}
См. Также Лямбда-выражения
Джава
Местный класс [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Переопределение и перегрузка
Следующие пункты Overriding vs Overloading применяются как для C ++, так и для Java:
- Переопределенный метод имеет то же имя и аргументы, что и его базовый метод.
- Перегруженный метод имеет одно и то же имя, но разные аргументы и не полагается на наследование.
- Два метода с тем же именем и аргументами, но с другим типом возврата являются незаконными. См. Связанные вопросы Stackoverflow о «перегрузке с помощью другого типа возврата в Java» - вопрос 1 ; вопрос 2
Полиморфизм
Полиморфизм - это способность объектов разных классов, связанных с наследованием, реагировать по-разному на один и тот же вызов метода. Вот пример:
- базовый класс Форма с областью как абстрактный метод
- два производных класса, квадрат и круг, методы области реализации
- Отображаются опорные точки формы к квадрату и области.
В C ++ полиморфизм активируется виртуальными методами. В Java методы по умолчанию являются виртуальными.
Порядок строительства / уничтожения
Очистка объектов
В C ++ рекомендуется объявить деструктор виртуальным, чтобы гарантировать, что деструктор подкласса будет вызываться, если указатель базового класса будет удален.
В Java метод finalize аналогичен деструктору в C ++; однако финализаторы непредсказуемы (они полагаются на GC). Лучшая практика - используйте метод «закрыть» для явной очистки.
protected void close() {
try {
// do subclass cleanup
}
finally {
isClosed = true;
super.close();
}
}
protected void finalize() {
try {
if(!isClosed) close();
}
finally {
super.finalize();
}
}
Абстрактные методы и классы
концепция | C ++ | Джава |
---|---|---|
Абстрактный метод объявлен без реализации | чистый виртуальный метод virtual void eat(void) = 0; | абстрактный метод abstract void draw(); |
Абстрактный класс не может быть | не может быть создан; имеет по крайней мере 1 чистый виртуальный метод class AB {public: virtual void f() = 0;}; | не может быть создан; могут иметь не абстрактные методы abstract class GraphicObject {} |
Интерфейс нет полей экземпляра | нет «интерфейса», но может имитировать интерфейс Java с возможностями абстрактного класса | очень похож на абстрактный класс, но 1) поддерживает множественное наследование; 2) никаких полей экземпляра interface TestInterface {} |
Модификаторы доступности
Модификатор | C ++ | Джава |
---|---|---|
Общественность - доступна всем | нет специальных заметок | нет специальных заметок |
Защищено - доступно по подклассам | также доступны друзьям | также доступны в одном пакете |
Частный - доступный для участников | также доступны друзьям | нет специальных заметок |
дефолт | class default - частный; struct default - общедоступный | доступный для всех классов в одном пакете |
Другой | Друг - способ предоставить доступ к частным и защищенным членам без наследования (см. Ниже) |
Пример использования C ++
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};
Проблема ужасного алмаза
Проблема с алмазом - это двусмысленность, возникающая, когда два класса B и C наследуют от A, а класс D наследуется как от B, так и от C. Если в A существует метод, который B и C переопределены, а D не переопределяет его, тогда какая версия метода наследует D: B или C? (из Википедии )
Хотя C ++ всегда была восприимчива к проблеме алмаза, Java была восприимчивой до Java 8. Первоначально Java не поддерживала множественное наследование, но с появлением методов интерфейса по умолчанию классы Java не могут наследовать «реализацию» из более чем одного класса ,
Класс java.lang.Object
В Java все классы наследуют, неявно или явно, из класса Object. Любая ссылка Java может быть перенесена в тип объекта.
У C ++ нет сопоставимого класса «Объект».
Контейнеры Java и C ++
Коллекции Java являются символами C ++ Containers.
Блок-схема Java Collections
Блок-схема контейнеров C ++
Целочисленные типы
Биты | Min | Максимум | Тип C ++ (на LLP64 или LP64) | Тип Java |
---|---|---|---|---|
8 | -2 (8-1) = -128 | 2 (8-1) -1 = 127 | голец | байт |
8 | 0 | 2 (8) -1 = 255 | unsigned char | - |
16 | -2 (16-1) = -32,768 | 2 (16-1) -1 = 32 767 | короткая | короткая |
16 | 0 (\ u0000) | 2 (16) -1 = 65,535 (\ uFFFF) | беззнаковый короткий | char (без знака) |
32 | -2 (32-1) = -2,147 млрд. | 2 (32-1) -1 = 2,147 млрд. | ИНТ | ИНТ |
32 | 0 | 2 (32) -1 = 4,295 млрд | unsigned int | - |
64 | -2 (64-1) | 2 (16-1) -1 | долго* | долго долго |
64 | 0 | 2 (16) -1 | unsigned long * unsigned long long | - |
*
API Win64 - всего 32 бит
Участники статического класса
Статические члены имеют класс, а не объект
Пример C ++
// define in header
class Singleton {
public:
static Singleton *getInstance();
private:
Singleton() {}
static Singleton *instance;
};
// initialize in .cpp
Singleton* Singleton::instance = 0;
Пример Java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
Классы, определенные в других конструкциях
Определено в другом классе
C ++
Вложенный класс [ref] (требуется ссылка на класс включения)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Джава
[нестатический] Вложенный класс (он же внутренний класс или класс участника)
class OuterClass {
...
class InnerClass {
...
}
}
Статически определено в другом классе
C ++
Статический вложенный класс
class Outer {
class Inner {
...
};
};
Джава
Статический вложенный класс (aka Static Member Class) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
Определено в рамках метода
(например, обработка событий)
C ++
Местный класс [ref]
void fun() {
class Test {
/* members of Test class */
};
}
Джава
Местный класс [ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Передача по значению и пересылка по ссылке
Многие утверждают, что Java ТОЛЬКО ПОКЛОННАЯ, но она более тонкая, чем та. Сравните следующие примеры на C ++ и Java, чтобы увидеть множество разновидностей pass-by-value (aka copy) и pass-by-reference (aka alias).
Пример C ++ (полный код)
// 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 (полный код)
// 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);
}
Наследование и композиция
C ++ и Java являются объектно-ориентированными языками, поэтому следующая диаграмма применима к обоим.
Изгой понижающее приведение
Остерегайтесь использования «downcasting» - Downcasting отличает иерархию наследования от базового класса до подкласса (т. Е. Напротив полиморфизма). В общем, используйте полиморфизм и переопределение вместо экземпляра & downcasting.
Пример C ++
// explicit type case required
Child *pChild = (Child *) &parent;
Пример Java
if(mySubClass instanceof SubClass) {
SubClass mySubClass = (SubClass)someBaseClass;
mySubClass.nonInheritedMethod();
}
Абстрактные методы и классы
Абстрактный метод
объявлен без реализации
C ++
чистый виртуальный метод
virtual void eat(void) = 0;
Джава
абстрактный метод
abstract void draw();
Абстрактный класс
не может быть
C ++
не может быть создан; имеет по крайней мере 1 чистый виртуальный метод
class AB {public: virtual void f() = 0;};
Джава
не может быть создан; могут иметь не абстрактные методы
abstract class GraphicObject {}
Интерфейс
нет полей экземпляра
C ++
ничего похожего на Java
Джава
очень похож на абстрактный класс, но 1) поддерживает множественное наследование; 2) никаких полей экземпляра
interface TestInterface {}