CS8392 Object Oriented Programming Exam
CS8392 Object Oriented Programming Exam
Encapsulation in Java is the practice of wrapping data (variables) and code acting on the data (methods) as a single unit or object. It helps maintain data integrity and security by restricting outside access to the internal state or variables, which only can be accessed through well-defined interfaces or methods. This promotes code security by preventing outside elements from altering the state of the object directly, reducing potential bugs and unintended side-effects .
Synchronization in Java is a mechanism that restricts multiple threads from accessing shared resources or critical sections simultaneously, ensuring thread safety and preventing race conditions. It is critical in scenarios where concurrent modifications to shared resources can lead to inconsistent data states. For example, synchronizing a method that updates a shared counter variable ensures that only one thread can modify it at a time, preventing data corruption when multiple threads attempt to increment the counter simultaneously .
Abstract classes in Java are classes that cannot be instantiated and are designed to be subclassed. They are significant when some base class functionalities need to be inherited by multiple subclasses, while also requiring additional subclass-specific implementations. Abstract classes can include both completed methods and abstract methods. They are preferable over interfaces when you want to provide a common base with shared code among different classes, such as sharing state or utility methods, which is not possible with interfaces as they do not hold fields .
Interfaces in Java facilitate polymorphism by allowing a class to implement multiple interfaces, thus defining multiple types of behavior that can be used polymorphically. Interfaces allow an object to be treated as an instance of any interface it implements, promoting flexibility in coding. However, interfaces lack the capability to store state or provide method implementations, which abstract classes can do. This means interfaces cannot offer shared code or fields, limiting code reuse to method contracts and requiring implementing classes to define all behavior, unlike abstract classes that can offer a mix of abstract methods and implemented methods .
Java Generics enable types (classes and interfaces) to be parameters when defining classes, interfaces, and methods, improving type safety by enforcing compile-time checks and reducing runtime errors. With generics, you can ensure that a collection contains only elements of a specific type, preventing errors like `ClassCastException`. For example, a parameterized class `Box<T>` allows you to specify the type of object to be stored using `Box<Integer>` or `Box<String>`, ensuring that only integers or strings are stored respectively, avoiding mismatched type operations .
Checked exceptions in Java are exceptions that must be either caught or declared in the method, whereas unchecked exceptions are not required to be handled or declared. Checked exceptions relate to conditions outside the control of program execution, such as IO errors, whereas unchecked exceptions are due to programming errors like illegal argument or null pointer references. This distinction influences how developers approach error handling, ensuring mandatory checking of recoverable exceptions with checked exceptions and permitting unchecked exceptions to be handled explicitly based on the application's requirements and robustness goals .
The `extends` keyword in Java is used to denote inheritance from a superclass, allowing a subclass to inherit fields and methods from it, establishing a class hierarchy. This keyword helps organize code into a well-structured framework by defining parent-child relationships between classes, facilitating method overriding and code reuse. For example, in a class hierarchy where a `Vehicle` class is extended by `Car` and `Bike`, both `Car` and `Bike` inherit common behaviors from `Vehicle` which they can further extend or override based on specific needs .
Using exceptions for error handling in Java provides clearer code structure and facilitates separation of error-handling logic from regular code flow compared to traditional error-checking methods. Exceptions enable a clean propagation of error states through method calls via throw mechanisms, reducing the need for constant error checks after each operation. This results in improved readability and maintainability of the code, as error handling is decoupled and programmed in a concentrated manner. Compared to traditional methods that mix error codes with normal logic, exceptions allow for centralized handling per exception type, simplifying debugging and supporting robust program execution .
In Java, a thread can be in one of several states: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, or TERMINATED. These states impact execution by determining the thread's ability to execute and its position within the thread scheduler. NEW indicates a thread that has not yet started; RUNNABLE signifies it is ready to run or currently executing; BLOCKED indicates it is waiting to enter a synchronized block/method; WAITING and TIMED_WAITING indicate it is waiting for another thread's action or specified time respectively; TERMINATED denotes completion of execution. Understanding these states helps in proper management and control of concurrency, especially when dealing with synchronization and context switching .
Polymorphism in Java allows objects to be treated as instances of their parent class, enhancing software flexibility by enabling a single method to operate on different types of objects. Method overriding exemplifies polymorphism where a subclass provides a specific implementation of a method declared in its superclass, allowing the same method name to behave differently based on the object type used at runtime. This approach increases software reusability and flexibility as new subclasses can override the method without altering the base class .