Java Inheritance and OOP Concepts
Java Inheritance and OOP Concepts
In the given program, the 'Student_Name' class inherits from the 'Student' class, demonstrating single-level inheritance. The 'Student_Name' class creates an instance 'p' in the 'Main' class, which invokes the 'Fee()' method from the 'Student' class and the 'Name()' method from the 'Student_Name' class. This illustrates how methods from a superclass can be invoked by a subclass object, showcasing inheritance and method invocation in Java .
The method overriding illustrated by 'Animal' and 'Dog' classes exemplifies polymorphism, where an 'Animal' reference can point to a 'Dog' object, and the overridden 'displayInfo()' method in 'Dog' is called, showing dynamic method dispatch. This finality enables objects to be treated as instances of their superclass, promoting flexibility and scalability by allowing new object behaviors without modifying existing code .
An abstract class in Java, such as 'Language', can have both abstract methods (without a body) and concrete methods (with a body). The class 'Main', which extends 'Language', demonstrates this by implementing the inherited concrete 'display()' method. Unlike regular classes, abstract classes cannot be instantiated directly and must be subclassed, allowing for polymorphism and a structured hierarchy in complex systems .
The 'finalize()' method in Java serves as a final safeguard for freeing resources before an object is garbage collected. It can be overridden to ensure that exclusive resources are released, as shown in 'MyClass', which prints 'Finalize called' during garbage collection. Although its use is rare due to unpredictable invocation timing and the preference for explicit resource management methods, it remains significant for resource cleanup in some legacy systems .
The '@Override' annotation in Java indicates that a method is intended to override a method in a superclass. In the 'Dog' class, '@Override' helps prevent errors by alerting the compiler if the method does not actually override a superclass method, thus providing extra compile-time error checking and ensuring correct method implementation adherence .
Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass. In the given example, the 'Dog' class overrides the 'displayInfo()' method of the 'Animal' class to provide a different output, allowing polymorphic behavior. This is crucial in object-oriented programming, as it enables dynamic method dispatch and ensures that the correct method is called at runtime based on the object's instance .
Inheritance allows for code reuse and logical hierarchy structuring, as demonstrated by reusing 'Fee()' from 'Student' in 'Student_Name'. However, improper use can lead to drawbacks like increased complexity, tight coupling, and difficulty in modifying system behavior. These problems can arise if subclasses depend too heavily on parent classes or if there's insufficient understanding of the inherited functionality .
Proper garbage collection is critical in Java because it automates memory management, preventing leaks and optimizing resource use. The 'MyClass' example demonstrates calling 'System.gc()' after setting 'obj' to null, suggesting explicit memory cleanup. This action prompts the garbage collector to reclaim memory from unused objects, enhancing application performance and resource efficiency, crucial for long-running applications .
Constructors in Java, like the one in 'MyClass', initialize new objects. The example shows a print statement 'Constructor called', highlighting the creation moment of an object. Proper constructor design affects resource allocation by ensuring objects start with a consistent and valid state, which is crucial for resource-intensive operations to avoid leaks and ensure predictable application behavior and performance .
In the 'MyClass' example, the constructor is used to initialize objects, as seen in the message 'Constructor called: Object created.' The 'cleanup()' method demonstrates manual resource cleanup. Although Java does not have destructors, the 'finalize()' method acts as a destructor by freeing resources before object collection, as shown by the 'Finalize called: Object is being collected.' This example highlights Java's garbage collection process and resource management techniques .