Implementing Complex Data Types with Java Classes
Classes and Objects
Classes
- A class is a blueprint for creating objects. It defines the data members (attributes) and methods (functions) that the objects created from the class will have.
- In Java, classes are defined using the
class
keyword. The general syntax is:
class ClassName {
// Data members (attributes)
// Methods (functions)
}
Objects
- An object is an instance of a class. It contains state (data) and behavior (methods).
- The process of creating an object is called instantiation.
- Objects are created using the
new
keyword, which allocates memory for the object. For example:
Rectangle r1 = new Rectangle(); // Creates an object of Rectangle class
Example Program: Classes and Objects
Here’s a breakdown of the example provided in the text:
package classesandobjectsproject;
import java.util.*;
class Rectangle {
private int len, brd; // Data members (attributes)
// Method to get data from the user
public void getData() {
Scanner scn = new Scanner(System.in);
System.out.println("Enter length and breadth:");
len = scn.nextInt();
brd = scn.nextInt();
}
// Method to set data directly
public void setData(int l, int b) {
len = l;
brd = b;
}
// Method to display data
public void displayData() {
System.out.println("Length = " + len);
System.out.println("Breadth = " + brd);
}
// Method to calculate area and perimeter
public void areaPeri() {
int area = len * brd;
int perimeter = 2 * (len + brd);
System.out.println("Area = " + area);
System.out.println("Perimeter = " + perimeter);
}
}
public class ClassesAndObjectsProject {
public static void main(String[] args) {
Rectangle r1, r2, r3; // Define three reference variables
r1 = new Rectangle(); // Create first object
r2 = new Rectangle(); // Create second object
r3 = new Rectangle(); // Create third object
r1.setData(10, 20); // Set data for r1
r1.displayData(); // Display r1's data
r1.areaPeri(); // Calculate and print area and perimeter for r1
r2.setData(5, 8); // Set data for r2
r2.displayData(); // Display r2's data
r2.areaPeri(); // Calculate and print area and perimeter for r2
r3.getData(); // Receive data from keyboard for r3
r3.displayData(); // Display r3's data
r3.areaPeri(); // Calculate and print area and perimeter for r3
}
}
Program Explanation
- Data Members: The class
Rectangle
has two private data members,len
(length) andbrd
(breadth). Making them private restricts direct access from outside the class, protecting the integrity of the data. - Methods:
getData()
: A method that prompts the user to enter the length and breadth.setData(int l, int b)
: A method to set the length and breadth directly using parameters.displayData()
: Displays the current values of length and breadth.areaPeri()
: Calculates and displays the area and perimeter based on the current values of length and breadth.
- Main Class: The
ClassesAndObjectsProject
class contains themain()
method, which is the entry point of the program.- Three
Rectangle
objects (r1
,r2
,r3
) are created. - Data is set for
r1
andr2
usingsetData()
, and results are displayed. - For
r3
, data is obtained from user input through thegetData()
method.
- Three
Access Modifiers
- Private: Data members (
len
andbrd
) are declared private, which means they cannot be accessed directly outside the class. - Public: The methods (
getData()
,setData()
,displayData()
,areaPeri()
) are public, allowing other classes to access them. This provides controlled access to the private data members.
Constructors
What is a Constructor?
- A constructor is a special method that is called when an object is instantiated. It has the same name as the class and does not have a return type.
- Constructors are used to initialize objects, often setting initial values for the data members.
Types of Constructors
- Zero-Argument Constructor: A constructor that does not take any parameters. It initializes data members to default values (e.g., 0, null).
- Parameterized Constructor: A constructor that takes parameters to initialize data members with specific values at the time of object creation.
Example Program: Constructors
Here’s another example demonstrating constructors:
package constructorsproject;
import java.util.*;
class Number {
private int i;
// Zero-argument constructor
public Number() {
}
// One-argument constructor
public Number(int j) {
i = j;
}
public void setData(int j) {
i = j;
}
public void getData() {
Scanner scn = new Scanner(System.in);
System.out.println("Enter any integer:");
i = scn.nextInt();
}
public void displayData() {
System.out.println("Value of i = " + i);
}
}
public class ConstructorsProject {
public static void main(String[] args) {
Number n1, n2, n3;
n1 = new Number(); // Calls zero-argument constructor
n1.displayData(); // Displays default value (0)
n1.setData(200); // Sets value using setData()
n1.displayData(); // Displays updated value
n2 = new Number(); // Calls zero-argument constructor
n2.displayData(); // Displays default value (0)
n2.getData(); // Gets input from the user
n2.displayData(); // Displays user-input value
n3 = new Number(100); // Calls one-argument constructor
n3.displayData(); // Displays value (100)
}
}
Constructor Explanation
- In this example, the
Number
class has both a zero-argument constructor and a one-argument constructor. - When
n1
andn2
are created using the zero-argument constructor, the default value ofi
is0
. - The value of
i
can later be set using thesetData()
method or obtained through user input viagetData()
. n3
is instantiated with the one-argument constructor, which initializesi
directly to100
.
Object Lifecycle and Memory Management
Memory Allocation
- When an object is created using the
new
operator, memory is allocated for that object on the heap. - The reference variable (like
r1
,n1
, etc.) is stored on the stack, holding the memory address of the object.
Garbage Collection
- Java has an automatic Garbage Collector that manages memory. It periodically checks for objects that are no longer referenced and reclaims memory, preventing memory leaks.
- This is different from languages like C++, where the programmer must manually manage memory (allocating and freeing it).
Finalize Method
- The
finalize()
method is defined in theObject
class and can be overridden to perform cleanup operations (like closing files or releasing resources) before an object is destroyed by the garbage collector. - It is called by the garbage collector, but there’s no guarantee when it will be called.
Example Program: Finalize Method
Here’s an example of how the finalize()
method works:
package objectdestructionproject;
class Example {
private int data;
public Example() { // Constructor
System.out.println("Inside the constructor");
}
protected void finalize() throws Throwable {
System.out.println("Inside finalize method");
super.finalize(); // Call to superclass finalize
}
}
public class ObjectDestructionProject {
public static void main(String[] args) {
Example e = new Example(); // Object creation
e = null; // Nullifying reference
System.gc(); // Suggest garbage collection
}
}
Finalization Explanation
- In this example, when the
Example
object is no longer referenced (by settinge
tonull
), the garbage collector is suggested to run usingSystem.gc()
. - Before the object’s memory is reclaimed, the
finalize()
method is called, allowing for any necessary cleanup.
Complex Class Implementation
Class Definition: The Complex
class is designed to represent complex numbers with a real and imaginary part.
class Complex {
private float real, imag;
...
}
Constructors:
- A default constructor initializes a
Complex
object without setting its values.An overloaded constructor initializes aComplex
object with specified real and imaginary parts.
public Complex() {
}
public Complex(float r, float i) {
real = r;
imag = i;
}
Data Input Methods:
getData()
method prompts the user to enter the real and imaginary parts of the complex number.setData(float r, float i)
allows setting values for the complex number.
public void getData() {
...
}
public void setData(float r, float i) {
real = r;
imag = i;
}
Display Method: displayData()
prints the real and imaginary parts of the complex number.
public void displayData() {
System.out.println("real = " + real);
System.out.println("imaginary = " + imag);
}
Arithmetic Operations:
addComplex(Complex y)
adds two complex numbers and returns the result as a newComplex
object.mulComplex(Complex y)
multiplies two complex numbers and returns the result.
public Complex addComplex(Complex y) {
Complex t = new Complex();
t.real = real + y.real;
t.imag = imag + y.imag;
return t;
}
public Complex mulComplex(Complex y) {
Complex t = new Complex();
t.real = real * y.real - imag * y.imag;
t.imag = real * y.imag + y.real * imag;
return t;
}
Main Class for Testing
Creating Complex Numbers: The main
method creates instances of Complex
and performs addition and multiplication on them.
public class ComplexNumbersProject {
public static void main(String[] args) {
Complex c1 = new Complex();
c1.setData(2.0f, 2.0f);
Complex c2 = new Complex();
Complex c3 = c1.addComplex(c2);
...
}
}
Chaining Method Calls: The program demonstrates the ability to chain method calls, such as adding the result of a multiplication directly to another complex number.
c7 = c1.addComplex(c2.mulComplex(c3));
The this
Reference
- The
this
keyword is used to refer to the current object instance. It helps distinguish between instance variables and parameters with the same name, particularly when they are set within methods.
public void setData(int i) {
this.i = i; // Uses 'this' to refer to the instance variable
}
Static Members
- Static members (both variables and methods) belong to the class rather than instances. They are shared among all instances of the class, which is useful for maintaining shared data, like a count of how many objects have been created
class Ex {
private static int count = 0;
...
public static void showCount() {
System.out.println(count);
}
}
Passing Objects to Functions
- Objects are passed by reference, meaning if you modify an object’s data within a method, the changes will reflect outside the method as well.
static void fun(Ex p) {
p.setData(3, 8.5f);
}