Unit 4
Unit 4
In Java, there are two types of inheritance: single-level inheritance and multilevel
inheritance.
class Vehicle {
public void start() {
System.out.println("Vehicle started");
}
}
In this example, the class Car is a subclass of the class Vehicle. The Car class
inherits the start() method from the Vehicle class and adds its own drive() method.
class Animal {
public void eat() {
System.out.println("Animal is eating");
}
}
In this example, the class Dog is a subclass of the class Mammal, which is itself a
subclass of the class Animal. The Dog class inherits the eat() method from the
Animal class, the walk() method from the Mammal class, and adds its own bark()
method.
Method Overriding
To override a method, the subclass must provide a method with the same name,
return type, and parameters as the method in the superclass. The method in the
subclass must also have the same or a more accessible access modifier than the
method in the superclass.
When the method is called on an object of the subclass, the implementation in the
subclass is executed instead of the implementation in the superclass. This is
because the Java Virtual Machine (JVM) determines the implementation of the
method based on the actual type of the object at runtime, rather than the declared
type of the reference variable.
class Animal {
@Override
System.out.println("Meow");
In this example, the Animal class has a method makeSound(). The Cat class extends
the Animal class and overrides the makeSound() method with its own
implementation that prints "Meow". In the main method, an object of the Animal
class and an object of the Cat class are created, and the makeSound() method is
called on each object. When the method is called on the Cat object, the
implementation in the Cat class is executed, even though the reference variable is
of type Animal. This demonstrates the dynamic method dispatch feature of Java.
When a method is called on an object, the JVM looks at the type of the object at
runtime and determines which implementation of the method to execute. If the
method is overridden in the subclass, the implementation in the subclass is
executed instead of the implementation in the superclass. This is known as
dynamic method dispatch.
@Override
System.out.println("Meow");
}
In this example, the Animal class has a method makeSound(). The Cat class extends
the Animal class and overrides the makeSound() method with its own
implementation that prints "Meow". In the main method, an object of the Animal
class, an object of the Cat class, and a reference variable of type Animal referring
to an object of the Cat class are created. When the makeSound() method is called
on each object or reference variable, the implementation that is executed is
determined at runtime based on the actual type of the object, demonstrating
dynamic method dispatch.
Abstract Classes
In Java, an abstract class is a class that cannot be instantiated on its own, but can be
subclassed by other classes. Abstract classes are useful when creating a hierarchy
of classes that share some common functionality, but each subclass has its own
specific behavior.
An abstract class is declared using the abstract keyword in its class definition. It can
contain both abstract and non-abstract methods. Abstract methods are methods that
do not have an implementation and are declared using the abstract keyword. Non-
abstract methods, on the other hand, have an implementation and are declared as
usual.
System.out.println("Animal is eating");
@Override
System.out.println("Meow");
}
In this example, the Animal class is declared as an abstract class with an abstract
method makeSound() and a non-abstract method eat(). The Cat class extends the Animal
class and provides an implementation for the makeSound() method.
In the Main class, an object of the Cat class is created and assigned to a reference
variable of type Animal. The makeSound() and eat() methods are called on the reference
variable, which calls the implementation of the makeSound() method from the Cat
class and the implementation of the eat() method from the Animal class.
Note that you cannot create an instance of an abstract class using the new keyword. You can only create instances of its non-
abstract subclasses. Also, if a class contains one or more abstract methods, it must be declared as abstract.
interface Animal {
@Override
System.out.println("Meow");
In this example, the Animal interface defines a single method makeSound(). The Cat class
implements the Animal interface and provides an implementation for the makeSound()
method.
Packages: A package is a namespace that organizes a set of related classes and interfaces. It
provides a way to group related classes together and also prevents naming conflicts between
classes with the same name. In Java, a package is declared using the package keyword at the
beginning of a Java file. By convention, the package name is in reverse order of the domain
name of the organization that created the code.
package com.example.animals;
interface Animal {
}
class Cat implements Animal {
@Override
System.out.println("Meow");
In this example, the Animal interface and the Cat and Main classes are declared in the
com.example.animals package. This package can be organized in a directory structure that
reflects the package name, with the Java files in the corresponding directory. For example,
the Main.java file can be located in the directory com/example/animals. To use classes from
this package in other Java files, you can use the import statement at the beginning of the file.
Extending interfaces and packages are important concepts in Java that help in
organizing and structuring code and also provide flexibility in code reuse.
Extending Interfaces: In Java, an interface can extend one or more other interfaces
using the extends keyword. When an interface extends another interface, it inherits
all the methods and constants from the parent interface. The child interface can
also add its own methods and constants.
interface Animal {
@Override
System.out.println("Meow");
@Override
In this example, the Animal interface defines a single method makeSound(). The
Mammal interface extends the Animal interface and adds a new method giveBirth(). The
Cat class implements the Mammal interface and provides implementations for both
the makeSound() and giveBirth() methods.
Extending Packages: In Java, packages can also be organized hierarchically. This
allows for easy grouping of related packages and also provides flexibility in code
reuse. When a package extends another package, it inherits all the classes and
interfaces from the parent package.
package com.example.animals;
interface Animal {
public void makeSound();
}
In this example, the com.example.animals package contains the Animal, Mammal, and
Main classes. If you have another package called com.example.zoo that needs to use the
Animal and Mammal interfaces, you can extend the com.example.animals package using
the import statement.
package com.example.zoo;
import com.example.animals.*;
class Zoo {
In this example, the Zoo class in the com.example.zoo package imports the Animal,
Mammal , and Cat classes from the com.example.animals package using the import
statement. This allows the Zoo class to use the functionality provided by the Animal,
Mammal , and Cat classes without having to redefine them in the com.example.zoo
package.
Public: Public members and classes are visible to all classes in all packages.
Example:
package com.example;
// code here
In this example, the MyClass class has a public variable myPublicVar and a public
method myPublicMethod(). These members can be accessed from any class in any
package.
Protected: Protected members and classes are visible to all classes within the same
package as well as any subclasses (even if they are in a different package).
Example:
package com.example;
// code here
In this example, the MyClass class has a protected variable myProtectedVar and a
protected method myProtectedMethod(). These members can be accessed from any
class within the same package and any subclass (even if they are in a different
package).
Example:
package com.example;
class MyClass {
int myDefaultVar;
void myDefaultMethod() {
// code here
Private: Members and classes with private visibility are only visible to the same
class.
Example:
package com.example;
// code here
In this example, the MyClass class has a private variable myPrivateVar and a
private method myPrivateMethod(). These members can only be accessed from
within the MyClass class itself.
Java comes with a set of standard packages that provide commonly used
functionality. These packages include java.util, java.lang, java.io, and
java.net.
Example:
import java.util.Scanner;
Example:
System.out.println(greeting);
Example:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MyClass {
try {
while (input.hasNextLine()) {
System.out.println(input.nextLine());
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Example:
import java.net.URL;
import java.net.URLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
try {
String line;
System.out.println(line);
input.close();
} catch (Exception e) {
Wrapper Class
For example, to convert a primitive int to an Integer object, you can use
the valueOf() method:
And to convert an Integer object back to an int, you can use the
intValue() method:
Wrapper classes are often used in situations where you need to store
primitive values in a collection or pass them as arguments to methods that
require objects. Additionally, wrapper classes can be useful when you need
to perform operations on primitive values using methods that are only
available for objects, such as sorting or searching a collection of values.
Overall, wrapper classes provide a convenient way to work with primitive
data types as objects in Java.
Autoboxing and unboxing are convenient features in Java that make code
more readable and easier to write. They allow you to treat primitive values
and their corresponding wrapper class objects interchangeably in most
situations. However, it's important to be aware of the performance
implications of autoboxing and unboxing, as the automatic conversions can
create unnecessary objects and lead to increased memory usage and
decreased performance.
Enumeration
Enumerations, or enums for short, are a special type of class in Java that represent a fixed set
of constants. Enums were introduced in Java 5 and are defined using the enum keyword.
An enum can contain a list of named constants, which are defined as public, static, and final
fields within the enum class. Each constant is typically written in uppercase letters, and they
are separated by commas.
You can also add additional data and methods to an enum. For example, you could define an
enum for the months of the year and include a method to return the number of days in each
month:
JANUARY(31),
FEBRUARY(28),
MARCH(31),
APRIL(30),
MAY(31),
JUNE(30),
JULY(31),
AUGUST(31),
SEPTEMBER(30),
OCTOBER(31),
NOVEMBER(30),
DECEMBER(31);
private final int days;
this.days = days;
return days;
Enums are useful for representing fixed sets of constants that are related to each other. They
can help make code more readable and maintainable by providing a concise and self-
documenting way to represent a set of values. Additionally, enums can be used in switch
statements, and they can also be used as the type of a variable or parameter.
Metadata
Annotations are defined using the @ symbol followed by the name of the
annotation, and they can be added to a declaration in one of two ways:
either directly preceding the declaration, or within the declaration using the
element-value pair syntax.
@Deprecated
// method implementation
}
You can also define your own custom annotations. Custom annotations can
be used to mark classes, methods, or other elements in your code with
additional information that can be processed by tools or frameworks.