JAVA Ass1
JAVA Ass1
OOP
In this example, the Car class overrides the start() method of the Vehicle
class.
void sleep() {
System.out.println("This animal is sleeping");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("The cat meows");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.sound(); // Outputs: The cat meows
cat.sleep(); // Outputs: This animal is sleeping
}
}
Here, Animal is an abstract class that has an abstract method sound(). The
Cat class provides an implementation for this abstract method.
2. Interfaces: An interface in Java is a reference type, similar to a class,
but it can only contain abstract methods (before Java 8). From Java 8
onwards, interfaces can also have default and static methods with
implementations.
Example:
interface Animal {
void sound(); // Interface method (implicitly public and abstract)
}
class Dog implements Animal {
@Override
public void sound() {
System.out.println("The dog barks");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // Outputs: The dog barks
}
}
In this example, the Dog class implements the Animal interface and
provides a concrete implementation for the sound() method.
Conclusion
OOP in Java provides a flexible, modular, and reusable structure for
building complex and scalable applications. By using encapsulation,
inheritance, polymorphism, and abstraction, developers can write code
that is maintainable, extensible, and easier to understand.
2. JDK
The Java Development Kit (JDK) is a software development
environment used for developing Java applications and applets. It is the
core component of the Java platform and provides all the necessary tools,
libraries, and utilities required to develop, compile, debug, and run Java
applications. The JDK is essential for Java developers, as it contains
everything needed to write and execute Java programs.
Here's a comprehensive overview of the JDK:
4. Development Tools
The JDK comes with several command-line tools for different stages of
Java application development. Here are some of the most widely used
ones:
javac: The Java compiler, used to compile Java source code into
bytecode.
java: The Java launcher, used to start the JVM and run Java
applications.
javadoc: A documentation generator that extracts comments from
the Java source code and generates API documentation in HTML
format.
jar: The Java Archive tool, used to package compiled Java classes
into a single file (typically .jar files) for easier distribution and
execution.
jdb: A command-line debugger for Java, allowing developers to
step through code, set breakpoints, and inspect variables at runtime.
javap: A Java class file disassembler that shows the bytecode and
other low-level details of compiled classes.
jshell: A Read-Eval-Print-Loop (REPL) tool introduced in JDK 9,
allowing developers to test code snippets interactively without
creating a full class or method.
jps, jstack, jmap, jstat: Performance monitoring and diagnostic
tools to help analyze and troubleshoot memory leaks, thread
deadlocks, and other performance issues.
In Java, data types are the foundation for defining variables and constants.
They determine the type of data that can be stored and the operations that
can be performed on that data. Java has two main categories of data types:
1.1. Byte
Size: 8 bits (1 byte)
Default value: 0
Range: -128 to 127
Use case: Useful for saving memory in large arrays where memory
savings matter.
Example: bytebyteValue=100;
1.2. Short
Size: 16 bits (2 bytes)
Default value: 0
Range: -32,768 to 32,767
Use case: Short can save memory in large arrays, but it is rarely used as
int is generally preferred.
Example: shortshortValue=10000;
1.3. Int
Size: 32 bits (4 bytes)
Default value: 0
Range: -2^31 to 2^31-1 (approximately -2.14 billion to 2.14 billion)
Use case: The most commonly used integer data type in Java for numeric
calculations.
Example: intintValue=100000;
1.4. Long
Size: 64 bits (8 bytes)
Default value: 0L
Range: -2^63 to 2^63-1 (approx -9.22 quintillion to 9.22 quintillion)
Use case: When you need a larger range than int can provide, such as for
large computations or representing large values.
Example: longlongValue=10000000000L;
1.5. Float
Size: 32 bits (4 bytes)
Default value: 0.0f
Range: Approximately ±3.4e38 (7 digits of precision)
Use case: Used when you need to save memory and don't need a very
high degree of precision.
Example: floatfloatValue=3.14f;
1.6. Double
Size: 64 bits (8 bytes)
Default value: 0.0d
Range: Approximately ±1.7e308 (15 digits of precision)
Use case: The default data type for decimal values in Java and should be
used when precision matters.
Example: doubledoubleValue=3.14159;
1.7. Boolean
Size: 1 bit (though its precise size is JVM-dependent)
Default value: false
Values: true or false
Use case: Represents one of two values, true or false. Commonly used in
conditional statements, loops, and flags for control flow.
Example: booleanisJavaFun=true;
1.8. Char
Size: 16 bits (2 bytes)
Default value: '\u0000' (the null character)
Range: 0 to 65,535 (since it stores Unicode values)
Use case: Used for storing a single character.
Example: charletter='A';
Example of Inheritance
Let's consider a more detailed example to illustrate the concept of
inheritance in Java.
Example:-
classVehicle {
int speed;
voidmove() {
System.out.println("Vehicle is moving at speed: " + speed);
}
}
classCarextendsVehicle {
int numDoors;
voiddisplay() {
System.out.println("Car has " + numDoors + " doors and is moving
at speed: " + speed);
}
}
publicclassMain {
publicstaticvoidmain(String[] args) {
CarmyCar=newCar();
myCar.speed = 60; // Inherited from Vehicle
myCar.numDoors = 4; // Specific to Car
myCar.move(); // Inherited method
myCar.display(); // Specific to Car
}
}
Explanation:
Vehicle is the superclass that has a speed attribute and a move() method.
Car is the subclass that inherits speed and move() from Vehicle and adds
a numDoors attribute and a display() method. The myCar object of class
Car has access to both the Vehicle and Car methods.
Advantages of Inheritance
1. Code Reusability: You can reuse existing code by inheriting it into the
subclass rather than writing the code again. This reduces redundancy.
2. Polymorphism: Inheritance allows the subclass to define specific
implementations of methods, which enables polymorphism (method
overriding). This allows for dynamic method dispatch, where the type of
the object determines which method is executed at runtime.
3. Extensibility: New features can be added to an existing class without
modifying it, by sub classing and extending the original class.
4. Data Hiding: The parent class can protect certain fields and methods
using access modifiers like private and protected, allowing controlled
access from subclasses.
Disadvantages of Inheritance
1. Tight Coupling: Inheritance creates a tightly coupled relationship
between the superclass and subclass. Changes in the superclass can affect
the subclasses, which can lead to maintenance challenges.
2. Complexity: Overusing inheritance or creating deep inheritance
hierarchies can make the code complex, difficult to understand, and hard
to maintain.
3. Limited Flexibility: Java only supports single inheritance through
classes. A class can only inherit from one superclass, which can limit the
flexibility compared to languages that support multiple inheritance.
5. POLYMORPHISM
Polymorphism is a core concept of OOP’s that allows objects of
different types to be treated as objects of a common super type. It enables
a single method, interface, or class to represent different behaviors in
different contexts. The term "polymorphism" comes from Greek,
meaning "many forms," and in Java, it refers to the ability of a single
method or object to take on different forms depending on the situation.
Polymorphism in Java can be categorized into two main types:
1. Compile-time (Static) Polymorphism
Compile-time polymorphism, also known as static polymorphism, is
resolved during the compilation of the program. In Java, it is achieved
through method overloading and operator overloading.
a. Method Overloading
Method overloading allows multiple methods in the same class to have
the same name but with different parameter lists. The method to be called
is resolved at compile time based on the method signature.
Example:
classCalculator {
intadd(int a, int b) {
return a + b;
}
intadd(int a, int b, int c) {
return a + b + c;
}
doubleadd(double a, double b) {
return a + b;
}
}
publicclassMain {
publicstaticvoidmain(String[] args) {
Calculatorcalc=newCalculator();
System.out.println(calc.add(10, 20));
System.out.println(calc.add(10, 20, 30));
System.out.println(calc.add(10.5, 20.5));
}
}
b.Upcasting
Upcasting refers to treating a subclass object as if it were an instance of
its superclass. This allows Java to achieve runtime polymorphism. In
upcasting, the subclass object can still call overridden methods, but not
methods specific to the subclass unless explicitly cast back to the subclass.
Example: AnimalmyDog=newDog(); // Upcasting
myDog.sound(); // Calls the Dog class's overridden method
Here, myDog is treated as an Animal reference, but it still calls the
sound() method from the Dog class because of polymorphism.
Advantages of Polymorphism
1. Code Reusability: Polymorphism allows you to write code that works
with multiple types of objects, reducing redundancy.
2. Flexibility and Maintainability: It allows one method to work with
objects of different types, which makes code more flexible and easier to
extend or maintain.
3. Dynamic Method Invocation: Runtime polymorphism allows
dynamic method invocation, which means that method calls are resolved
at runtime based on the actual object being referred to.
4. Simplifies Code: Through polymorphism, the same piece of code can
work for objects of different types, reducing the complexity of the overall
program.
Disadvantages of Polymorphism
1. Slower Execution: Runtime polymorphism incurs a slight
performance overhead because method calls are resolved at runtime
rather than compile-time.
2. Debugging Complexity: Because method invocations are determined
at runtime, tracking down bugs can be more challenging, especially in
larger applications.
3. Increased Complexity in Understanding: New developers may find
it harder to understand the code since method invocation depends on the
actual object at runtime, not the reference type.
4. Reduced Type Safety: Polymorphism sometimes leads to reduced
compile-time type safety, which may result in runtime errors (though
Java mitigates this to a large extent with its strong typing system).
Summary
Polymorphism in Java provides flexibility in code design by allowing
objects of different classes to be treated as objects of a common
superclass or interface. It is mainly achieved through:
1. Compile-time (static): Via method overloading.
2. Runtime (dynamic): Via method overriding and up casting.
It enables Java applications to have cleaner, more modular, and extensible
designs by supporting object-oriented principles like abstraction,
encapsulation, and inheritance.