RAJARAJESWARI COLLEGE OF ENGINEERING
Kumbalgodu, Bangalore-74
DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING
Scheme & Solution
INTERNALS ASSESSMENT-II
Subject : Object Oriented Programming using Java
Subject Code : BCS306A
Semester& Section : 3rd Sem
1.a. How do you pass arguments to superclass constructor through the subclass constructor? Explain with a code snippet. (10)
To pass arguments to a superclass constructor through a subclass constructor, you use the super() function in the subclass constructor. This
calls the constructor of the superclass with the provided arguments, allowing you to initialize both the superclass and subclass with the
necessary values.
Example program:
python
Copy code
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
# Call the superclass (Animal) constructor and pass the 'name' argument
super().__init__(name)
self.breed = breed
# Usage
dog = Dog("Buddy", "Golden Retriever")
print(dog.name) # Output: Buddy
print(dog.breed) # Output: Golden Retriever
Explanation
1. The Animal class has an __init__ method that initializes the name attribute.
2. The Dog class, a subclass of Animal, has its own __init__ method with parameters for name and breed.
3. Inside the Dog constructor, super().__init__(name) calls the __init__ method of Animal, passing the name argument to initialize
the name attribute in Animal.
4. Then, self.breed = breed initializes the breed attribute specific to Dog.
This way, the subclass constructor can pass parameters to the superclass constructor while also initializing any subclass-specific attributes.
1.b. Explain the following keywords. i)this ii) super iii) final iv) static (10)
1. this
Purpose: Refers to the current instance of a class.
Usage: Used within an instance method or constructor to access fields, methods, or constructors of the current object.
Example:
java
Copy code
public class Person {
private String name;
public Person(String name) {
this.name = name; // 'this.name' refers to the instance variable, 'name' refers to the parameter
Note: Helps in disambiguating class fields and parameters with the same name.
2. super
Purpose: Refers to the superclass (parent class) of the current object.
Usage: Used to call superclass methods, constructors, or to access superclass fields from a subclass.
Example:
public class Animal {
public Animal() {
System.out.println("Animal created");
public class Dog extends Animal {
public Dog() {
super(); // Calls the constructor of superclass, Animal
System.out.println("Dog created");
Note: The super() call must be the first statement in a subclass constructor if you want to call the superclass constructor explicitly.
3. final
Purpose: Used to declare constants, prevent method overriding, or prevent inheritance.
Usage:
o Final Variable: Once assigned, cannot be modified.
o Final Method: Cannot be overridden by subclasses.
o Final Class: Cannot be subclassed.
Example:
java
Copy code
public final class MathConstants {
public static final double PI = 3.14159; // Constant value, can't be changed
public class Shape {
public final void draw() {
System.out.println("Drawing shape");
Note: A final variable must be initialized only once, either at the time of declaration or in the constructor.
4. static
Purpose: Indicates that a variable, method, or nested class belongs to the class itself rather than to instances of the class.
Usage:
o Static Variables: Shared across all instances of a class.
o Static Methods: Can be called without creating an instance of the class.
o Static Nested Classes: A nested class that does not require an instance of the outer class.
o
Example:
java
Copy code
public class Counter {
public static int count = 0;
public Counter() {
count++; // 'count' is shared among all instances
public static void displayCount() {
System.out.println("Total count: " + count); // Static method can access static variables
Note: Static methods cannot access instance (non-static) variables or methods directly.
2.a. What do you mean by method overriding? Discuss with a programming example (10)
Method Overriding is a feature in object-oriented programming where a subclass provides a specific implementation of a method that is
already defined in its superclass. This allows the subclass to define a behavior that’s specific to its type, even though the method is called
through a superclass reference.
Key Points of Method Overriding
1. The method in the subclass must have the same name, return type, and parameters as the method in the superclass.
2. It is used to achieve runtime polymorphism.
3. The @Override annotation is often used before an overridden method to make it clear and help catch errors if the method signatures
don’t match.
Example of Method Overriding
Here’s an example to illustrate method overriding in Java:
java
Copy code
// Superclass
class Animal {
// Method to be overridden in the subclass
public void sound() {
System.out.println("Animal makes a sound");
// Subclass
class Dog extends Animal {
// Overriding the sound method
@Override
public void sound() {
System.out.println("Dog barks");
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // Animal reference and object
Animal myDog = new Dog(); // Animal reference but Dog object
myAnimal.sound(); // Calls Animal's sound() method: Output -> "Animal makes a sound"
myDog.sound(); // Calls Dog's overridden sound() method: Output -> "Dog barks"
Explanation
1. Superclass (Animal): The Animal class has a sound() method that simply prints "Animal makes a sound".
2. Subclass (Dog): The Dog class extends Animal and overrides the sound() method to print "Dog barks".
3. Runtime Behavior: When we create an Animal reference pointing to a Dog object (Animal myDog = new Dog();), the overridden
sound() method in Dog is called, not the one in Animal.
Advantages of Method Overriding
Dynamic Method Dispatch: Allows the program to decide at runtime which method to execute, enabling polymorphism.
Custom Behavior in Subclass: Provides specific implementation for subclass types while using the same method signature,
enhancing flexibility and reusability.
2.b. Explain Dynamic Method Dispatch with suitable programming example. (10)
Dynamic Method Dispatch (also known as runtime polymorphism) is a process in which a call to an overridden method is resolved at runtime
rather than at compile time. It occurs when a superclass reference variable holds a subclass object, and the method that gets called is determined
based on the actual object type, not the reference type.
Dynamic method dispatch enables Java to implement runtime polymorphism, allowing methods in subclass objects to be accessed through
superclass references.
How Dynamic Method Dispatch Works
When a method is called on a superclass reference holding a subclass object, Java looks at the actual object type to determine which method
to invoke. This enables the program to select the appropriate method implementation at runtime.
Example of Dynamic Method Dispatch
Consider the following example to understand how dynamic method dispatch works:
java
Copy code
// Superclass
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
// Subclass Dog
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
// Subclass Cat
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Cat meows");
// Main class to demonstrate dynamic method dispatch
public class Main {
public static void main(String[] args) {
// Create superclass reference holding subclass objects
Animal myAnimal; // Superclass reference
// Pointing to Dog object
myAnimal = new Dog();
myAnimal.sound(); // Output: Dog barks
// Pointing to Cat object
myAnimal = new Cat();
myAnimal.sound(); // Output: Cat meows
Explanation
1. Superclass (Animal): The Animal class has a sound() method that will be overridden in each subclass.
2. Subclass (Dog): The Dog class overrides the sound() method to print "Dog barks".
3. Subclass (Cat): The Cat class overrides the sound() method to print "Cat meows".
4. Dynamic Method Dispatch in Action:
o We declare an Animal reference, myAnimal.
o Assigning myAnimal to a Dog object calls the Dog’s version of sound(), outputting "Dog barks".
o Reassigning myAnimal to a Cat object then calls the Cat’s version of sound(), outputting "Cat meows".
Advantages of Dynamic Method Dispatch
Runtime Polymorphism: Enables polymorphic behavior, where the actual method that gets executed is based on the runtime
object type, not the reference type.
Flexibility and Extensibility: Allows programs to decide at runtime which specific implementation to invoke, making the program
more flexible and extensible.
Dynamic method dispatch is fundamental to achieving polymorphism, one of the key principles of object-oriented programming, enabling
more flexible and reusable code.
3.a. Create an abstract class called Employee. Include the members: Name, EmpID and an abstract method cal_sal(). Create two
inherited classes SoftwareEng (with the members basic and DA) and HardwareEng (with members basic and TA). Implement runtime
polymorphism (dynamic method dispatch) to display salary of different employees by creating array of references to superclass. (10)
// Abstract superclass Employee
abstract class Employee {
String name;
int empID;
// Constructor to initialize name and empID
public Employee(String name, int empID) {
this.name = name;
this.empID = empID;
}
// Abstract method to calculate salary
public abstract double cal_sal();
// SoftwareEng subclass with basic and DA
class SoftwareEng extends Employee {
double basic;
double DA; // Dearness Allowance
// Constructor to initialize name, empID, basic, and DA
public SoftwareEng(String name, int empID, double basic, double DA) {
super(name, empID);
this.basic = basic;
this.DA = DA;
// Overridden method to calculate salary
@Override
public double cal_sal() {
return basic + DA;
// HardwareEng subclass with basic and TA
class HardwareEng extends Employee {
double basic;
double TA; // Travel Allowance
// Constructor to initialize name, empID, basic, and TA
public HardwareEng(String name, int empID, double basic, double TA) {
super(name, empID);
this.basic = basic;
this.TA = TA;
// Overridden method to calculate salary
@Override
public double cal_sal() {
return basic + TA;
}
// Main class to demonstrate dynamic method dispatch
public class Main {
public static void main(String[] args) {
// Creating an array of Employee references
Employee[] employees = new Employee[3];
// Initializing the array with SoftwareEng and HardwareEng objects
employees[0] = new SoftwareEng("Alice", 101, 50000, 15000); // SoftwareEng
employees[1] = new HardwareEng("Bob", 102, 40000, 10000); // HardwareEng
employees[2] = new SoftwareEng("Charlie", 103, 55000, 20000); // SoftwareEng
// Displaying the salary of each employee using runtime polymorphism
for (Employee emp : employees) {
System.out.println("Employee Name: " + emp.name);
System.out.println("Employee ID: " + emp.empID);
System.out.println("Salary: " + emp.cal_sal());
System.out.println("----------------------");
Output:
Employee Name: Alice
Employee ID: 101
Salary: 65000.0
----------------------
Employee Name: Bob
Employee ID: 102
Salary: 50000.0
----------------------
Employee Name: Charlie
Employee ID: 103
Salary: 75000.0
3.b. Design Interface called polygon with a method called area (). Implement this Interface to create different classes like Square,
Rectangle and print the area of Square and Rectangle. (10)
// Interface Polygon
interface Polygon {
// Abstract method to calculate area
double area();
// Class Square implementing Polygon interface
class Square implements Polygon {
double side;
// Constructor to initialize side
public Square(double side) {
this.side = side;
// Implementation of area() method
@Override
public double area() {
return side * side;
// Class Rectangle implementing Polygon interface
class Rectangle implements Polygon {
double length;
double width;
// Constructor to initialize length and width
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
// Implementation of area() method
@Override
public double area() {
return length * width;
}
// Main class to test the implementation
public class Main {
public static void main(String[] args) {
// Create instances of Square and Rectangle
Polygon square = new Square(5); // 5 is the side length of the square
Polygon rectangle = new Rectangle(4, 6); // 4 and 6 are the length and width of the rectangle
// Display the areas
System.out.println("Area of Square: " + square.area());
System.out.println("Area of Rectangle: " + rectangle.area());
4.a. What do you mean by a package? How to find Packages and CLASSPATH? How do you import in a Java program? Explain with
a program. (10)
In Java, a package is a way of grouping related classes and interfaces together, much like folders on a computer, making the code modular
and easier to maintain. Packages help avoid naming conflicts by providing namespaces and allow for more organized project structures.
Finding Packages and CLASSPATH
1. Finding Packages:
o Java provides several built-in packages like java.util, java.io, and java.lang.
o To list available packages, you can browse the jre/lib and lib folders in your Java installation, which contain core
libraries.
2. CLASSPATH:
o CLASSPATH is an environment variable that tells the Java compiler and Java runtime where to find the classes and
packages.
o To view or set CLASSPATH:
View: Run echo %CLASSPATH% on Windows or echo $CLASSPATH on macOS/Linux in the command
line.
Set CLASSPATH:
On Windows: set CLASSPATH=path_to_classes_or_jars
On macOS/Linux: export CLASSPATH=path_to_classes_or_jars
3. Importing Packages in Java:
o To use a class from another package, you use the import keyword.
o You can either import a single class (import packageName.ClassName;) or an entire package (import packageName.*;).
Example Program Using a Package
Let's create a simple program that defines a custom package myPackage with a Calculator class and then uses it in the main program.
Step 1: Define the Calculator Class in myPackage
Save this code in a file named Calculator.java inside a folder called myPackage:
java
Copy code
// Calculator.java in myPackage
package myPackage;
public class Calculator {
public int add(int a, int b) {
return a + b;
public int subtract(int a, int b) {
return a - b;
Step 2: Compile the Calculator Class
Navigate to the folder containing myPackage and compile the class:
bash
Copy code
javac myPackage/Calculator.java
This will create a myPackage/Calculator.class file.
Step 3: Using the Calculator Class in Another Program
Now, let’s create a program that imports and uses the Calculator class from myPackage.
Save this code as Main.java:
java
Copy code
// Main.java in the default package
import myPackage.Calculator; // Importing the Calculator class
public class Main {
public static void main(String[] args) {
// Create an instance of Calculator
Calculator calc = new Calculator();
// Use Calculator methods
int sum = calc.add(10, 5);
int difference = calc.subtract(10, 5);
// Print results
System.out.println("Sum: " + sum); // Output: Sum: 15
System.out.println("Difference: " + difference); // Output: Difference: 5
}
Step 4: Compile and Run Main.java
Ensure CLASSPATH is set to the parent directory of myPackage or include it directly while running:
1. Compile:
bash
Copy code
javac Main.java
2. Run:
bash
Copy code
java Main
Explanation
1. Package Declaration (package myPackage;): Declares Calculator as part of myPackage.
2. Import Statement (import myPackage.Calculator;): Allows Main.java to access Calculator without needing the full path.
3. Using Calculator Methods: The Main class creates an instance of Calculator and calls its add and subtract methods.
This example demonstrates how to create a package, import it into another class, and use its functionality in Java.
4.b. Define an interface. Explain how to define and implement an interface with an example. (10)
An interface in Java is a reference type that can contain only constants, method signatures, default methods, static methods, and nested types.
Interfaces are abstract by nature, meaning they provide a contract for classes to implement but do not provide any concrete behavior
themselves.
Key Characteristics of an Interface
1. Defines Methods Without Implementations: Methods in an interface are abstract by default (no body).
2. Implements Multiple Inheritance: A class can implement multiple interfaces, allowing Java to achieve multiple inheritance.
3. Access Modifiers: All methods in an interface are implicitly public and abstract, and fields are implicitly public, static, and final.
4. Default and Static Methods: Java 8 and later allow default and static methods in interfaces, which can have a body.
Defining an Interface
To define an interface, use the interface keyword. Here’s the syntax:
java
Copy code
interface InterfaceName {
// Constant declarations
int MY_CONSTANT = 10; // implicitly public, static, and final
// Abstract method (no implementation)
void myMethod();
// Default method with an implementation (Java 8+)
default void defaultMethod() {
System.out.println("Default method in interface");
}
// Static method with an implementation (Java 8+)
static void staticMethod() {
System.out.println("Static method in interface");
Implementing an Interface
A class implements an interface using the implements keyword and must provide implementations for all of its abstract methods. If a class
fails to implement all methods, it must be declared abstract.
Example: Defining and Implementing an Interface
In this example, we’ll define an interface called Shape with an abstract method area() and then implement it in Circle and Rectangle classes.
Step 1: Define the Shape Interface
java
Copy code
// Define interface Shape
interface Shape {
// Abstract method to calculate area
double area();
Step 2: Implement Shape in Circle Class
java
Copy code
// Circle class implementing Shape interface
class Circle implements Shape {
private double radius;
// Constructor
public Circle(double radius) {
this.radius = radius;
// Implementation of area() method
@Override
public double area() {
return Math.PI * radius * radius;
Step 3: Implement Shape in Rectangle Class
java
Copy code
// Rectangle class implementing Shape interface
class Rectangle implements Shape {
private double length;
private double width;
// Constructor
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
// Implementation of area() method
@Override
public double area() {
return length * width;
Step 4: Use Interface References to Access Implementations
Here’s the Main class demonstrating the use of the Shape interface:
java
Copy code
// Main class to test interface implementation
public class Main {
public static void main(String[] args) {
// Creating instances of Circle and Rectangle
Shape circle = new Circle(5); // Shape reference for Circle
Shape rectangle = new Rectangle(4, 6); // Shape reference for Rectangle
// Displaying areas using interface references
System.out.println("Area of Circle: " + circle.area()); // Output: Area of Circle: 78.5398...
System.out.println("Area of Rectangle: " + rectangle.area()); // Output: Area of Rectangle: 24.0
Explanation
1. Interface (Shape): Declares an abstract method area() that classes implementing this interface must define.
2. Implementing Classes (Circle and Rectangle):
o Each class provides its own implementation of area().
o Circle calculates area as π * radius^2, while Rectangle calculates it as length * width.
3. Interface References:
o In the Main class, Shape interface references (circle and rectangle) hold instances of Circle and Rectangle, respectively.
o Calls to area() are resolved at runtime, demonstrating polymorphism.
Benefits of Using Interfaces
Decoupling: Interfaces allow a class to become more flexible and reusable.
Multiple Inheritance: Enables a class to inherit behavior from multiple sources.
Polymorphism: Interface references enable polymorphic behavior by allowing different class implementations to be treated
uniformly.
5.a. Explain the access protection for packages in Java with programming examples (10)
In Java, access protection within packages is governed by access modifiers: public, protected, default (no modifier), and private. These access
levels determine the visibility of classes, methods, and fields across different packages and classes.
Here’s a breakdown of how each modifier affects access:
1. public: Accessible from any class, in any package.
2. protected: Accessible within the same package and by subclasses in other packages.
3. default (package-private): Accessible only within the same package. If no access modifier is specified, it’s considered default.
4. private: Accessible only within the same class.
Example to Illustrate Access Levels
Let’s look at a scenario with two packages to see how access protection works in Java.
Step 1: Create Package packageA with a Parent Class
In the Parent class, we’ll define fields and methods with different access modifiers.
Save this code as packageA/Parent.java:
java
Copy code
// packageA/Parent.java
package packageA;
public class Parent {
public String publicField = "Public Field";
protected String protectedField = "Protected Field";
String defaultField = "Default Field"; // No modifier (default)
private String privateField = "Private Field";
public void publicMethod() {
System.out.println("Public Method");
protected void protectedMethod() {
System.out.println("Protected Method");
}
void defaultMethod() {
System.out.println("Default Method");
private void privateMethod() {
System.out.println("Private Method");
// Method to demonstrate access within the same class
public void showAllAccess() {
System.out.println(publicField);
System.out.println(protectedField);
System.out.println(defaultField);
System.out.println(privateField);
publicMethod();
protectedMethod();
defaultMethod();
privateMethod();
Step 2: Create Package packageB with a Child Class
In this package, we’ll create a Child class that extends Parent to demonstrate which members are accessible through inheritance.
Save this code as packageB/Child.java:
java
Copy code
// packageB/Child.java
package packageB;
import packageA.Parent;
public class Child extends Parent {
public void display() {
// Accessing fields from Parent class
System.out.println(publicField); // Accessible
System.out.println(protectedField); // Accessible because of inheritance
// System.out.println(defaultField); // Not accessible (package-private)
// System.out.println(privateField); // Not accessible (private)
// Accessing methods from Parent class
publicMethod(); // Accessible
protectedMethod(); // Accessible because of inheritance
// defaultMethod(); // Not accessible (package-private)
// privateMethod(); // Not accessible (private)
Step 3: Create a Test Class in packageB to Test Access Protection
Save this code as packageB/Test.java:
java
Copy code
// packageB/Test.java
package packageB;
import packageA.Parent;
public class Test {
public static void main(String[] args) {
Parent parent = new Parent();
Child child = new Child();
// Accessing Parent class members through Parent reference
System.out.println("Accessing Parent class fields:");
System.out.println(parent.publicField); // Accessible
// System.out.println(parent.protectedField); // Not accessible outside package without inheritance
// System.out.println(parent.defaultField); // Not accessible outside package
// System.out.println(parent.privateField); // Not accessible (private)
System.out.println("\nAccessing Parent class methods:");
parent.publicMethod(); // Accessible
// parent.protectedMethod(); // Not accessible outside package without inheritance
// parent.defaultMethod(); // Not accessible outside package
// parent.privateMethod(); // Not accessible (private)
System.out.println("\nAccessing inherited fields and methods in Child class:");
child.display(); // Calls Child's display() method to demonstrate inheritance access
Explanation of Access Levels in This Example
1. public Access:
o publicField and publicMethod() in Parent are accessible everywhere, including Child and Test classes in packageB.
2. protected Access:
o protectedField and protectedMethod() are accessible in Child class because Child inherits from Parent. However, they
are not accessible in Test class, which does not inherit from Parent.
3. default (package-private) Access:
o defaultField and defaultMethod() are accessible only within the packageA package. They are not accessible in Child
(since it’s in packageB) or in the Test class.
4. private Access:
o privateField and privateMethod() are only accessible within the Parent class itself and are not accessible in either Child
or Test classes.
Output
plaintext
Copy code
Accessing Parent class fields:
Public Field
Accessing Parent class methods:
Public Method
Accessing inherited fields and methods in Child class:
Public Field
Protected Field
Public Method
Protected Method
Summary of Access Control
Access Modifier Same Class Same Package (Non-Subclass) Subclass (Same Package) Subclass (Different Package) Other Packages
public ✔ ✔ ✔ ✔ ✔
protected ✔ ✔ ✔ ✔ (via inheritance) ✘
default ✔ ✔ ✔ ✘ ✘
private ✔ ✘ ✘ ✘ ✘
This example illustrates how access modifiers control the visibility of fields and methods in Java across classes and packages, ensuring
encapsulation and controlled access within projects.
5.b. Discuss the following with Java code snippet. i) Returning Objects ii) Recursion (10)
i) Returning Objects
In Java, methods can return objects. This can be useful for methods that need to return instances of classes. When a method returns an object,
it can return a new instance, an existing object, or an object passed into the method.
Example: Returning an Object
In this example, we’ll create a Book class with a method that returns a Book object.
java
Copy code
class Book {
private String title;
private String author;
// Constructor to initialize title and author
public Book(String title, String author) {
this.title = title;
this.author = author;
// Method that returns an instance of Book
public static Book createBook(String title, String author) {
return new Book(title, author);
public void displayInfo() {
System.out.println("Title: " + title + ", Author: " + author);
public class Main {
public static void main(String[] args) {
// Calling the static method to create a new Book object
Book myBook = Book.createBook("1984", "George Orwell");
// Display the book information
myBook.displayInfo();
Explanation
1. Book Class: Defines a constructor and a static method createBook() that returns a new Book object.
2. Returning an Object: The createBook method returns a new Book instance.
3. Using Returned Object: In the Main class, we call createBook to get a Book object and then call displayInfo to print the details.
ii) Recursion
Recursion is a technique in which a method calls itself to solve a problem. A recursive method typically has a base case (to stop recursion)
and a recursive case (where the method calls itself).
Example: Calculating Factorial Using Recursion
In this example, we’ll define a recursive method to calculate the factorial of a number.
java
Copy code
class FactorialCalculator {
// Recursive method to calculate factorial
public static int factorial(int n) {
if (n <= 1) { // Base case
return 1;
} else { // Recursive case
return n * factorial(n - 1);
public class Main {
public static void main(String[] args) {
int number = 5;
int result = FactorialCalculator.factorial(number);
System.out.println("Factorial of " + number + " is: " + result);
Explanation
1. Recursive Method (factorial):
o The base case checks if n is less than or equal to 1. If true, it returns 1, stopping further recursion.
o The recursive case calculates n * factorial(n - 1), which calls factorial again with a smaller argument.
2. Using Recursion:
o For factorial(5), it will evaluate as 5 * 4 * 3 * 2 * 1, returning 120.
Output of the Program
plaintext
Copy code
Title: 1984, Author: George Orwell
Factorial of 5 is: 120
These examples illustrate returning objects and using recursion in Java. Returning objects is a powerful feature for encapsulation and reuse,
while recursion is useful for problems that can be broken down into smaller, self-similar subproblems.