GTU Object Oriented Programming - I (Java) Summer 2021 PYQ with solutions

Download Question Paper : click here

Q.1

A. Define object oriented concepts.

  1. Abstraction: This is the process of reducing complex real-world problems into smaller, more manageable components that can be represented as objects.
  2. Encapsulation: This involves hiding the internal details of an object from the outside world. This is achieved by defining public and private methods and variables within the object.
  3. Inheritance: This allows objects to inherit properties and methods from a parent class. This makes it possible to reuse code and create objects with similar functionality.
  4. Polymorphism: This refers to the ability of objects to take on multiple forms. This allows for the use of objects with different data types and allows methods to be overridden and redefined in child classes.
  5. Class and Objects: Class is the blueprint or prototype from which the object is created. Object is the instance created from the class.

B. What is the difference between the StringBuffer and StringBuilder

classes?

StringBufferStringBuilder
Thread-safe (synchronized)Not thread-safe (unsynchronized)
Slower performance due to synchronizationFaster performance due to lack of synchronization
Designed for multithreaded environmentsDesigned for single-threaded environments
Can be accessed and modified by multiple threadsCan only be accessed and modified by one thread at a time
Provides methods for appending, inserting, deleting, and replacing characters in a stringProvides methods for appending, inserting, deleting, and replacing characters in a string
Should be used when thread safety is a concernShould be used when performance is a concern

C. Define constructor. How objects are constructed? Explain constructor

overloading with an example.

  • A constructor is a special method that is used to initialize an object in Java. It is called when an object is created and its purpose is to ensure that the object is in a valid state before it is used.
  • The name of the constructor is the same as the name of the class.
  • Constructors are called automatically when the object is created.
  • When an object is created in Java, memory is allocated for the object and its variables. The constructor is then called to initialize the object's variables and ensure that the object is in a valid state. Once the constructor has completed its initialization, the object is ready to be used. To Create a object :
Class object = new Class() // default constructor
  • Constructor overloading is the process of defining multiple constructors in a class with different parameters. This allows objects to be initialized in different ways depending on the arguments passed to the constructor. Here is an example of constructor overloading:
  • Every overloaded constructor must be different in terms of parameters or return type.
public class Person {
    String name;
    int age;

    public Person() {
        name = "John Doe";
        age = 18;
    }

    public Person(String name) {
        this.name = name;
        age = 18;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Q.2

(a) Explain about arrays, Type of arrays and arrays methods.

  • Array is a fixed sized sequenced collection of data that are of same datatype.
  • Array’s are immutable.
  • It is used to store data of similar datatype.
  • Types of arrays:
  1. One-Dimensional Array: This is a simple type of array that consists of a single row of elements. Each element in the array is identified by its index position within the array.
  2. Two-Dimensional Array: This is an array that consists of multiple rows and columns of elements. Each element in the array is identified by its row and column position within the array.
  3. Multi-Dimensional Array: This is an array that consists of more than two dimensions. For example, a three-dimensional array would consist of multiple layers of rows and columns of elements.
  • Some of the Array methods that are extensively used are: length(), push(), pop(), shift(), unshift(), indexOf() etc.

(b) Explain about Encapsulation, Abstraction.

  • Encapsulation and Abstraction are two important concepts in object-oriented programming (OOP) and are closely related to each other. Both these concepts are used to improve the reliability and maintainability of the code.
  1. Encapsulation:
  • Encapsulation is the process of hiding the internal details of an object from the outside world. It is a technique of binding together the data and the methods that operate on that data, into a single unit called a class. The main purpose of encapsulation is to protect the data from external interference and to ensure that it can be accessed only through the methods defined in the class.
  • Encapsulation is achieved by declaring the instance variables of a class as private and providing public methods, also known as getters and setters, to access and modify the values of those variables.
  1. Abstraction:
  • Abstraction is the process of hiding the implementation details of a system and exposing only the essential features to the users. It is a technique of creating a simplified view of a complex system, which makes it easier to understand and use.
  • Abstraction is achieved by using abstract classes and interfaces. An abstract class is a class that cannot be instantiated and is used as a base class for other classes. It defines the common properties and methods that are shared by its subclasses, but leaves the implementation of those methods to the subclasses.

(c) State the design hints for class and inheritance.

Also discuss the working and meaning of the “static” modifier with suitable examples.

  • Class is the blueprint or prototype for the objects to be made. It is the collection of different variables and methods for that variable.
  • Inheritance is the process of acquiring the protected and public properties of another class.
  • While designing one common approach is to group the common functionalities of various classes into one class and then inheriting that class into different classes with common functionalities.
  • This reduces the CODE repetition. also supports DRY (Don’t Repeat Yourself).
  • while designing we also have to decide if we should allow modification of base properties or we completely leave the implementation of those method to the extending classes.
  • To restrict the modification of property of base class we declare it final. Or if we want to mandate the implementation of a particular property by extending classes we declare that function abstract.
  • Interface only have abstract methods but abstract classes may make some methods abstract and implement some of the method by itself.

Static

  • ****The "static" modifier in Java is used to create class-level variables and methods that can be accessed without creating an instance of the class. This means that the variable or method belongs to the class itself, not to any particular object of the class.
  • Static variables and functions are shared by all the instances of the class.
  • It is used to share data between instances of the class.
public class MyClass {
    private static int count = 0;
    private int id;
    public MyClass() {
        count++;
        id = count;
    }
    public static int getCount() {
        return count;
    }
        public static void main(String[] args){
            MyClass obj = new MyClass();
            System.out.println(MyClass.getCount())
        }
}

(c) Explain in detail how inheritance and polymorphism are supported in java with necessary examples.

Inheritance and polymorphism are two important concepts in object-oriented programming that are supported in Java. Inheritance is a mechanism where a new class is created from an existing class, and the new class inherits all the properties and methods of the existing class. Polymorphism, on the other hand, is the ability of an object to take on many forms, i.e., it can behave differently in different contexts.

Inheritance: is the process of the inheriting the protected and public properties of another class.

  • Inheritance helps in Code reusability and Code structuring.
  • inheritance is implemented using the "extends" keyword. The new class that is created is called the subclass, and the existing class is called the superclass. The subclass inherits all the properties and methods of the superclass and can add new properties and methods as well.
  • Inheritance call also be implemented using “implements” keyword for inheriting Interfaces.
class Vehicle {
  String name;
  String color;
  void start() {
    System.out.println("Starting the vehicle...");
  }
  void stop() {
    System.out.println("Stopping the vehicle...");
  }
}

class Car extends Vehicle {
  int speed;
  void accelerate() {
    System.out.println("Accelerating the car...");
  }
  void brake() {
    System.out.println("Applying the brakes...");
  }
}
public class Example{
    public static void main(String[] args)
    {
        Car car = new Car();
        car.name = "BMW";
        car.color = "Red";
        car.speed = 60;


        car.start();
        car.accelerate();
        car.brake();
        car.stop();
    }
}

Polymorphism

  • Polymorphism is the ability to take more than one form. i.e. It can behave differently in different circumstances.
  • polymorphism is implemented using two mechanisms: method overriding and method overloading.
  • Method overriding is a mechanism where a subclass provides its own implementation for a method that is already defined in the superclass. The method in the subclass has the same name, return type, and parameters as the method in the superclass.
  • Method overloading is a mechanism where a class can have multiple methods with the same name but different parameters. The method to be called is determined based on the number and type of arguments passed.
class Vehicle {
  String name;
  String color;
  void start() {
    System.out.println("Starting the vehicle...");
  }
  void stop() {
    System.out.println("Stopping the vehicle...");
  }
}

class Car extends Vehicle {
  int speed;
  void start() {
    System.out.println("Starting the car...");
  }
  void accelerate() {
    System.out.println("Accelerating the car...");
  }
  void brake() {
    System.out.println("Applying the brakes...");
  }
}
public class Example{
    public static void main(String[] args)
    {
        Car car = new Car();
        car.start();
    }
}

Q.3

(a) Explain about different types of string methods.

  • strings are objects of the Stringclass, which has many built-in methods that can be used to manipulate and work with strings. Here are some of the commonly used string methods in Java:
  1. length(): This method returns the length of the string.
  2. charAt(int index): This method returns the character at the specified index in the string.
  3. indexOf(String str): This method returns the index of the first occurrence of the specified substring in the string, or -1 if the substring is not found.
  4. toLowerCase(): This method returns a new string with all the characters in lowercase.
  5. toUpperCase(): This method returns a new string with all the characters in uppercase.
  6. split(String regex): This method splits the string into an array of substrings based on the specified regular expression.
  7. equals(Object obj): This method returns true if the string is equal to the specified object, and false otherwise.

(b) Write short notes on access specifiers and modifiers in java.

  • Access specifiers are used to define the level of access that other classes or packages have to a particular class member. There are four access specifiers in Java:
  1. Public: Public members are accessible to all classes, regardless of package.
class MyClass{
    **public** void method() {
        //code
    }
}
  1. Private: Private members are only accessible within the same class.
class MyClass{
    **private** void method() {
        //code
    }
}
  1. Protected: Protected members are accessible within the same package and in subclasses.
class MyClass{
    **protected** void method() {
        //code
    }
}
  1. Default: Default members are accessible within the same package.
class MyClass{
    void method() {
        //code
    }
}
  • Modifiers, are used to modify the behavior or characteristics of a class member. Some of the common modifiers in Java are:
  1. Final: Final members cannot be modified once they are initialized.
class MyClass {
    **final** float PI = 3.14f;
}
  1. Static: Static members belong to the class and not to the instance of the class.
class MyClass {
    static void count(){
        //static code
    }
}
  1. Abstract: Abstract members are declared but not implemented in the class, and must be implemented in the subclass.
abstract class MyClass {
    abstract void implementThis();
}
  1. Synchronized: Synchronized members are used for thread synchronization.
class MyClass {
    synchronized void update(){
        // synchornized code
    }
}

(c) What is an Exception? Explain the exception hierarchy. Explain how

to throw, catch and handle Exceptions.

  • An Exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. It can be caused by many factors such as invalid user input, hardware or software failure, or system resource exhaustion. Exceptions are represented by objects that belong to the class hierarchy called "Throwable".
  • The Throwable class is the root of the exception hierarchy in Java. It has two main subclasses: Exception and Error. Exceptions are used to represent exceptional conditions that can be handled programmatically, while Errors are used to represent serious problems that should not be handled programmatically.
  • There are many types of exception classes which extends Exception class. Some of that classes are: ‘ArrayIndexOutOfBoundsException’, ‘ArithmeticException’, ‘NumberFormatException’.

https://programmers.io/wp-content/uploads/2021/12/Java-Exceptions-Hierarchy.jpg

Throwing an Exception:

  • You can throw an exception explicitly in your code using the "throw" keyword. For example, if you want to throw an exception when a method receives invalid input, you can write:
  • You can also throw CustomException created by extending the Exception class.
if (input < 0) {
   throw new IllegalArgumentException("Input must be a positive number.");
}

Catching and Handling an Exception:

  • To catch an exception and handle it gracefully, you use a try-catch block. You place the code that might throw an exception inside the try block, and the code that handles the exception inside the catch block. For example:
try {
   // code that might throw an exception
} catch (ExceptionType e) {
   // code that handles the exception
}
  • We can also group multiple catch blocks together to handle various types of exceptions.
  • To handle exception we can also use finally block to execute the clean-up code. Finally block always runs even if exception occurs or not.
try {
   // code that might throw an exception
} catch (ExceptionType e) {
   // code that handles the exception
} finally {
   // code that is executed regardless of whether an exception is thrown or not
}

Q.3

(a) Explain about Final class, Fields, Methods.

Final Class

  • Final class is a class that cannot be extended or subclassed. It means that we cannot create a subclass of final classes. Doing so will give an error.
  • Final classes are useful when we want to restrict the extension or inheritance hierarchy of the current class.
  • For example : String class in java is a final class, which means we cannot create a subclass of String class.

Final Fields

  • Final Fields in a Non changeable variable that belongs to a particular class or an object. Fields are used to store data that can be accessed by method or object.
  • We cannot modify the final field.
  • We must initialize final field during the time of declaration.
  • We can use different access modifiers during the time of declaring final fields.

Final Methods

  • Final Methods declared in class is a collection of statements that performs a specific task.
  • Final methods cannot be overridden by the subclass of the class in which the final method in defined.
  • Final methods are used when we want to ensure certain functionality mustn’t be modified by the subclass.

(b) What is a Package? What are the benefits of using packages? Write

down the steps in creating a package and using it in a java program with an example.

  • A package is a collection of classes defined in it. It is a way of organizing related classes and interfaces.
  • It helps preventing naming conflicts and make it easier to manage code.

Benefits

  1. Modularity: Packages allow you to group related classes, interfaces, and sub-packages together in a modular way. This makes the code more organized and easier to maintain.
  2. Encapsulation: Packages provide a level of encapsulation that helps to hide the implementation details of a package from other packages.
  3. Reusability: Packages make it easier to reuse code across different projects.

Steps to create a package.

  1. Create a directory with the name of your package.
  2. Create your Java files and save them in the directory.
  3. Every java file you want to place in package should be saved inside this directory.
  4. Every java file should have this statement as its first statement.
package packageName;

Steps to use a package

  • To use another package inside current file we need to import that package.
  1. Import Package
import packageName.*; // will import all the classes inside packageName package.
import packageName.Class1; // will import only Class1 from packageName package.
  1. use Class
// we can use this Class1 to instantiate a object and use its properties.
Class1 obj = new Class1();
obj.property();
  • package can also contain another package inside them which will create package hierarchies.
  • we can import nested packages like :
import package1.package2.class; // use this class in the same way

(c) Explain the concept of inner classes and explain the types of inner

classes with an example program.

  • An inner class is a class that is defined within another class. Inner classes have access to the members (fields and methods) of the outer class, including private members, and they can also be used to encapsulate logic within the outer class or provide a way to define a class that is closely related to the outer class.
  • There are four types of Inner class:
    1. Nested Inner Class
    2. Method Local Inner Classes
    3. Static Nested Classes
    4. Anonymous Inner Classes
  1. Nested Inner Class:
  • It can access any private instance variable of the outer class. Like any other instance variable, we can have access modifier private, protected, public, and default modifier. Like class, an interface can also be nested and can have access specifiers.
  • We can not have a static method in a nested inner class

class Outer {
    class Inner {
        public void show() {
            System.out.println("In a nested class method");
        }
    }
}
class Main {
    public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();
        in.show();
    }
}
  1. Method Local Inner Class :
  • Inner class can be declared within a method of an outer class which we will be illustrating in the below example where Inner is an inner class in outerMethod().

class Outer {
    void outerMethod() {
        System.out.println("inside outerMethod");
        class Inner {
            void innerMethod() {
                System.out.println("inside innerMethod");
            }
        }
        Inner y = new Inner();
        y.innerMethod();
    }
}
class GFG {
    public static void main(String[] args) {
        Outer x = new Outer();
        x.outerMethod();
    }
}
  1. Static Nested Classes
  • Static nested classes are not technically inner classes. They are like a static member of outer class.
import java.util.*;
class Outer {
    private static void outerMethod() {
        System.out.println("inside outerMethod");
    }
    static class Inner {
        public static void display() {
            System.out.println("inside inner class Method");
            outerMethod();
        }
    }
}
class GFG {
    public static void main(String args[]) {
        Outer.Inner.display();
    }
}
  1. Anonymous Inner Class

Anonymous inner classes are declared without any name at all. They are created in two ways.

  • As a subclass of the specified type
  • As an implementer of the specified interface
import java.util.*;
class Demo {
    void show() {
        System.out.println(
            "i am in show method of super class");
    }
}
class Flavor1Demo {
    static Demo d = new Demo() {
        void show() {
            super.show();
            System.out.println("i am in Flavor1Demo class");
        }
    };
}
interface Hello {
    void show();
}
class GFG {
    static Hello h = new Hello() {
        public void show() {
            System.out.println("i am in anonymous class");
        }
    };
}

Q.4

(a) What is Dynamic binding? Show with an example how dynamic

binding works.

  • When type of the object is determined at run-time, it is known as dynamic binding.
  • It allows for polymorphism, where objects of different classes can be treated as if they belong to the same type, and their appropriate methods are invoked based on their actual type at runtime.
class Animal {
     void eat(){
            System.out.println("animal is eating...");
     }
}
class Dog extends Animal{
     void eat(){
            System.out.println("dog is eating...");
    `}
     public static void main(String args[]){
          Animal a=new Dog();
          a.eat();
     }
}

(b) Write short notes about I/O stream classes.

  • I/O (Input/Output) stream classes are used for reading and writing data from and to various sources, such as files.
  • They provide an abstraction for performing I/O operations in a standardized way. Here's a brief explanation of commonly used I/O stream classes
  1. InputStream and OutputStream : abstract base classes for reading and writing binary data.
  2. FileInputStreamand FileOutputStream : classes are used for reading and writing binary data from and to files on the local file system.
  3. BufferedInputStreamand BufferedOutputStream : classes provide buffering capabilities for input and output operations, improving performance.
  4. Reader and Writer : abstract base classes for reading and writing character data.
  5. FileReader and FileWriter: classes are used for reading and writing character data from and to files on the local file system.
  6. BufferedReader and BufferedWriter : classes provide buffering capabilities for character input and output operations, improving performance by reading and writing characters in larger chunks.
  7. PrintStream and PrintWriter : classes provide methods for printing formatted output to various destinations, such as the console or files.

(c) Explain the thread state, thread properties and thread synchronization.

  • Thread is a very light-weighted process, or we can say the smallest part of the process that allows a program to operate more efficiently by running multiple tasks simultaneously.
  • Thread can be Implemented in two ways :
    • Extending Thread class
    • Implementing Runnable Interface
  • During program execution thread can be in several states : https://programmerbay.com/wp-content/uploads/2020/01/final-thread-lifecycle.jpg
    • New : The thread has been created but has not yet started.
    • Runnable : The thread is currently executing or is eligible to be executed by the CPU.
    • Blocked / Waiting : The thread is waiting for some operation to be completed.
    • Running : Thread is currently Running process on the CPU.
    • Terminated : The thread has completed its execution and has terminated.
  • Thread Properties : Threads in Java have several properties that can be accessed and modified using methods provided by the Thread class. Some of the commonly used thread properties are:
    • Thread name: Each thread has a name that can be set or retrieved using the setName() and getName() methods, respectively.
    • Thread priority: Threads can have different priority levels ranging from 1 (lowest) to 10 (highest), which can be set or retrieved using the setPriority() and getPriority() methods, respectively.
  • Thread Synchronization
    • In multithreaded application, thread synchronization is important to ensure that threads can safely access shared resources without conflicts or inconsistencies.
    • Java provides several mechanism for thread synchronization :
      • Synchronized blocks : A synchronized block is a section of code that can only be executed by one thread at a time, preventing multiple threads from concurrently accessing shared resources. Synchronized blocks are defined using the synchronized keyword. java synchronized void printTriagle() { // Prints triangle // Only one thread can access this method at a time }
      • Inter-Thread Communication : Java provides methods like wait(), notify(), and notifyAll().
        • wait() methods makes the thread to wait in a blocked state until another thread calls notify() or notifyAll() method.
        • notify() to wake up a another sleeping thread
        • notifyAll() to wake up all the sleeping threads.
    • Thread synchronization is crucial to prevent issues such as data races, deadlocks, and other concurrency-related bugs in multithreaded applications, and should be carefully implemented to ensure correct and reliable behavior of concurrent threads.

Q.4

(a) Explain the concept of finalization.

  • Finalization is a mechanism provided by the Java Virtual Machine (JVM) to perform cleanup operations on objects before they are garbage collected.
  • When an object becomes unreachable and is eligible for garbage collection, the JVM invokes the object's finalize() method (if it has been defined) to perform any necessary cleanup actions.
  • The finalize() method is a special method that is automatically called by the JVM during the garbage collection process.
  • The finalize()method is a protected method defined in the java.lang.Object class, which is the base class for all objects in Java. It can be overridden in subclasses to provide custom cleanup logic for objects before they are garbage collected.
    • Syntax of finalize() method :
protected void finalize() throws Throwable {
    // Cleanup logic here
}

(b) What is reflection and how does it help to manipulate java code.

  • Reflection is an API that is used to examine or modify the behavior of methods, classes, and interfaces at runtime. The required classes for reflection are provided under java.lang.reflect  package which is essential in order to understand reflection.
  • Reflection gives us information about the class to which an object belongs and also the methods of that class that can be executed by using the object.
  • Through reflection, we can invoke methods at runtime irrespective of the access specifier used with them.

https://media.geeksforgeeks.org/wp-content/cdn-uploads/reflection.png

  • ****Reflection can be used to get information about class, constructors, and methods as depicted below in tabular format as shown:
ClassThe getClass() method is used to get the name of the class to which an object belongs.
ConstructorsThe getConstructors() method is used to get the public constructors of the class to which an object belongs.
MethodsThe getMethods() method is used to get the public methods of the class to which an object belongs.
  • We can invoke a method through reflection if we know its name and parameter types. We use two methods for this purpose as described below before moving ahead as follows:
  1. getDeclaredMethod()
Class.getDeclaredMethod(name, parametertype)
  1. invoke()
Method.invoke(Object, parameter)

(c) Write a java program to implement the multiple inheritance concepts

for calculating area of circle and square.

interface Circle {
    void calculateCircleArea();
}
interface Square {
    void calculateSquareArea();
}
class Shape implements Circle, Square {
        int side = 0;
        float radius = 0.0f;
        public Shape(int r) {
            radius = r;
        }
        public Shape(int s) {
            side = s;
        }
    public void calculateCircleArea() {
            System.out.println("Area of Circle : " + (Math.PI * radius * radius));
    }
        public void calculateSquareArea() {
            System.out.println("Area of Square : " + (side * side));
    }
        public void printArea()
        {
            if(side != 0) {
                    calculateSquareArea();
            }
            if(radius != 0.0f) {
                    calculateCircleArea();
            }
        }
}
public class MulInher {
    public static void main(String[] args) {
        Shape s = new Shape(2.3f);
        s.printArea();
    }
}

Q.5

(a) Explain about callback

  • A callback is a mechanism that allows a piece of code to be executed at a later time, usually in response to an event. A callback is essentially a reference to a method that is passed as an argument to another method.
  • When the method that accepts the callback is executed, it calls the callback method, passing any necessary arguments. This allows the caller to specify custom behavior that will be executed at a later time, without having to modify the original method.
  • Callbacks are often used in event-driven programming, where an application responds to user input or other external events. For example, a button click event in a graphical user interface (GUI) might trigger a callback method that updates the display or performs some other action.
  • In Java, callbacks are typically implemented using interfaces or functional interfaces. An interface defines the signature of the callback method, and a class that implements the interface provides the actual implementation of the method.
public interface MyCallback {
    void onComplete(int result);
}
public class MyTask {
    public void doWork(MyCallback callback) {
        int result = 42;
        callback.onComplete(result);
    }
}
public class MyApp {
    public static void main(String[] args) {
        MyTask task = new MyTask();
        MyCallback callback = new MyCallback() {
            public void onComplete(int result) {
                System.out.println("Result: " + result);
            }
        };
        task.doWork(callback);
    }
}

(b) Explain the interface with an example program.

  • An interface is a collection of abstract methods and constants that can be implemented by a class. It defines a contract that specifies the methods that a class must implement, but does not provide an implementation of those methods.
  • Interface is similar to class but it only contains abstract methods and final variables.
  • Class implementing a interface must define all abstract methods declared inside interface.
  • Interface is also used to implement multiple inheritance.
public interface Animal {
    void makeSound();
    void move();
}
public class Cat implements Animal {
    public void makeSound() {
        System.out.println("Meow");
    }

    public void move() {
        System.out.println("Walking");
    }
}
public class MyApp {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.makeSound(); // prints "Meow"
        animal.move(); // prints "Walking"
    }
}

(c) What is Generic programming and why is it needed? Explain with example. List the limitations and restrictions of generic programming.

  • Generic programming in Java is a feature that allows for the creation of classes and methods that can work with different types of objects. It provides a way to write code that is type-safe and reusable across different data types.
  • Generics are declared using angle brackets (< and >), and can be used with classes, interfaces, and methods. The type parameter is specified in the angle brackets, and is used as a placeholder for the actual data type that will be used when the code is executed.
  • Example of Generic class :
public class Box<T> {
    private T data;

    public void setData(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }
}
  • In this example, the Box class is generic, with a type parameter T. The setData() and getData() methods can work with any type of object, as specified by the type parameter.
public class MyApp {
    public static void main(String[] args) {
        Box<Integer> box = new Box<>();
        box.setData(42);
        int data = box.getData();
        System.out.println(data); // prints 42
    }
}
  • In this example, we create a Box object with a type parameter of Integer. We then set the data to 42 using the setData() method, and retrieve the data using the getData() method. Since we specified the type parameter as Integer, the compiler knows that the data is of type Integer, and we can assign it to an int variable.
  • Limitations of Generic Programming :
    1. Type erasure: Generics in Java are implemented using type erasure, which means that the type parameter is removed at runtime, and the actual data type is unknown. This can result in some limitations, such as the inability to create new instances of the type parameter.
    2. Inheritance: Generic classes cannot extend Throwable, which means they cannot be used for exception handling.
    3. Static context: Type parameters cannot be used in a static context, such as a static field or a static method.
    4. Type bounds: Type parameters can be bounded by a specific type or an interface, but not by a class.
    5. Performance: Using generics can result in a slight performance hit, due to the additional overhead of type checking and type casting.

Q.5

(a) Explain about Proxy class, Interface and Methods.

  • In Java, a proxy class is a class that implements a given interface by forwarding method calls to another object. It acts as a wrapper or surrogate for the underlying object, intercepting method calls and performing additional processing before or after the call.
  • To create a proxy class in Java, you need to define an interface and an implementation class, and then use the Proxy class to create a dynamic proxy object that implements the interface. Here's an example:
public interface MyInterface {
    void myMethod();
}
public class MyImplementation implements MyInterface {
    public void myMethod() {
        System.out.println("MyImplementation.myMethod() called");
    }
}
public class MyProxy implements InvocationHandler {
    private Object target;

    public MyProxy(Object target) {
        this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method call");
        Object result = method.invoke(target, args);
        System.out.println("After method call");
        return result;
    }
    public static void main(String[] args) {
        MyImplementation obj = new MyImplementation();
        MyProxy proxy = new MyProxy(obj);
        MyInterface proxyObj = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(), new Class[] {MyInterface.class}, proxy);
        proxyObj.myMethod();
    }
}
  • In the invoke() method of the MyProxy class, we print a message before and after calling the target object's method, and then return the result of the method call. In the main() method, we create an instance of the MyImplementation class and a proxy object using the Proxy class. We then call the myMethod() method on the proxy object, which in turn calls the implementation in the MyImplementation class.

(b) Explain about adapter classes and mouse events with an example.

  • Adapter Classes : Adapter classes in Java provide a way to create a listener without the need to implement all the methods of an interface. Instead, you can extend an adapter class, which provides default implementations for all the methods of the interface, and override only the methods you are interested in. This can make your code simpler and easier to read.
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;

public class MyFrame extends JFrame {
  public MyFrame() {
    // Set up the frame...
    // Add a mouse listener using an adapter
    addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
        // Handle the mouse press event...
      }
    });
  }
}
  • Mouse Events
    • MouseListener : Mouse Listener interface can be used to listen various mouse events such as
      1. void mouseReleased(MouseEvent e) : Mouse key is released
      2. void mouseClicked(MouseEvent e) : Mouse key is pressed/released
      3. void mouseExited(MouseEvent e) : Mouse exited the component
      4. void mouseEntered(MouseEvent e) : Mouse entered the component
      5. void mousepressed(MouseEvent e) : Mouse key is pressed
        • Class Implementing the MouseListener Interface need to implement all the methods listed here. OR. MouseAdapter can be used to use the default behaviour of MouseListener Interface.
    • MouseMotionListener : is used to listener all Mouse Movement Events such as :
      1. void mouseDragged(MouseEvent e) : Invoked when a mouse button is pressed in the component and dragged. Events are passed until the user releases the mouse button.
      2. void mouseMoved(MouseEvent e) : invoked when the mouse cursor is moved from one point to another within the component, without pressing any mouse buttons. java import java.awt.*; import java.awt.event.*; import javax.swing.*; class Mouse extends Frame implements MouseListener { Mouse() { } public static void main(String[] args) { JFrame f = new JFrame("MouseListener"); f.setSize(600, 100); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel p = new JPanel(); p.setLayout(new FlowLayout()); label1 = new JLabel("no event "); label2 = new JLabel("no event "); label3 = new JLabel("no event "); Mouse m = new Mouse(); f.addMouseListener(m); p.add(label1); p.add(label2); p.add(label3); f.add(p); f.show(); } public void mousePressed(MouseEvent e) { label1.setText("mouse pressed at point:" + e.getX() + " " + e.getY()); } public void mouseReleased(MouseEvent e) { label1.setText("mouse released at point:" + e.getX() + " " + e.getY()); } public void mouseExited(MouseEvent e) { label2.setText("mouse exited through point:" + e.getX() + " " + e.getY()); } public void mouseEntered(MouseEvent e) { label2.setText("mouse entered at point:" + e.getX() + " " + e.getY()); } public void mouseClicked(MouseEvent e) { label3.setText("mouse clicked at point:" + e.getX() + " " + e.getY() + "mouse clicked :" + e.getClickCount()); } }

(c) With a neat diagram explain the Model view controller design pattern

and list out the advantages and disadvantages of using it in designing an application.

  • The Model-View-Controller (MVC) design pattern is a popular architectural pattern used in Java and other programming languages. It separates an application into three interconnected components: the Model, the View, and the Controller.
  • Model : The Model represents the data and business logic of the application. It encapsulates the data and provides methods for accessing and manipulating it. The Model is responsible for notifying the View of any changes to the data.
  • View : The View represents the user interface of the application. It displays the data from the Model to the user and sends user input to the Controller. The View is passive, meaning it doesn't perform any data manipulation or business logic.
  • Controller : The Controller acts as an intermediary between the Model and the View. It receives input from the View, updates the Model, and updates the View with any changes to the data.

https://i.stack.imgur.com/NECv2.png

  • Advantages of using the MVC design pattern:
    • Separation of concerns: The MVC pattern separates the concerns of the application into three distinct components, making it easier to develop and maintain the codebase.
    • Reusability: Each component of the MVC pattern can be reused in different parts of the application or in different applications altogether.
    • Testability: The separation of concerns and clear interfaces between components make it easier to test each component independently.
    • Flexibility: The MVC pattern allows for a high degree of flexibility in terms of modifying or replacing individual components without affecting the rest of the application.
  • Disadvantages of using the MVC design pattern:
    • Complexity: The MVC pattern can add complexity to the application, especially for smaller projects.
    • Learning curve: Developers who are not familiar with the MVC pattern may need time to understand the pattern and how to implement it correctly.
    • Over-engineering: In some cases, using the MVC pattern can lead to over-engineering, where the complexity of the pattern outweighs the benefits for a particular project.
  • Example of MVC in java :

    • Model class : java public class StudentModel { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
    • View class : ```java import javax.swing.*; public class StudentView extends JFrame { private JTextField nameField; private JTextField ageField; private JButton saveButton;

      public StudentView() { setTitle("Student Information"); setSize(300, 200); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(3, 2));
        panel.add(new JLabel("Name: "));
        nameField = new JTextField(20);
        panel.add(nameField);
        panel.add(new JLabel("Age: "));
        ageField = new JTextField(3);
        panel.add(ageField);
        saveButton = new JButton("Save");
        panel.add(saveButton);
        add(panel);
      
        setVisible(true);
        
      }

      public String getName() { return nameField.getText(); }

      public void setName(String name) { nameField.setText(name); }

      public int getAge() { return Integer.parseInt(ageField.getText()); }

      public void setAge(int age) { ageField.setText(Integer.toString(age)); }

      public void addSaveListener(ActionListener listener) { saveButton.addActionListener(listener); } } ```

    • Controller class : ```java import java.awt.event.ActionEvent; import java.awt.event.ActionListener;

    public class StudentController { private StudentModel model; private StudentView view; public StudentController(StudentModel model, StudentView view) { this.model = model; this.view = view; view.addSaveListener(new SaveListener()); updateView(); } public void updateView() { view.setName(model.getName()); view.setAge(model.getAge()); } class SaveListener implements ActionListener { public void actionPerformed(ActionEvent e) { String name = view.getName(); int age = view.getAge(); model.setName(name); model.setAge(age); updateView(); } } } ```

    • Main class : java public class Main { public static void main(String[] args) { StudentModel model = new StudentModel(); StudentView view = new StudentView(); StudentController controller = new StudentController(model, view); } }