In Java we do not have the scope resolution operator ::
that we
had in C++. We have the super
and this
predefined variables
instead:
super
- allows us to refer to states and methods of the parent class
directly. So, super.display()
would call the display()
method, written or inherited by the parent class. If the parent class of the parent
class with a display()
method also had a display()
method, we
do not have access to that method. This super
predefined variable can also be used in an
unusual way to call the parent constructor from within the child constructor, provided it is used as the first line
of the child constructor (just like member initialisation lists in Java).
this
- allows us to refer to "this object", i.e. to access states or methods for
the class that the code is currently within. It allows us to pass a reference to the current object and it also allows
us to access the states of the class that are currently out of scope.
So, an example of super
and this
would be:
public class TestParent { protected int y=2; // example parent state public TestParent(int a) // example parent constructor { y=a; } } public class Test extends TestParent // inheritance { private int x; public Test(int a) { super(a); // calls the parent constructor x = 5; } public void someMethod(int x) { this.x = x; // this.x refers to the state of the class super.y = 5; // sets the y state of the parent class to a value of 5. someOtherMethod(this); // passes the current object to the // someOtherMethod() method } }
While abstract classes are not much different to abstract classes in C++, there are some points to note.
Once again, abstract methods are a place-holder that define a set of operations within the class that have not yet been implemented. In Java you can actually set a class to be abstract, even if it has no abstract methods. This would prevent this class from being instantiated. However, if one or more methods in a class are abstract then the class must be defined as abstract. For example:
public abstract class Car { public abstract void display(); } public class SportsCar extends Car { public abstract void display() { System.out.println(" Sports car - etc."); } }
Some points to note:
Not all methods in an abstract class need to be abstract.
Abstract classes cannot have private abstract methods.
Abstract classes cannot have static abstract methods.
A Java Interface is a way of grouping methods that describe a particular behaviour. They allow developers to reuse design and they capture similarity, independent of the class hierarchy. We can share both methods and constants using Interfaces, but there can be no states in an interface. Methods in an interface are implicitly public and abstract. Constant states in an interface are implicitly public, static and final.
Interfaces differ from abstract classes in that an interface cannot have an implementation for any method, i.e. all methods are abstract. Classes can implement many interfaces, all unconstrained by a class inheritance structure.
interface Demo { public static final String demoConst = "hello"; // public static final can be omitted // as is implicit void go(); // these methods are public and abstract void stop(); // even if public abstract is omitted } class SomeClass extends Object implements Demo { public void go() { // write implementation here } public void stop() { // write implementation here } } public class TestApp { public static void main(String args[]) { SomeClass c = new SomeClass(); System.out.println(SomeClass.demoConst); // will print out "hello" } }
Consider the mouse. We may write many applications that use the mouse, and within these applications, the mouse may be used in many different ways. We can define a common interface for the mouse that each one of these applications must implement. These applications then share a common defined interface, without having to create an IS-A/IS-A-PART-OF relationship.
Interfaces are Java's replacement for multiple inheritance in C++. Since methods and constants are shared through interfaces, and not states, we do not have the difficulties experienced with multiple inheritance when implementing multiple interfaces:
A class can implement as many interfaces as desired. They are listed one after the other and comma separated.
An interface should always begin with a capital letter, e.g.
MouseListener
.
You can define your own interfaces, in the same way that you can define your own classes.
Strings in Java are very similar to the strings we discussed in C++, through the use of the
#include<string.h>
.
The String
class provides a convenient mechanism for working with
strings in Java. String objects in Java are immutable - once assigned a value, it cannot
be changed. The compiler converts string constants to String
objects
directly.
Some notes on strings:
String
object comparisons are achieved
using the compareTo()
and equals()
methods.
The String
class in Java is the only class in
Java with overloaded operators of "+" and "=". You should not use "==". So, the
"+" operator allows two strings to be concatenated to form a new String
object.
Java strings are not null terminated, like C++ strings.
So for example:
1 2 3 import java.lang.*; 4 5 public class StringTest 6 { 7 public static void main(String args[]) 8 { 9 String x = "Hello "; 10 String y = new String("World!"); 11 12 String z = new String(x + y); 13 System.out.println(z); 14 System.out.println("The length of this string is " 15 + z.length() + " characters."); 16 17 String c = "Cat"; 18 String d = "Dog"; 19 if (c.compareTo(d)<=0) 20 { 21 System.out.println( c + " is less than " + d); 22 } 23 24 if (c.equals("Cat")) 25 { 26 System.out.println("The c object is equal to Cat"); 27 } 28 29 String shout = "HELLO!"; 30 System.out.println("A bit quieter - " + shout.toLowerCase()); 31 } 32 } 33 34
The full source code for this example is in
StringTest.java
.
The output of this example is:
C:\Temp>javac StringTest.java C:\Temp>java StringTest Hello World! The length of this string is 12 characters. Cat is less than Dog The c object is equal to Cat A bit quieter - hello!
As of J2SE 1.5 an alternative format is available as demonstrated in
StringTest2.java
which demonstrates an alternative form (C Style) outputting, where we
can have slightly more control over our output. For example,
... System.out.printf("The length of this string is %d characters.\n", z.length()); ... System.out.printf( "%s is less than %s \n", c, d); ...
This is the new PrintStream
printf
method. This method allows us to use format
specifiers as placeholders for different types, e.g. %d
for an integer variable and
%s
for a string. Note that in this example printf
is used instead
of println
for this task. The %
in the format string denotes the start of a format specifier. The
%s
and %d
in this example indicates the insertion of a String
and
<typename>int</typename> value. The use of a %s
on an object will trigger the call to toString()
.
A full list of the methods available in the String
can
be found in the Java API documentation under the java.lang.String
class description. Note that the String
class is hyperlinked in the notes HTML documentation. Were possible I have hyperlinked standard
classes to provide direct access to the API documentation.
The StringBuffer
object can be used instead of a String
object when more
flexibilty is required in the object. The
StringBuffer
class is mutable and so can grow in size as the application runs.
We can convert directly between a String
object and
a StringBuffer
object when required. Some of the functionality
available in the StringBuffer
includes:
Constructors: StringBuffer() StringBuffer(String s) Methods: int length() char charAt(int index) String toString() StringBuffer append(String s) StringBuffer insert(int offset, String s)
So, for example:
1 2 3 import java.lang.*; 4 5 public class StringBufferTest 6 { 7 public static void main(String args[]) 8 { 9 String s = new String("Hello World!"); 10 StringBuffer buffer = new StringBuffer(s); 11 12 buffer.insert(5, " to the"); 13 14 String t = buffer.toString(); 15 System.out.println(t); 16 } 17 } 18 19
The full source code for this example is in
StringBufferTest.java
Java Arrays are quite like those of C++. There is a special length state that returns the size of the array. With arrays in Java, the Virtual machine constantly checks to see if the index goes out of bounds, and throws an exception if it does (we will talk about exceptions later!).
char s[]; // a variable s to be an array of char int[] anArray; // a variable anArray to be an array of type int int[][] a2DArray; // a 2-D array of type int int initArray[][] = { {1,2,3}, {4,5,6}, {7,8,9} }; // Creates an initialised 3x3 array of type int. //You cannot write int A[5]; as in C++ int myArray[]; // just 4 bytes of memory myArray = new int[10]; // allocate the room for 10 ints.
The rules are similar to C++ when dealing with arrays of objects.
Object objArray[]; objArray = new Object[5]; // we have allocated room for 5 objects, but we have // not created 5 objects. for (int i=0; i<objArray.length; i++) { objArray[i] = new Object(); // create the object using the constructor }
Object
classThis may be a little confusing, but Java has an
Object
class. By default,
every class extends the Object class, even if you don't extend any class. The
Object
class provides methods
that are inherited by all Java classes, such as equals()
, getClass()
, toString()
and
more.
Consider the advantages in a common behaviour of every class:
Since Object
is the parent of all
classes, then every class must have a toString()
method. So when we write System.out.println("Value =" + someObject);
It can immediately be converted to
System.out.println("Value =" + someObject.toString());
by
the compiler, as each object must have this method.
Consider passing data across a network. We could write
methods to send Object
objects (no typo!) across the network. Since every
class extends the Object
class, we can convert any
class to an object of the Object
class, transmit it,
and then extract it again on the receiving end. This will prove very useful.
Class
classObjects of this class, the Class
class
(called class descriptors) are automatically
created and associated with the objects to which they refer. For example,
the getName()
and toString()
methods return the String
containing the name of
the class or interface. We could use this to compare the classes
of objects.
© 2006
Dr. Derek Molloy
(DCU).