Core Java Practical Assignments
Core Java Practical Assignments
Method overriding in the Java program is demonstrated by creating a `Bike2` class that extends the `Vehicle` class. The `run` method in the `Vehicle` class is overridden in the `Bike2` class to provide specific functionality - printing "Bike is running safely" instead of the generic message from the `Vehicle` class. The significance of this process lies in polymorphism, allowing an object of the derived class, `Bike2`, when invoking `run`, to use its own method implementation rather than that of the base class. This demonstration shows how behavior of inherited classes can be customized, enhancing flexibility and robustness in object-oriented design .
The implementation of threads in the Java programs demonstrates basic thread behavior and state management without explicit synchronization. Threads are created by extending the `Thread` class, and their lifecycle—from 'New' to 'Runnable' and 'Terminated'—is showcased using console output of the thread states. The program lacks synchronization mechanisms, implying threads run independently, potentially leading to race conditions if shared resources were involved. This highlights the need for synchronization primitives like `synchronized` blocks or `java.util.concurrent` utilities in more complex threading scenarios to ensure thread safety and data consistency .
The Java program demonstrates file handling by enabling reading user-entered student data and writing it into a file with `FileWriter`. This involves collecting input, such as roll number, name, and marks, and storing it in a file using `write()`. Java’s extensive I/O functionalities facilitate handling character and byte streams effectively. The integration of `Scanner` and `FileWriter` and handling of exceptions show how Java manages both input capture and persistent storage. This highlights Java’s robust I/O capabilities which are crucial for applications requiring data storage and retrieval .
Inheritance is leveraged in the Java program to achieve code reuse by allowing a `Programmer` class to inherit properties from an `Employee` class. The `Employee` class contains a `salary` field, while `Programmer` inherits this field and adds an additional `bonus` field. By inheriting from `Employee`, `Programmer` avoids redundant declaration of `salary`, demonstrating effective code reuse. The program calculates and prints both fields, illustrating inheritance's role in reducing duplicate code and enhancing maintainability .
The Java program utilizes nested loops to print a right-aligned triangle pattern of asterisks by using two loops: an outer loop to iterate over each row and an inner loop to manage the number of asterisks per row. The outer loop runs in decreasing order from 5 to 1, representing the number of asterisks in each row, while the inner loop prints asterisks equal to the current value of the outer loop's counter. After printing the asterisks for a row, the program moves to the next line .
The principles demonstrated by the Java class on object construction and destruction include resource management and cleanup operations. The class `cons` implements a constructor to initialize objects and print "Hello" when an instance is created. Additionally, it includes a `finalize` method (destructor) to be called by the garbage collector before an object is destroyed, executing `System.gc()`, which explicitly calls the garbage collector and prints "Destroyed" when the object is null and collected. This highlights resource allocation during object creation and necessary cleanup, ensuring efficient memory usage by releasing resources no longer needed .
The Java program converts a decimal number to binary using `Integer.toBinaryString(d)`, which transforms an integer `d` into a binary string representation. Conversely, it converts a binary string back to a decimal by passing it to `Integer.parseInt(b,2)`, which interprets string `b` as a binary number and converts it to a decimal integer. This method is effective due to its simplicity and reliance on built-in methods that handle conversions efficiently, abstracting the complexity of manual binary calculations and reducing potential errors in conversion logic .
The Java program employs file input and output operations using `FileInputStream` and `FileOutputStream`. The `FileInputStream` reads data from a specified file by iteratively using the `read()` method in a loop until it reaches the end of the file. For output, `FileOutputStream` writes data to another file within a loop that reads from the input stream and writes each byte to the output stream using `write()`. The program closes both streams after operations to ensure resource management and prevent memory leaks. These strategies ensure efficient handling and manipulation of file data .
The Java implementation demonstrates abstract classes using the `calc` class, which declares abstract methods `sqr` and `cube` without providing implementations. The subclass `pract4` implements these methods, defining how they operate. The use of abstract classes is significant because it allows for defining a common interface and deferring implementation details to subclasses, promoting a design pattern that encourages abstraction and modularity, enabling diverse implementations of methods defined in the abstract class .
The class `SortData` manipulates array data by employing Java's `Arrays` class methods to sort integer arrays. Two functions, `asec()` and `desc()`, demonstrate sorting operations: `asec()` uses `Arrays.sort()` to sort the array in ascending order, while `desc()` utilizes `Arrays.sort()` combined with `Collections.reverseOrder()` to sort the same array in descending order. These showcase how Java's collection APIs provide efficient mechanisms for data manipulation, offering both ascending and descending sort capabilities in a straightforward manner .