A package is a group of related and possibly cooperating classes. All non-private variables and methods of all classes in the package are visible to all other classes in the package. In other words, a package can provide name scoping and access control to methods and variables in the classes belonging to the package. Creating a package is simple.
package utilities.graph;
import java.awt.*;
Encapsulation, is an import part of Object Oriented programming. Hiding data within a class has several advantages (discussed in chapter 1). The visibility of methods and attributes of a class are defined by specific keywords.
If a specific visibility is not defined, a default visibility is used.
the use of the default modifier is not intuitive and should be avoided.
Situation | public | default | protected | private protected | private |
Accessible to non-subclass from same package? | yes | yes | yes | no | no |
Accessible to subclass from same package? | yes | yes | yes | no | no |
Accessible to non-subclass from different package? | yes | no | no | no | no |
Accessible to subclass from different package? | yes | no | no | no | no |
Inherited by subclass in same package? | yes | yes | yes | yes | no |
Inherited by subclass in different package? | yes | no | yes | yes | no |
There is no concept of a free() method or a delete operator. Java has a garbage collector does it for us. By keeping track of the references to objects, the interpreter knows when an object is no longer being referenced. Then it frees the memory object uses.
The garbage collector uses a mark and sweep algorithm for cleaning up. The collector goes through the list of objects and marks the ones that are still being referenced. The collector then goes through and cleans all unmarked objects.
The garbage collector also performs Object.fiinalize() method that is doing nothing by default. You can override this method for some objects, where you need special actions, like closing sockets or file descriptors.
The new keyword allocates memory for the object being created, during runtime. Java does not provide access directly to memory. It provides access to memory through the form of symbolic handles to objects called object references.
The Java keyword new returns an object reference.
private Object _myObject = new Object();
This example creates an instance of a Object and allocates a section of memory for it.
_myObject is a pointer to an instance of Object. It is not a pointer to memory. You can not access memory or have a pointer to memory in Java.
The statement new Object() runs the default constructor for the Object class
| // Example public class Dot { // constructor public Dot() { // do smth ... } } |
There may be times when you want to create objects with different information depending on the circumstance. Imagine a simple class for a circle. The class has a center point at (x, y) and a radius size. There can be several constructors for this one simple class.
Note how the example below uses the this pointer. One constructor can call another by using the this pointer. Only the first executable line of a constructor can use this type of syntax! Chaining constructors reduces the amount of duplicate code being written in constructors.
The super keyword calls the constructor for the superclass. If no call to the superclass constructor is made, Java will implicitly provide one. Using super as a constructor call has the same rule as using this. The call to the superclass constructor has to be the first executable line of a constructor.
public Circle(int iX, iY, int iRadius) { // calls the last constructor this(new Point(iX, iY), iRadius); } public Circle() { // default (no arguments) constructor // calls the next (one argument) constructor this(0); } public Circle (int iRadius) { // calls 3 arguments constructor this(0, 0, iRadius); } public Circle(Point iCenter, int iRadius) { // a single constructor to be executed // super() MUST be the first executable line // it calls for a parent constructor super(); _center = iPoint; _radius = iRadius; }
When a class defines a method with the same name, return type and arguments as a method in its superclass, the method in the class overrides the method in the superclass. When an instance of the class calls the method, the method in the class is used and not the method in the superclass
Overloading, as in the constructor example on the previous page, is not overriding.
/** * Superclass is an example of a parent class * @author jzhuk */ public class Superclass() { private int _x; private int _y; public int method1(int iX) { _x = iX; return _x * _y; } private int method2(int iY) { _y = iY; return _x * _y; } } /** * Subclass is an example of a child class that extends Superclass * @author jzhuk */ public class Subclass extends Superclass { // Override public int method1(int iX) { _x = iX; return _x * _x; } // Overload public int method2(int iX, int iY) { _y = iY; _x = iX; return _x * _y; } }
public class assign1 { public static void main(String args[]) { int a = 10; int b; // compiler ERROR: b must be initialized if (a >= 5) b = 17; System.out.println(b); } }which gives a compile error. The reason for the error is that the Java language has a "definite assignment" rule, which means that a compiler must make a specific check about whether a local variable has been assigned to before its value is used. In the example above, the compiler does not take into account that the value of "a" is known at compile time, and rejects this code.
You can define a method without implementing it by making the method abstract. An abstract method has no body; it just has a signature definition followed by a semicolon.
public abstract class Shape
{
public abstract double area();
public abstract double circumference();
}
An interface looks a lot like an abstract class, except that it uses the keyword interface instead of the words abstract and class. All methods defined in an interface are implicitly abstract and must be public. All variables in an interface must be public, static and final. Why use interfaces if they can only define abstract methods and constants? Abstract classes represent a type hierarchy and interfaces represent optional functionality
public interface Constants
{
public static final int CG_MAX = 100;
public static final int CG_MIN = 0;
}
When a class implements an interface, it inherits the constants. By defining constants this way they can be accessed by just naming the constant.
Creating a constants interface for each package can become very useful when the constants are used all over the package or other packages.
x = CC_MY_CONSTANT * y;
vs.
x = SomeOtherClass.CC_MY_CONSTANT * y;
Implementing any number of interfaces only requires the addition of the keyword implements and the interface name to the class declaration line. If more than one interface is implemented, than commas are used to separate the names of the interfaces.
public class MyClass extends MyParentClass implements OneInterface, TwoInterface { // define a class MyClass and implement all methods // that are defined in OneInterface and TwoInterface }
Interfaces can have sub-interfaces just like classes can have sub-classes. A sub-interface inherits all the abstract methods and constants of its super-interface and may define new constants and abstract methods. One important difference between interfaces and classes is that interfaces support multiple inheritance and classes do not.
public interface One {...}
public interface Two extends One {...}
public interface Three {...}
public interface Four extends Two, Three {...}
All Java classes extend from Object. In other words, Object is the superclass of all classes. There are several public methods in Object that are useful to override.
toString() - println calls the toString() method on a class. If you provide a toString() method, a simple println call can be useful in debugging.
equals() - equals() returns a boolean. If you provide an equals() method, then you can use the syntax:
if (myObject1.equals(myObject2))
to determine if the attributes of the objects are equal.
clone() - clone() returns Object, You have to cast a call to clone(). clone() makes a duplicate copy of the object. If your class has instances of other objects, clone() has to call clone() on those objects ...
Some useful methods to override from Object
// Example of using these methods in the Circle class public class Circle { private Point _center; private int _radius; public String toString() { return new String("Center: x=" + String.valueOf(_center.x) + " y=" + String.valueOf(_center.y) + " Radius = " + _radius); } public boolean equals(Object iObject) { if ((Circle)iObject.getRadius() != _radius) // cast Object to Circle class return false; return (_center.equals((Circle)iOject.getPoint()); } public Object clone() { Point oCenter = new Point(_center.x, _center.y); return (new Circle(oCenter, _radius)); } }