P in JAVA M3
P in JAVA M3
Programming in Java
Course Code 21CS652 CIE Marks 50
Teaching Hours/Week (L: T: P: S) (3:0:0:0) SEE Marks 50
Total Hours of Pedagogy 40 hours Theory Total Marks 100
Credits 03 Exam Hours 03
Course Learning Objectives
CLO 1. Learn fundamental features of object-oriented language and JAVA.
CLO 2. To create, debug and run simple Java programs.
CLO 3. Learn object-oriented concepts using programming examples.
CLO 4. Study the concepts of importing packages and exception handling mechanism.
CLO 5. Discuss the String Handling examples with Object Oriented concepts.
Teaching-Learning Process (General Instructions)
These are sample Strategies, which teachers can use to accelerate the attainment of the various course outcomes.
1. Lecturer method (L) need not to be only a traditional lecture method, but alternative effective teaching methods could be
adopted to attain the outcomes.
2. Use of Video/Animation to explain functioning of various concepts.
3. Encourage collaborative (Group Learning) Learning in the class.
4. Ask at least three HOT (Higher order Thinking) questions in the class, which promotes critical thinking.
5. Adopt Problem Based Learning (PBL), which fosters students’ Analytical skills, develop design thinking skills such as the ability
to design, evaluate, generalize, and analyze information rather than simply recall it.
6. Introduce Topics in manifold representations.
7. Show the different ways to solve the same problem with different circuits/logic and encourage the students to come up with their
own creative ways to solve them.
8. Discuss how every concept can be applied to the real world - and when that's possible, it helps improve the students'
understanding.
Module-3:
Introducing Classes: Class Fundamentals, Declaring Objects, Assigning Object Reference Variables, Introducing Methods,
Constructors, The this Keyword, Garbage Collection, The finalize( ) Method, A Stack Class.
A Closer Look at Methods and Classes: Overloading Methods, Using Objects as Parameters, A Closer Look at Argument Passing,
Returning Objects, Recursion, Introducing Access Control, understanding static, Introducing final, Arrays Revisited.
Inheritance: Inheritance, Using super, Creating a Multilevel Hierarchy, When Constructors Are Called, Method Overriding.
Textbook 1: Ch 6, Ch 7.1-7.9,Ch 8.1-8.5
Teaching-Learning Process Chalk and Talk, PowerPoint Presentation RBT Level: L1, L2, L3
Textbooks
1. Herbert Schildt, Java The Complete Reference, 7th Edition, Tata McGraw Hill, 2007. (Chapters 2, 3, 4, 5, 6,7, 8, 9,10, 12,15)
Reference Books:
1. Mahesh Bhave and Sunil Patekar, "Programming with Java", First Edition, Pearson
Education,2008, ISBN:9788131720806.
2. Rajkumar Buyya,SThamarasiselvi, xingchen chu, Object oriented Programming with java, Tata
McGraw Hill education private limited.
3. E Balagurusamy, Programming with Java A primer, Tata McGraw Hill companies.
}
}
Explanation:
1. Class Definition (`Person`):
- We define a class named `Person` using the `class` keyword. It has two data members (`name` and `age`) and one
method (`sayHello()`).
- Data members (`name` and `age`) are variables that store information about the objects of the class.
- The method `sayHello()` is a function that defines the behavior of the objects.
2. Creating Objects (`person1` and `person2`):
- We create objects of the class `Person` using the `new` keyword. Each object represents a specific person with its
own set of data members.
3. Accessing Data Members:
- We access and modify the data members (`name` and `age`) of the objects using the dot notation
(`objectName.dataMember`).
4. Calling Methods on Objects:
- We call the method `sayHello()` on the objects using the dot notation (`objectName.method()`). Each object calls the
method with its own data members.
The process of creating an instance of a class has to follow the following steps given below:
• Declaration
• Instantiation
• Initialization
Now let us understand them one by one.
Declaration
In order to create an object, we start by declaring a variable of that class type. This variable can be used to refer to that newly
created object. Following is the syntax for declaration, along with an example:
Syntax: className varName;
Example: Box myBox;
The defined variable in the state currently references no object and is just understood as the variable name, myBox of data-
type Box.
Instantiation
After variable declaration, we need to acquire an actual, physical copy of that object (memory reference) and assign it to
the variable. The new keyword instantiates a class by allocating memory for a new object and returning a reference to that
memory. This dynamic memory allocation happens at the run-time.
The new operator returns a reference to the object it created. This reference is usually assigned to a variable of the
appropriate type, like:
Syntax: className varName = new className();
Example: Box mybox = new Box();
Now let us concentrate on the class Box prototype before jumping on
dynamic allocation of memory.
class Box{
double width;
double height;
double depth;
}
In the diagram given :
• We are declaring a variable myBox of data type Box. We have not yet assigned a memory reference to it.
• In the second statement, the new keyword instantiates the class by allocating memory to its new object and returns a
reference to that memory to the myBox variable, thereby initializing it.
Key Points:
• The key phrase “instantiating a class” can be described as “creating an object.” When we create an object, we are
actually creating an “instance” of the class.
• The memory reference returned by the new operator can be directly used in an
expression, as shown below. It doesn't need to be assigned to a variable of
appropriate data type.
double height = new Box().height;
• Since arrays are objects in Java, hence while instantiating arrays, we use the new
operator. For example:
// Method that takes parameters and sets the dimensions of the box
public void setDimensions(double width, double height, double depth) {
this.width = width;
this.height = height;
this.depth = depth;
}
`setDimensions()` method: This method takes three parameters (`width`, `height`, and `depth`) and sets the dimensions of
the box based on the provided values.
Non-Parameterized Methods:
- Non-parameterized methods are methods that do not accept any input parameters when they are called. They perform
their operations without requiring any additional data from the calling code.
- Non-parameterized methods are useful when you have fixed behaviors or calculations that do not depend on external
input. These methods are often used for simple operations or utility functions.
Here's an example of a non-parameterized method:
// Method that does not take parameters
public double calculateVolume() {
return width * height * depth;
}
`calculateVolume()` method: This method calculates the volume of the box using the formula `volume = width * height *
depth`. It does not take any parameters and returns the calculated volume.
In summary, parameterized methods accept input parameters for dynamic behavior, while non-parameterized
methods perform fixed operations without requiring any additional data. Both types of methods are essential
in programming and serve different purposes based on the requirements of the code.
In the modified `Box` class, we have added two new methods: With these new methods added to the `Box` class, you can
now use them in your `Main` class to perform volume calculations and set different dimensions for the boxes.
public class Main {
public static void main(String[] args) {
// Initializing using the default constructor
Box defaultBox = new Box();
System.out.println("Default Box: Volume = " + defaultBox.calculateVolume());
Garbage Collection
Write a short note on Garbage Collection
Since objects are dynamically allocated by using the new operator, you might be wondering how such objects are destroyed
and their memory released for later reallocation. In some languages, such as C++, dynamically allocated objects must be
manually released by use of a delete operator. Java takes a different approach; it handles deallocation for you automatically.
The technique that accomplishes this is called garbage collection. It works like this: when no references to an object exist, that
object is assumed to be no longer needed, and the memory occupied by the object can be reclaimed. There is no explicit need
to destroy objects as in C++. Garbage collection only occurs sporadically (if at all) during the execution of your program. It
will not occur simply because one or more objects exist that are no longer used. Furthermore, different Java run-time
implementations will take varying approaches to garbage collection, but for the most part, you should not have to think
about it while writing your programs
When you pass an object as a parameter, you're passing a reference to the object, so any changes made to the object within
the method will affect the original object outside the method. In this example, the `doubleArea()` method modifies the width
and height of the `Rectangle` object, and these modifications are reflected in the original object `rect`.
In programming languages like Java, when passing arguments to methods, there are two common ways that parameters can
be passed: "call by value" and "call by reference". Let's discuss each of these concepts along with an example:
Returning Objects
A method can return any type of data, including class types that you create. For example, in the following program, the
incrByTen( ) method returns an object in which the value of a is ten greater than it is in the invoking object.
class Rectangle {
double length; double width;
Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
double calculateArea() {
return length * width;
}
}
public class ReturnObjectExample {
static Rectangle createRectangle(double length, double width) {
return new Rectangle(length, width);
}
public static void main(String[] args) {
Rectangle rect = createRectangle(5, 3);
double area = rect.calculateArea();
System.out.println("Area of the rectangle: " + area);
}
}
In the provided example, a `Rectangle` class is defined to model rectangles, characterized by their length and width
attributes. The `Rectangle` class incorporates a constructor responsible for initializing these attributes, alongside a
`calculateArea()` method designed to compute the area of the rectangle based on its dimensions. Additionally, a
`ReturnObjectExample` class is introduced, featuring a static method named `createRectangle()`. This method accepts
parameters denoting the length and width of the rectangle and returns a new instance of the `Rectangle` class, initialized
with the specified dimensions. Within the `main()` method of the program, the `createRectangle()` method is invoked to
instantiate a new rectangle object. Subsequently, the returned rectangle object is utilized to calculate and display its area,
exemplifying the concept of returning objects from methods and utilizing them within the program flow.
1) Private access modifier: The private access modifier is accessible only within class.
Example of private access modifier: In this example, we have created two classes A and Simple. A class contains private
data member and private method. We are accessing these private members from outside the class, so there is compile time
error.
class A{
private int data=40;
private void msg(){System.out.println("Hello java");} }
public class Simple{
public static void main(String args[]){
A obj=new A();
System.out.println(obj.data);//Compile Time Error
obj.msg();//Compile Time Error
} }
2) Default access modifier: If you don't use any modifier, it is treated as default by default. The default modifier is
accessible only within package.
Example of default access modifier: Given code has two packages pack and mypack. We are accessing the A class from
outside its package, since A class is not public, so it cannot be accessed from outside the package.
//save by A.java
package pack;
class A{
void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();//Compile Time Error
obj.msg();//Compile Time Error } }
In the above example, the scope of class A and its method msg() is default so it cannot be accessed from outside the package.
3) Protected access modifier: The protected access modifier is accessible within package and outside the package but
Understanding static
Static method/instance variable: Can be accessed before any objects of its class are created, and without reference to any
In summary, static methods are associated with the class rather than individual instances, and they have limited access to other
class members compared to instance methods. They cannot manipulate instance variables directly or reference the current instance
using `this`, as they are not associated with any particular object's state.Initializing static variables : declare a static block that gets
executed exactly once, when the class is first loaded
Example:
public class Counter {
private static int count = 0; // static instance variable
public Counter() {
count++; // Increment count each time a new Counter object is created
}
public static int getCount() { // static method to access count
return count;
}
public static void resetCount() { // static method to reset count to zero
count = 0;
}
}
1. `Counter` class:
- This class represents a counter with a static instance variable `count`, which is initialized to 0.
Introducing final
The `final` keyword in Java is used to apply restrictions on classes, methods, and variables. When applied to a class, it indicates that
the class cannot be subclassed. When applied to a method, it indicates that the method cannot be overridden by subclasses. When
applied to a variable, it indicates that the variable's value cannot be changed once initialized. Let's provide examples for each case:
1. Final Class:
final class FinalClass {
// Class implementation
}
In this example, `FinalClass` is declared as `final`, meaning it cannot be subclassed. Any attempt to extend this class will result
in a compilation error.
2. Final Method:
class ParentClass {
final void finalMethod() {
// Method implementation
}
}
class ChildClass extends ParentClass {
// Attempting to override finalMethod will result in a compilation error
}
In this example, the `finalMethod()` in `ParentClass` is declared as `final`, indicating that it cannot be overridden by
subclasses. Any attempt to override this method in a subclass will result in a compilation error.
3. Final Variable:
class MyClass {
final int constantValue = 10;
void modifyConstant() {
// Attempting to modify constantValue will result in a compilation error
// constantValue = 20;
}
}
In this example, `constantValue` is declared as `final`, meaning its value cannot be changed once initialized. Any attempt to
modify the value of `constantValue` after initialization will result in a compilation error.
These examples demonstrate how the `final` keyword can be used to enforce immutability and restrict inheritance and method
overriding in Java.
2. Avoiding Name Conflicts: When a method or constructor parameter has the same name as an instance variable, the
"this" keyword can be used to distinguish between them.
public class MyClass {
private int value;
public void setValue(int value) {
this.value = value; // "this.value" refers to the instance variable, and "value" refers to the
parameter
}
}
3. Passing the Current Object: Sometimes, you might need to pass the current object as an argument to other methods
or constructors. The "this" keyword is used for this purpose.
public class MyClass {
private int value;
public MyClass() {
initialize(this); // Passing the current object as an argument
}
private void initialize(MyClass obj) {
// Do something with the obj parameter
obj.setValue(42); // Setting the value of the passed object to 42
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public static void main(String[] args) {
MyClass myObject = new MyClass();
System.out.println("Value of myObject: " + myObject.getValue());
}
}
5. Static Context: The "this" keyword cannot be used within a static method, as static methods belong to the class and not
to any specific instance.
public class MyClass {
private static int staticValue;
public static void setStaticValue(int value) {
staticValue = value; // Correct way to access static variables
}
public static int getStaticValue() {
return staticValue;
}
public static void main(String[] args) {
MyClass.setStaticValue(42); // Setting the static value to 42
System.out.println("Static Value: " + MyClass.getStaticValue()); // Retrieving the static value
}
}
In summary, the "this" keyword in Java is used to refer to the current instance of the class. It is most commonly used to
access instance variables, avoid name conflicts, pass the current object to other methods or constructors, and chain
constructors within a class. However, it cannot be used within static methods as static methods do not have access to any
specific instance of the class.
A Stack Class : Write class called Stack that implements a stack for integers:
In this implementation, the Stack class has an integer array data to store the elements, a variable top to keep track of the top
index of the stack, and capacity to set the maximum size of the stack. The class provides methods like push, pop, peek,
isEmpty, and isFull to manipulate and query the stack.
The main method demonstrates how to use the Stack class by pushing and popping elements from the stack. The output
shows the popped value, peeked value, and the size of the stack after some operations.
public class Stack {
private int[] data;
private int top;
private int capacity;
public Stack(int capacity) {
this.data = new int[capacity];
this.top = -1;
this.capacity = capacity;
}
output:
Species: Canine
Breed: Labrador
The Animal class has a species variable and a displaySpecies() method to print the species.
The Dog class extends Animal and adds a breed variable.
In the Dog constructor, super(species) is used to call the superclass constructor and initialize the species variable.
The displayDetails() method in Dog calls the displaySpecies() method of the superclass using super.displaySpecies() to print the species.
In the Main class, we create a Dog object and invoke its displayDetails() method.
This demonstrates how super can be used to call superclass constructors, to access superclass methods (displaySpecies())
and variables (species), allowing subclasses to utilize and extend functionality provided by the superclass.
This demonstrates how hidden variables in a subclass can be accessed and how the superclass variable can be accessed using
`super`.
Explanation:
- We have a superclass `Animal` with a method `eat()`.
- `Dog` class is a subclass of `Animal` and inherits the `eat()` method. It also has its own method `bark()`.
- `Bulldog` class is a subclass of `Dog` and inherits both `eat()` and `bark()` methods. It also adds its own method `guard()`.
- In the `Main` class, we create an object of `Bulldog` class and demonstrate how methods are inherited through multiple levels of inheritance.
Multilevel inheritance allows for the reuse of code and promotes code organization by organizing classes into a hierarchy
based on their relationships. However, it can also lead to tight coupling and complexity if not used carefully.