OOP Concepts in C++ and Java

Similar Constructors

Constructors work almost exactly the same way in C++ and Java. If you do not define a constructor for a class then it is allocated a default constructor. If we do define a constructor then we must use it. The only significant difference is that there is no copy constructor in Java as all objects of a class (i.e. non-primitive types) are passed by reference.

No Destructors!

There are no destructors in Java, even thought there is a new keyword, there is no corresponding delete keyword, as Java takes care of all of the memory management. Java has a special finalize() method that you can add to any class. The strange thing about this method is that you can use it for tidying up (printing a paper record for Account etc.), but you do not know when it will be called. In C++ this was easier, as the destructor is called when the object goes out of scope, but in Java the finalize() method will be called when the garbage collector destroys the object. We do not know when this will be called! As discussed previously, we can request that the garbage collector should run, but we do not know when it will run! You can help the garbage collector slightly by setting all your references to null when you no longer need them, e.g. a = null; - will send a hint to the garbage collector that the object is no longer being used.

Access Specifiers

Like C++, in Java we have public, private and protected access specifiers, but we also have another access specifier "package". This is the default access specifier and means that all states and methods are accessible to all classes within the same package. There is no package access specifier keyword, it is simply the default if public, private or protected are not used. Access specifiers in Java are:

  • public - accessible everywhere, an interface method (same as C++)

  • private - accessible only in the class where it was defined (same as C++)

  • protected - accessible in the class where it is defined, the derived classes and in the same package (almost the same as C++ with the exception of the package)

  • "package" - default (there is no package specifier keyword) and means that it is accessible by any class in the same package. You can equate this to the C++ friendly condition by saying that all of the classes in the same package (directory) are friendly.

In Java there is no direct equivalent to protected in C++. In Java version 1.0 there was! it was called "private protected", but was deemed complex and unnecessary, and so was removed.

Access Specifiers when Inheriting Classes

Inheritance in Java does not change the protection level of the members in the base class. You cannot specify public, private or protected inheritance in Java, as you can in C++. Over-ridden methods in a derived class cannot reduce the access of the method in the base class. For example, if a method is public in the base class and you over-ride it, your over-ridden method must also be public. The compiler will enforce this rule.

Virtual and Non-Virtual Methods

In C++ methods are non-virtual by default, so to replace the behaviour (allow over-riding) of a method in the derived class you have to explicitly use the virtual keyword in the parent class. You are able to replace the behaviour of a non-virtual method but this causes serious difficulties when the behaviour of the object depends on the static rather than the dynamic type! In Java, methods are virtual by default and we always operate on the dynamic type of the object. You cannot specify a method as non-virtual, but there is a final keyword. Once you use the final keyword on a method you cannot replace it - so there are no issues with static and dynamic types.

Multiple Inheritance

C++ allows multiple inheritance - Java does not! As discussed previously in the C++ section of the notes, multiple inheritance is complex for the programmer, in that they must make complex decisions about the way that the data of the base class is to be inherited. In Java, we do not have multiple inheritance but we do have the use of Interfaces. Interfaces are a special kind of abstract class that have no data or implemented code. Interfaces might not sound too useful, but they allow a form of multiple inheritance, without having the associated difficulties of dealing with data. This replacement behaviour works very well and does not impact on development, once you get used to the change.

No scope resolution operator

There is no scope resolution operator in Java - such as Account::display(); as used previously in C++. This is possible because you must define all methods and states within a class so there is no global namespace as we had in C++. We have the super and this keywords which allow us to access the parent (only through the direct parent) and the states of a class. Packages are used instead of namespaces. When you use the super()method call in the constructor to call the parent constructor it must be the first line of the child constructor implementation.

Nested Classes

In Java we have the facility to define a class inside of another class. We refer to this class as an inner class. The only issue worth mentioning with inner classes is that they have full access to the private data and methods of the class in which they are nested. Because of this, we do not need to pass state pointers to methods that need callback.

Inline Methods

In C++ we had inline methods, generally short methods that the compiler in effect cuts-and-pastes the method code into the final program, leading to greater efficiency as the assembly language program counter is not jumping around in the final executable. There is of course a trade-off between speed of execution and size of the executable. There are no inline methods in Java - well that's not entirely true. It is up to the compiler to decide whether a method should or should not be inline. There is a keyword in Java called final which suggests to the compiler that the method should be inline, but you have no guarantee that the compiler will agree!