Inheritance, Package and Collection
3.1 Overview of Inheritance
Inheritance is a fundamental concept in object-oriented programming that allows a new class (derived class or subclass) to inherit attributes and methods from an existing class (base class or superclass). This promotes code reuse and establishes a natural hierarchy between classes.
Key Points:
Superclass: The class being inherited from.
Subclass: The class that inherits from the superclass.
extends Keyword: Used to create a subclass from a superclass.
Method Overriding: A subclass can provide a specific implementation of a method already defined in its superclass.
Access Specifiers: Inheritance respects access control modifiers (private, protected, public).
3.2 Inheritance in Constructors
Constructors are not inherited in the same way as methods. However, a subclass constructor can call a superclass constructor using the super keyword. This ensures that the initialization defined in the superclass is performed.
Example:
class Animal {
String name;
// Superclass constructor
Animal(String name) {
this.name = name;
}
void display() {
System.out.println("Animal name: " + name);
}
}
class Dog extends Animal {
String breed;
// Subclass constructor
Dog(String name, String breed) {
super(name); // Calls the superclass constructor
this.breed = breed;
}
@Override
void display() {
super.display(); // Calls the superclass method
System.out.println("Dog breed: " + breed);
}
}
public class InheritanceExample {
public static void main(String[] args) {
Dog dog = new Dog("Buddy", "Golden Retriever");
dog.display();
}
}
3.3 Inheriting Data Members and Methods
When a subclass inherits from a superclass, it inherits all non-private data members and methods. The subclass can use these members and methods directly or override them to provide specific functionality.
Example:
java
Copy code
class Animal {
// Data members
protected String name;
protected int age;
// Method
void eat() {
System.out.println(name + " is eating.");
}
}
class Dog extends Animal {
// Additional data member
private String breed;
// Constructor
Dog(String name, int age, String breed) {
this.name = name; // Inherited data member
this.age = age; // Inherited data member
this.breed = breed;
}
// Overridden method
@Override
void eat() {
System.out.println(name + " the " + breed + " is eating.");
}
// Additional method
void bark() {
System.out.println(name + " is barking.");
}
}
public class InheritanceExample {
public static void main(String[] args) {
Dog dog = new Dog("Buddy", 5, "Golden Retriever");
dog.eat(); // Calls overridden method
dog.bark(); // Calls subclass method
}
}
Key Points:
Data Members: Subclasses inherit all non-private data members. Private members are not accessible directly, but they can be accessed via public/protected getter and setter methods.
Methods: Subclasses inherit all non-private methods. They can use these methods as is or override them to change their behavior.
3.4 Multilevel Inheritance
Multilevel inheritance is a type of inheritance where a class is derived from another derived class, forming a chain of inheritance. In this structure, the subclass inherits the properties and methods of its superclass, which in turn inherits from another superclass.
Method Overriding in Multilevel Inheritance
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. In multilevel inheritance, any subclass can override a method from any superclass in the inheritance chain.
Handling Multilevel Constructors
When dealing with multilevel inheritance, constructors from each superclass in the hierarchy must be called to ensure proper initialization. The super keyword is used to call the constructor of the immediate superclass.
Example
class Animal {
String name;
Animal(String name) {
this.name = name;
System.out.println("Animal constructor called");
}
void eat() {
System.out.println(name + " is eating.");
}
}
class Mammal extends Animal {
Mammal(String name) {
super(name); // Call to Animal's constructor
System.out.println("Mammal constructor called");
}
@Override
void eat() {
System.out.println(name + " the mammal is eating.");
}
}
class Dog extends Mammal {
Dog(String name) {
super(name); // Call to Mammal's constructor
System.out.println("Dog constructor called");
}
@Override
void eat() {
System.out.println(name + " the dog is eating.");
}
}
public class MultilevelInheritanceExample {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
dog.eat();
}
}
3.5 Use of super and final Keyword
super Keyword
The super keyword in Java is used to refer to the immediate superclass of a current object. It can be used to:
Call a superclass constructor.
Call a superclass method.
Example of super Keyword
class Animal {
void eat() {
System.out.println("Animal is eating.");
}
}
class Dog extends Animal {
@Override
void eat() {
super.eat(); // Calls the superclass method
System.out.println("Dog is eating.");
}
}
public class SuperExample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
}
}
final Keyword
The final keyword can be used with classes, methods, and variables to restrict their modification:
final class: A class that cannot be subclassed.
final method: A method that cannot be overridden.
final variable: A variable whose value cannot be changed once assigned.
Example of final Keyword
final class Animal {
final void eat() {
System.out.println("Animal is eating.");
}
}
class Dog { // Cannot extend Animal because Animal is final
// void eat() { // Cannot override because eat() is final in Animal
// System.out.println("Dog is eating.");
// }
}
public class FinalExample {
public static void main(String[] args) {
Animal animal = new Animal();
animal.eat();
}
}
3.6 Interface
An interface in Java is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. Interfaces cannot contain instance fields or constructors. They are used to specify a contract that classes must follow.
Key Points
Method Signatures: An interface defines methods that implementing classes must provide.
Multiple Inheritance: A class can implement multiple interfaces, providing a way to achieve multiple inheritance.
Default Methods: Methods in interfaces with a default implementation.
Static Methods: Methods in interfaces that are static.
Example of an Interface
interface Animal {
void eat();
void sleep();
}
class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog is eating.");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping.");
}
}
public class InterfaceExample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.sleep();
}
}
Multiple Interface Implementation
interface Animal {
void eat();
}
interface Pet {
void play();
}
class Dog implements Animal, Pet {
@Override
public void eat() {
System.out.println("Dog is eating.");
}
@Override
public void play() {
System.out.println("Dog is playing.");
}
}
public class MultipleInterfaceExample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.play();
}
}
Multilevel Inheritance: Allows classes to inherit from other derived classes. Constructors and methods can be overridden in the inheritance chain.
super Keyword: Used to call superclass constructors and methods.
final Keyword: Prevents classes from being subclassed, methods from being overridden, and variables from being reassigned.
Interfaces: Define a contract that implementing classes must follow, supporting multiple inheritance and abstract method definitions.
3.7 Creation and Implementation of an Interface, Interface Reference
Creating an Interface
An interface in Java is created using the interface keyword. It can contain abstract methods, default methods, static methods, and constants.
Example:
interface Animal {
void eat();
void sleep();
}
Implementing an Interface
A class implements an interface using the implements keyword and provides concrete implementations for all the interface methods.
Example:
class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog is eating.");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping.");
}
}
public class InterfaceExample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.sleep();
}
}
Interface Reference
An interface reference can refer to any object that implements the interface. This allows for polymorphic behavior.
Example:
public class InterfaceReferenceExample {
public static void main(String[] args) {
Animal animal = new Dog(); // Interface reference
animal.eat();
animal.sleep();
}
}
3.8 Interface Inheritance
Interfaces can extend other interfaces, allowing for a hierarchical structure. An interface can extend multiple interfaces, enabling multiple inheritance.
Example:
interface Animal {
void eat();
}
interface Mammal extends Animal {
void walk();
}
class Dog implements Mammal {
@Override
public void eat() {
System.out.println("Dog is eating.");
}
@Override
public void walk() {
System.out.println("Dog is walking.");
}
}
public class InterfaceInheritanceExample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.walk();
}
}
3.9 Dynamic Method Dispatch
Dynamic method dispatch, also known as runtime polymorphism, is the mechanism by which a call to an overridden method is resolved at runtime rather than compile-time. This is achieved through method overriding and interface references.
Example:
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("Cat meows");
}
}
public class DynamicMethodDispatchExample {
public static void main(String[] args) {
Animal animal;
animal = new Dog();
animal.sound(); // Calls Dog's sound method
animal = new Cat();
animal.sound(); // Calls Cat's sound method
}
}
Summary
Creation and Implementation of an Interface: Interfaces are created using the interface keyword. Classes implement interfaces using the implements keyword, and an interface reference can refer to any object that implements the interface.
Interface Inheritance: Interfaces can extend other interfaces, enabling hierarchical and multiple inheritance structures.
Dynamic Method Dispatch: Allows method calls to be resolved at runtime. This is achieved through method overriding and interface references, enabling polymorphic behavior.
3.10 Abstract Class
An abstract class in Java is a class that cannot be instantiated on its own and is meant to be subclassed. It may contain abstract methods, which are declared but not implemented in the abstract class. Subclasses must implement these abstract methods.
Creating an Abstract Class
An abstract class is created using the abstract keyword.
abstract class Animal {
abstract void sound(); // Abstract method
}
Implementing an Abstract Class
Subclasses of an abstract class must provide concrete implementations for all abstract methods, or they themselves must be declared abstract.
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
3.11 Comparison between Abstract Class and Interface
Abstract Class
Can have constructors.
Can have both abstract and non-abstract methods.
Can have member variables that can be inherited.
Supports single inheritance only.
Can provide default implementations for methods.
Can have access modifiers for methods and fields.
Interface
Cannot have constructors.
Can only have abstract methods (before Java 8).
Cannot have member variables, only constants.
Supports multiple inheritance.
Cannot provide default implementations for methods (before Java 8), but default and static methods are allowed in Java 8 and later.
All methods are implicitly public and abstract.
3.12 Access Control
Access control in Java determines the accessibility of classes, methods, and variables from different parts of the program.
Access Modifiers
Private: Accessible only within the same class.
Default (Package-private): Accessible only within the same package.
Protected: Accessible within the same package and by subclasses (even if they are in a different package).
Public: Accessible from anywhere.
Example:
public class AccessControlExample {
private int privateVar;
int defaultVar; // Package-private
protected int protectedVar;
public int publicVar;
private void privateMethod() {
System.out.println("Private method");
}
void defaultMethod() { // Package-private
System.out.println("Default method");
}
protected void protectedMethod() {
System.out.println("Protected method");
}
public void publicMethod() {
System.out.println("Public method");
}
}
Accessing Members
public class Main {
public static void main(String[] args) {
AccessControlExample obj = new AccessControlExample();
// Accessing variables
obj.defaultVar = 10;
obj.protectedVar = 20;
obj.publicVar = 30;
// Accessing methods
obj.defaultMethod();
obj.protectedMethod();
obj.publicMethod();
}
}
Summary
Abstract Class: Used when you want to provide a common interface for subclasses while leaving some methods to be implemented by them.
Interface: Used when you want to provide a contract that implementing classes must adhere to, allowing multiple inheritance.
Access Control: Determines the accessibility of classes, methods, and variables, ensuring encapsulation and security in Java programs.
3.13 Packages
In Java, packages are used to organize classes into namespaces, providing a way to modularize code and prevent naming conflicts. A package can contain multiple classes and sub-packages, helping to maintain code organization and structure.
3.13.1 Packages Concept
Key Points:
Namespace: Packages provide a way to create separate namespaces for classes, preventing naming conflicts.
Organization: Packages help organize related classes and resources.
Access Control: Classes in the same package can access each other's package-private members directly.
Naming Convention: Package names are usually in lowercase and follow a reverse domain name convention (e.g., com.example.package).
3.13.2 Creating User-defined Packages
Package Declaration
To declare a class to be a part of a package, use the package keyword followed by the package name at the top of the source file.
package com.example.mypackage;
public class MyClass {
// Class members and methods
}
Using User-defined Packages
To use a class from a user-defined package, you can either specify the fully qualified class name or import the package.
Example:
import com.example.mypackage.MyClass;
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
// Use obj
}
}
3.13.3 Java Built-in Packages
Java provides several built-in packages that contain a variety of classes and interfaces for different functionalities.
Examples of Built-in Packages:
java.lang: Contains fundamental classes and interfaces that are automatically imported into every Java program.
java.util: Contains utility classes and interfaces, such as collections framework, date and time utilities, etc.
java.io: Contains classes for handling input and output operations, such as file I/O, streams, etc.
java.net: Contains classes for networking operations, such as sockets, URLs, etc.
3.13.4 Import Statement, Static Import
Import Statement
The import statement is used in Java to make classes and interfaces from other packages available in the current source file.
Example:
import java.util.ArrayList;
import java.util.List;
Static Import
The static import statement is used to import static members (fields and methods) of a class or interface so that they can be used directly without qualification.
Example:
import static java.lang.Math.PI;
Summary
Packages: Used for organizing classes and resources into namespaces, preventing naming conflicts and providing modularity.
User-defined Packages: Created by using the package keyword in source files and can be imported for use in other classes.
Built-in Packages: Provided by Java and contain classes and interfaces for various functionalities.
Import Statement: Used to import classes and interfaces from other packages.
Static Import: Used to import static members of a class or interface for direct use without qualification.
3.14 Collection
In Java, the Collection Framework provides a set of classes and interfaces to represent and manipulate collections of objects. Collections are used to store, retrieve, and manipulate groups of objects.
3.14.1 Collection Framework
The Collection Framework in Java provides a unified architecture for representing and manipulating collections of objects. It includes interfaces, implementations, and algorithms to work with collections.
Key Components:
Interfaces: Defines contracts for different types of collections.
Implementations: Provides concrete implementations of the collection interfaces.
Algorithms: Contains algorithms to operate on collections.
3.14.2 Interfaces: Collection, List, Set
Collection Interface
Represents a group of objects known as elements.
Does not guarantee any specific order of elements.
Key Subinterfaces: List, Set.
List Interface
Represents an ordered collection (sequence) of elements.
Allows duplicate elements.
Key Implementations: ArrayList, LinkedList.
Set Interface
Represents a collection of unique elements.
Does not allow duplicate elements.
Key Implementations: HashSet, TreeSet.
3.14.3 Navigation: Enumeration, Iterator, ListIterator
Enumeration Interface
Allows iterating through elements of a collection.
Only supports read operations.
Superseded by Iterator interface.
Iterator Interface
Allows traversing through elements of a collection.
Supports both read and remove operations.
More flexible and powerful than Enumeration.
ListIterator Interface
Extends Iterator interface and allows bidirectional traversal of elements in a list.
Supports additional operations like adding and modifying elements during traversal.
3.14.4 Classes: LinkedList, ArrayList, Vector, HashSet
LinkedList Class
Implements the List interface using a doubly linked list.
Provides efficient insertion and deletion operations.
Suitable for frequent insertion and deletion operations.
ArrayList Class
Implements the List interface using a dynamic array.
Provides fast random access to elements.
Suitable for scenarios requiring frequent access to elements by index.
Vector Class
Deprecated since Java 2, replaced by ArrayList.
Similar to ArrayList but synchronized (thread-safe).
Slower than ArrayList due to synchronization overhead.
HashSet Class
Implements the Set interface using a hash table.
Does not guarantee the order of elements.
Provides constant-time performance for basic operations (add, remove, contains) on average.
Summary
Collection Framework: Provides a unified architecture for representing and manipulating collections of objects.
Interfaces: Collection, List, and Set define contracts for different types of collections.
Navigation: Enumeration, Iterator, and ListIterator allow traversing through elements of collections.
Classes: LinkedList, ArrayList, Vector, and HashSet are commonly used implementations of collection interfaces.
No comments:
Post a Comment