Object Oriented Programming (Model Questions Sol)
Object Oriented Programming (Model Questions Sol)
- Built-in data types: These are pre-defined data types provided by the programming
language. They are fundamental and directly supported by the language. Examples include
integers, floating-point numbers, characters, boolean values, etc.
- Derived data types: These are data types that are derived from built-in data types or
other derived data types. They are created using combination or transformation of existing
data types. Examples include arrays, structures, pointers, etc.
- User-defined data types: These are data types that are defined by the user or
programmer. They are created based on the requirements of a specific program or application.
Examples include classes, enumerations, unions, etc.
%d\n", area);
}
int main() {
int l = 5;
int w = 3;
calculateArea(l, w);
return 0;
}
```
In OOP, the focus is on objects that encapsulate data and behavior. Here's an example program
in Java using an object-oriented approach:
```java class
Rectangle {
private int length;
width;
}
public int calculateArea() {
return length * width;
}
}
public class Main { public static void
rectangle.calculateArea();
- Modularity: It promotes the organization of code into modular units, such as classes and
objects. This enhances code reusability, maintainability, and flexibility.
- Message passing: Objects communicate with each other by sending and receiving
messages. Methods are invoked on objects to perform operations and exchange data.
8. Objects and classes are closely related but have distinct characteristics:
- Class: A class is a blueprint or template that defines the structure and behavior of
objects. It represents a concept or category of objects and provides a set of attributes and
methods that the objects of that class will possess.
Object: An object is an instance of a class. It represents a specific occurrence or
realization of the concepts defined by the class. Objects have their own
unique state (attribute values) and behavior (method implementations).
In summary, a class is a general description or definition, while an object is a specific instance
created based on that definition.
9. An instance of a class refers to an individual object created from that class. It is a unique
occurrence of the class and has its own set of attribute values and behavior. Each instance
can be manipulated and accessed independently.
10. Classes accomplish data hiding (or encapsulation) by providing access modifiers to control
the visibility and accessibility of attributes and methods. By marking attributes as private,
they can only be accessed and modified within the class itself. Public methods can be used to
provide controlled access to private attributes, ensuring proper encapsulation and data
integrity.
11. Abstract Data Types (ADTs) are high-level descriptions of data structures that specify the
operations or functionalities performed on the data, without specifying the implementation
details. ADT specifications define the interface (methods or operations) and the behavior
(preconditions, postconditions, and invariants) of the data type.
For example, an ADT specification for a stack may define methods like `push()`, `pop()`, and
`isEmpty()`, but it does not specify how these operations are implemented internally.
13. The differences between primitive data types and abstract data types are as follows:
Primitive data types:
- Primitive data types are built-in data types provided by the programming language.
- They are low-level and directly supported by the language.
- They have a fixed set of values and predefined operations.
- Examples include integers, floating-point numbers, characters, boolean values, etc.
Abstract data types:
- Abstract data types are user-defined data types that encapsulate data and behavior within a
single unit.
- They are high-level and defined by the programmer.
- They have a well-defined set of operations or methods that define the behavior.
- Examples include stacks, queues, lists, trees, etc.
15. Function overloading refers to the ability to define multiple functions with the same name
but different parameter lists. The compiler or interpreter selects the appropriate function
to execute based on the number, type, and order of the arguments provided during the
function call.
Function overloading allows for more flexibility in function design and improves code
readability by providing descriptive function names for different variations of the same
functionality.
For example, in a programming language that supports function overloading, you could define
multiple functions named `calculateArea` with different parameter lists to handle different
shapes, such as `calculateArea(int radius)` for a circle, `calculateArea(int length, int
width)` for a rectangle, and so on.
16. Overriding refers to the ability to provide a different implementation for a method in a
subclass that is already defined in its superclass. When a method is overridden, the version
of the method defined in the subclass is executed instead of the version defined in the
superclass when the method is called on an instance of the subclass.
To override a method, the method in the subclass must have the same name, return type, and
parameter list as the method in the superclass. The `@Override` annotation (if supported by
the programming language) is often used to indicate that a method is intended to override a
superclass method, providing compile-time checks for correctness.
Method overriding is a key feature of inheritance in object-oriented programmingspecialization
and customization of behavior in derived classes while maintaining a common interface defined
by the superclass.
17. Polymorphism refers to the ability of objects of different classes to be treated as objects
of a common superclass. It allows a single interface (e.g., a method call) to be used to
represent different types of objects, providing flexibility and extensibility in program
design.
Polymorphism is typically achieved through method overriding and dynamic method binding.
When a method is called on a polymorphic reference, the appropriate implementation is
determined at runtime based on the actual type of the object.
Polymorphism allows for writing generic code that can operate on objects of different classes,
as long as they share a common superclass or implement a common interface. It enables code
reuse and promotes flexibility in handling different types of objects without the need for
explicit type checks.
18. Dynamic method binding (also known as dynamic dispatch or late binding) is a mechanism in
object-oriented programming where the appropriate implementation of a polymorphic
method is determined at runtime, based on the actual type of the object being referenced.
When a method is called on a polymorphic reference, the decision about which version of the
method to execute is made dynamically, based on the actual class of the object. This allows for
flexibility and extensibility in program design, as different subclasses can provide their own
implementations of the method.
Dynamic method binding is often contrasted with static method binding (or early binding), where
the decision about which method implementation to execute is made at compiletime based on
the declared type of the reference.
Dynamic method binding is a fundamental concept in polymorphism and plays a crucial role in
enabling the flexibility and adaptability of object-oriented programs.
19. In C++, a friend function is a function that is not a member of a class but has access to the
private and protected members of the class. It is declared and defined outside the class but
is granted access to the private and protected members by using the `friend` keyword.
Example:
```cpp
class MyClass {
private:
int privateData;
public:
<< endl;
}
int main() { MyClass
obj(42);
friendFunction(obj);
return 0;
}
```
20. Merits of using friend functions:
- They can access private and protected members of a class, allowing controlled access to
the internals of a class.
- They can provide a cleaner and more logical interface for accessing private members of
a class.
- They can enhance encapsulation by allowing selected functions or classes to have
privileged access.
21. Here's an example of a program using a friend function to add data objects of two different
classes:
```cpp
#include <iostream>
class ClassB; // Forward declaration
class ClassA {
private: int
value;
public:
ClassA(int val) : value(val) {}
friend int addValues(ClassA objA, ClassB objB);
};
class ClassB {
private:
int value;
public:
ClassB(int val) : value(val) {}
friend int addValues(ClassA objA, ClassB objB);
};
int addValues(ClassA objA, ClassB objB) {
}
int main() {
ClassA objA(5); ClassB objB(10);
return 0;
}
```
22. Yes, we can use the same function name for a member function of a class and an outside
function in the same program file. They are distinguished based on the scope in which they are
called.
Example:
```cpp
#include <iostream>
class MyClass { public: void display() {
}
};
void display() { std::cout << "Outside
}
int main() { MyClass obj; obj.display(); // Calls the
23. The compiler distinguishes between a set of overloaded functions having the same name
based on the number and types of arguments in the function calls. It looks for the best match
by comparing the argument types and performs implicit type conversions if necessary. If there
is no exact match or if there are multiple equally good matches, it results in a compilation error.
24. The mechanism of accessing data members and member functions depends on the
context. Here are the cases:
- Accessing data members: Use the dot operator (`.`) or arrow operator (`->`) with the
object of the class.
- Accessing member functions: Use the dot operator (`.`) or arrow operator (`->`) with
the object of the class followed by the function name and parentheses.
private: int
data;
public:
void setData(int value) {
data = value;
}
void displayData() { std::cout << "Data: "
<< data << std::endl;
}
};
int main() {
MyClass obj;
obj.setData(42);
obj.displayData();
return 0;
}
```
25. Here's a complete program to implement a bank account using the given class description:
```cpp
#include <iostream>
#include <string>
class BankAccount {
private:
std::string depositorName;
int accountNumber;
std::string accountType;
double balance;
public:
void assignInitialValues(const std::string& name, int accNumber, const std::string& type,
double initialBalance) { depositorName = name; accountNumber = accNumber;
accountType = type;
balance = initialBalance;
}
void depositAmount(double amount) {
balance += amount;
}
void withdrawAmount(double amount) {
if (amount <= balance) { balance -= amount;
} else {
std::cout << "Insufficient balance." << std::endl;
}
}
void displayDetails() { std::cout << "Name: " << depositorName <<
std::endl; std::cout << "Account Type: " << accountType << std::endl;
}
};
int main() {
BankAccount account; account.assignInitialValues("John Doe",
12345, "Savings", 1000.0); account.displayDetails();
account.depositAmount(500.0); account.displayDetails();
account.withdrawAmount(200.0);
account.displayDetails();
account.withdrawAmount(1500.0);
account.displayDetails();
return 0;
}
```
26. A constructor is a special member function of a class that is automatically called when an
object of that class is created. It is used to initialize the object's data members and
perform any necessary setup. It has the same name as the class and does not have a return
type.
Constructors are not mandatory to use in a class. If a class does not define any constructors,
the compiler provides a default constructor, which initializes the data members with default
values (e.g., 0, null).
27. Definitions:
a) Default constructor: A default constructor is a constructor that is automatically
generated by the compiler if no constructor is explicitly defined in a class. It initializes the
data members with default values. It has no parameters.
28. Yes, we can have more than one constructor in a class. This is known as constructor
overloading. Each constructor can have a
different set of parameters or a different number of parameters.
Example:
```cpp class
MyClass {
private:
int value;
public:
MyClass() : value(0) {}
int main() {
MyClass obj1; // Uses the default constructor
MyClass obj2(42); // Uses the parameterized constructor
return 0;
}
```
30. An argument to a copy constructor must always be passed as a reference to avoid infinite
recursion. If the argument is passed by value, it would lead to a call to the copy constructor
again, creating an infinite loop.
By passing the argument as a reference, it ensures that the copy constructor is called with the
actual object being passed by reference, avoiding unnecessary copies and recursion.
}
int getValue() const {
return value;
}
};
int main() {
MyClass obj1(42);
MyClass obj2 = obj1; // Copy constructor is called
return 0;
}
```
32. The `new` and `delete` operators are used for dynamic memory allocation and
deallocation in C++. The `new` operator is used to allocate memory for an object or array on the
heap, and the `delete` operator is used to deallocate the memory and destroy the object.
Example:
```cpp int* dynamicArray = new int[5]; // Allocate memory for an array of 5
```
33. Polymorphism refers to the ability of an object to take on many forms. In C++, there are
two types of polymorphism:
- Compile-time polymorphism (static polymorphism): This is achieved through function
overloading and operator overloading. The compiler determines which function or operator to
call based on the number and types of arguments.
Example:
```cpp void print(int num) { std::cout << "Printing
}
void print(double num) { std::cout << "Printing
}
int main() {
print(42); // Calls print(int)
return 0;
}
```
- Run-time polymorphism (dynamic polymorphism): This is achieved through virtual functions and
inheritance. The appropriate function is called based on the actual object type at runtime.
Example:
```cpp class
Shape {
public:
virtual void draw() { std::cout << "Drawing a
}
};
class Circle : public Shape { public:
void draw() override { std::cout <<
"Drawing a circle." << std::endl;
}
};
int main() {
Shape* shape = new Circle(); shape-
shape; return 0;
}
```
34. (a) Compile-time polymorphism is achieved through function overloading and operator
overloading. The determination of which function or operator to call is done by the compiler
during the compilation process based on the number and types of arguments. The function calls
are resolved at compile time.
(b) Run-time polymorphism is achieved through virtual functions and inheritance. The
determination of which function to call is done at runtime based on the actual object type. The
appropriate function is resolved dynamically during program execution.
35. Yes, a pointer of base class type can point to an object of the derived class. This is known as
upcasting. It allows treating a derived class object as an object of its base class. However, when
using a base class pointer to access members, only the members of the base class are accessible
unless the member functions are declared as virtual.
Example:
```cpp
class Base {
public:
}
};
class Derived : public Base { public:
void display() override { std::cout << "Derived
}
};
int main() {
Derived obj;
Base* basePtr = &obj; // Upcasting basePtr-
>display(); // Calls display() of Derived class
return 0;
}
```
36. In C++, a virtual function is a member function declared in a base class that is overridden by
a derived class. It allows the function call to be resolved dynamically at runtime based on the
actual object type. This enables polymorphic behavior.
A pure virtual function is a virtual function that is declared in a base class but has no
implementation in the base class. It is meant to be overridden by derived classes, and any class
containing a pure virtual function becomes an abstract class. Abstract classes cannot be
instantiated, but they can be used as base classes for other classes.
Example:
```cpp class
Animal {
public:
virtual void makeSound() = 0; // Pure virtual function
};
class Dog : public Animal { public:
}
};
int main() { Dog dog; dog.makeSound(); // Calls
return 0;
}
```
37. Function overriding refers to the ability of a derived class to provide a different
implementation of a virtual function that is already defined in the base class. It allows the
derived class to redefine the behavior of the function while preserving the same function
signature.
Example:
```cpp
class Base {
public:
}
};
class Derived : public Base { public:
void display() override { std::cout << "Derived
}
};
int main() { Derived obj; obj.display(); //
Calls display() of Derived class return 0;
}
```
39. Wrapper classes in Java are classes that encapsulate and provide a way to manipulate
primitive data types as objects. They provide a convenient way to convert between primitive
data types and objects.
There are eight wrapper classes in Java:
- `Boolean`: wraps a boolean value.
- `Byte`: wraps a byte value.
- `Short`: wraps a short value.
- `Integer`: wraps an int value.
- `Long`: wraps a long value. - `Float`: wraps a float value.
- `Double`: wraps a double value.
- `Character`: wraps a char value.
Wrapper classes provide various utility methods and constants for working with the
corresponding primitive types. They are often used in situations where objects are required,
such as collections, generics, and serialization.
40. Inheritance is a fundamental concept in object-oriented programming that allows creating
new classes (derived classes) from existing classes (base classes). The derived classes
inherit the properties and behaviors (data members and member functions) of the base
class, allowing code reuse and creating a hierarchical relationship between classes.
The derived classes can add new members or modify the inherited members. Inheritance
promotes code organization, extensibility, and reusability.
41. Here are explanations and sample programs for different types of inheritance:
(a) Single Inheritance:
Single inheritance involves a derived class inheriting from a single base class.
```java class Base {
void displayDerivedData() {
derivedObj.baseData = 42;
derivedObj.displayBaseData();
derivedObj.derivedData = 24;
derivedObj.displayDerivedData();
}
}
```
(b) Multilevel Inheritance:
Multilevel inheritance involves a derived class inheriting from another derived class.
```java class Base {
derived2Obj.baseData = 42;
derived2Obj.displayBaseData();
derived2Obj.derived1Data = 24;
derived2Obj.displayDerived1Data();
derived2Obj.derived2Data = 12;
derived2Obj.displayDerived2Data();
}
}
```
(c) Multiple Inheritance (not supported in Java):
Multiple inheritance involves a derived class inheriting from multiple base classes. Java does not
support multiple inheritance of classes, but it supports multiple inheritance of interfaces.
(d) Hierarchical Inheritance:
Hierarchical inheritance involves multiple derived classes inheriting from a single base class.
```java class Base {
derived1Obj.baseData = 42;
derived1Obj.displayBaseData();
derived1Obj.derived1Data = 24;
derived1Obj.displayDerived1Data();
derived2Obj.derived2Data = 5;
derived2Obj.displayDerived2Data();
}
}
```
(e) Hybrid Inheritance (combination of multiple types):
Hybrid inheritance involves a combination of different types of inheritance. It can include
multiple inheritance, multilevel inheritance, or hierarchical inheritance.
42. An abstract class in Java is a class that cannot be instantiated. It is declared using the
`abstract` keyword. Abstract classes can contain both abstract and non-abstract methods, and
they are used as base classes for other classes.
Abstract classes are meant to be extended by subclasses, which provide the implementation for
the abstract methods. If a class contains at least one abstract method, it must be declared as
abstract.
Example:
```java abstract class
Shape { protected
String color;
public Shape(String color) {
this.color = color;
}
public abstract double getArea();
public void displayColor() {
System.out.println("Color: " + color);
}
}
class Circle extends Shape {
}
public double getArea() {
}
}
public class Main { public static void
circle.displayColor();
43. In C++, a virtual base class is a class that is inherited virtually by multiple derived classes. It
is used to resolve the issues related to multiple inheritance, such as the diamond problem.
To make a class virtual, the `virtual` keyword is used during the inheritance declaration.
The need for virtual base classes arises when a class is inherited by multiple paths in an
inheritance hierarchy. Virtual base classes ensure that only one instance of the base class is
inherited by the derived classes.
Example:
```cpp
class Base {
public:
int baseData;
};
class Derived1 : virtual public Base { public:
int derived1Data;
};
class Derived2 : virtual public Base { public:
int derived2Data;
};
class Derived3 : public Derived1, public Derived2 { public:
int derived3Data;
};
int main() { Derived3 obj; obj.baseData = 42;
return 0;
}
```
In this example, `Derived3` inherits from `Derived1` and
`Derived2`, both of which virtually inherit from `Base`. The virtual base class ensures that
`Base` is inherited only once by `Derived3`.
44. Objects are stored in memory based on their data members. Each object occupies a certain
amount of memory that includes the memory required for its data members and any additional
overhead.
The exact memory layout depends on the programming language, compiler, and system
architecture. In general, the memory for an object is allocated either on the stack or the heap.
- Stack: In many programming languages, local objects and function parameters are
allocated on the stack. The memory for these objects is automatically managed by the compiler
or runtime system. When a function call is made, the objects are pushed onto the stack, and
they are automatically deallocated when the function returns.
- Heap: Objects allocated dynamically using the `new` operator in languages like C++ or
using dynamic memory allocation functions like `malloc` in C are stored on the heap. The
memory for these objects must be explicitly allocated and deallocated. The objects on the heap
can be accessed using pointers, and they exist until explicitly deallocated using the `delete`
operator or a similar mechanism.
The memory organization and management of objects are handled by the language runtime or
the operating system.
45. In Java, interfaces define a contract of methods that a class implementing the interface
must provide. An interface is a collection of abstract methods and constants.
To implement an interface, a class must use the `implements` keyword followed by the
interface name. The implementing class must provide the implementation for all the methods
declared in the interface.
Interfaces allow for multiple inheritance in Java, as a class can implement multiple interfaces.
Example:
```java
interface
Drawable {
void draw();
}
class Circle implements Drawable {
System.out.println("Drawing a circle.");
}
}
class Rectangle implements Drawable {
System.out.println("Drawing a rectangle.");
}
}
public class Main {
public static void main(String[] args) {
// Drawing a circle.
Rectangle rectangle = new Rectangle();
}
}
```
In this example, the `Drawable` interface declares a single method `draw()`. The `Circle` and
`Rectangle` classes implement the `Drawable` interface and provide their own implementation
of the `draw()` method.
Interfaces are useful for achieving abstraction and defining common behavior for unrelated
classes. They are widely used in Java's collection framework and various other APIs.
46. In C++, ambiguity in multiple inheritance is resolved using virtual inheritance. Virtual
inheritance is used when a class is inherited virtually from multiple base classes to ensure that
only a single instance of the common base class is inherited.
When a base class is inherited virtually, a shared subobject of the base class is created, which
is shared among the derived classes. This resolves the ambiguity caused by multiple paths to the
same base class.
Example:
```cpp
class Base {
public:
int baseData;
};
class Derived1 : virtual public Base { public:
int derived1Data;
};
class Derived2 : virtual public Base {
public:
int derived2Data;
};
class Derived3 : public Derived1, public Derived2 { public:
int derived3Data;
};
int main() { Derived3 obj; obj.baseData = 42; //
return 0;
}
```
In this example, `Derived3` inherits from `Derived1` and `Derived2`, both of which virtually
inherit from `Base
`. The virtual inheritance ensures that only one instance of the base class `Base` is inherited
by `Derived3`, resolving any ambiguity.
47. Multiple inheritance is not supported in Java for classes. Java's designers decided to
omit multiple inheritance of classes to avoid complexity and potential issues like the diamond
problem. The diamond problem occurs when a class inherits from two classes that have a
common base class.
However, Java supports multiple inheritance of interfaces. A class can implement multiple
interfaces, allowing it to inherit multiple sets of method signatures.
48. In Java, multiple inheritance can be achieved using interfaces. By implementing multiple
interfaces, a class can inherit and provide implementations for methods defined in those
interfaces.
Example:
```java interface
Interface1 { void
method1();
}
interface Interface2 {
void method2();
}
class MyClass implements Interface1, Interface2 {
System.out.println("Implementation of method1");
}
public void method2() {
System.out.println("Implementation of method2");
}
}
public class Main { public static void main(String[]
}
}
```
In this example, `MyClass` implements both `Interface1` and `Interface2`. It provides the
implementation for the `method1` and `method2` defined in the interfaces.
49. The iterator pattern in Java provides a way to access the elements of a collection in a
sequential manner without exposing the underlying structure of the collection.
The iterator pattern involves two main components:
- Iterator: An iterator is an object that provides methods to traverse a collection and
access its elements one by one.
- Collection: The collection is an object that holds a group of elements and provides a way
to create an iterator for the collection.
The iterator pattern allows clients to access elements of a collection without knowing its
internal implementation. It provides a uniform way to iterate over different types of
collections.
Example:
```java import
java.util.ArrayList;
import
java.util.Iterator;
import java.util.List;
names.add("Alice"); names.add("Bob");
names.add("Charlie");
while (iterator.hasNext()) {
50. Java Generics is a feature introduced in Java 5 that allows the creation of generic types
and methods. It enables the use of type parameters to create classes, interfaces, and methods
that can work with different data types.
Generics provide compile-time type safety by allowing the specification of the type or types
that a generic class or method can operate on. This ensures type compatibility and eliminates
the need for explicit type casting.
- Code Reusability: Generic classes and methods can be used with different data types,
promoting code reuse.
- Performance: Generics avoid the need for type casting, improving performance by
eliminating unnecessary type checks and conversions.
Example:
```java class
Box<T> {
private T value;
this.value = value;
public T getValue() {
return value;
this.value = value;
new Box<>("Hello");
```
In this example, the `Box` class is defined with a type parameter `T`. This allows creating
`Box` objects that can hold values of different types. The type parameter is specified when
creating instances of the `Box` class (`Box<Integer>`, `Box<String>`), ensuring type safety at
compile time.
51. The collection framework in Java provides a set of interfaces and classes to store,
manipulate, and process groups of objects. It includes interfaces like `List`, `Set`, `Queue`,
and `Map`, along with their implementation classes such as `ArrayList`, `HashSet`,
`LinkedList`, `HashMap`, and more.
The collection framework offers a wide range of data structures and algorithms for working
with collections of objects. It provides features like dynamic resizing, searching, sorting,
filtering, and iteration over collections.
Some key interfaces in the Java collection framework are:
- `Collection`: The root interface that represents a group of objects. It provides basic
operations for working with collections, such as adding, removing, and iterating over elements.
- `List`: An ordered collection that allows duplicate elements. It provides operations to
access elements by their index.
- `Set`: A collection that does not allow duplicate elements. It provides operations for
adding, removing, and querying elements.
- `Queue`: A collection that represents a queue data structure. It follows the FIFO
(First-In-FirstOut) principle.
- `Map`: A collection that stores key-value pairs. It allows efficient retrieval of values
based on their keys.
The collection framework provides a rich set of classes and interfaces that cater to different
use cases, making it easier to work with collections of objects in Java.
52. Java AWT (Abstract Window Toolkit) and Java Swing are two different GUI (Graphical
User Interface) libraries in Java.
Java AWT:
- Java AWT is the original GUI library introduced with the first versions of Java.
- It provides a set of classes and methods to create GUI components like windows, buttons,
labels, text fields, etc.
- AWT components are heavyweight and rely on the underlying operating system's windowing
system.
- AWT components have a native peer component associated with them, which handles the
rendering and interaction.
- AWT is relatively simpler and has a less modern look and feel compared to Swing.
- AWT components are platform-dependent and may not have consistent behavior across
different operating systems.
Java Swing:
- Java Swing is a more advanced and modern GUI library introduced in later versions of Java.
- It provides a rich set of GUI components that are lightweight and independent of the
underlying operating system.
- Swing components are implemented entirely in Java and do not rely on the native windowing
system.
- Swing components have a consistent look and feel across different operating systems.
- Swing provides additional components and features compared to AWT, such as tables, trees,
tabbed panes, sliders, etc.
- Swing components can be customized extensively using pluggable look and feel (PLAF) and can
have a more modern and attractive appearance.
Java Swing is generally preferred over AWT for developing modern, cross-platform GUI
applications due to its flexibility, rich feature set, and consistent behavior across different
operating systems.
53. Here is an example of a generic function in Java:
```java public class Main { public static <T>
element : array) {
System
.out.println(element);
}
}
public static void main(String[] args) {
Integer[] numbers = {1, 2, 3, 4, 5};
String[] names = {"Alice", "Bob", "Charlie"};
printArray(numbers);
printArray(names);
}
}
```
In this example, the `printArray` method is a generic function that can accept an array of any
type. The type parameter `T` is used to specify the type of elements in the array. The function
then iterates over the array and prints each element.
The `printArray` method is invoked with both an `Integer` array (`numbers`) and a `String`
array (`names`). The type inference mechanism in Java determines the appropriate type for
`T` based on the argument passed to the function. This allows the same generic function to
work with different types of arrays.
54. Here is an example of traversing a collection of integers, filtering even elements greater
than a specific number using the `stream()` method in Java:
```java import
java.util.Arrays;
import java.util.List;
main(String[] args) {
10
```
55. Java Swing provides a wide range of components and containers to create graphical user
interfaces. Some of the commonly used Swing components are:
- `JFrame`: A top-level container representing a window. It provides the basic frame for
building GUI applications.
- `JPanel`: A container that can hold other Swing components. It is often used to organize and
group components.
- `JTextField`: A text input component that allows users to enter and edit text.
- `JCheckBox`: A check box component that allows users to select one or more options.
- `JRadioButton`: A radio button component that allows users to select a single option from a
group.
- `JComboBox`: A drop-down list component that allows users to select one item from a list of
options.
- `JList`: A component that displays a list of items. Users can select one or multiple items from
the list.
These are just a few examples of Swing components. Swing provides many more components and
containers that can be combined to create complex GUIs.
56. Here is an example of a Java Swing program that changes the background color of a frame
using an action event:
```java import
javax.swing.*; import
java.awt.*; import
java.awt.event.Action
Event; import
java.awt.event.Action
Listener;
public class Main { public static void
main(String[] args) {
frame.set
DefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);
JPanel panel = new JPanel();
JButton button = new JButton("Change Color");
panel.add(button);
button.addActionListener(new ActionListener() {