Xirius-JavaInheritance1-COS201.pdf
Xirius AI
DOCUMENT OVERVIEW
This document, titled "Xirius-JavaInheritance1-COS201.pdf," serves as a comprehensive educational resource on the concept of Inheritance in Java programming, specifically tailored for the COS201 course. It systematically introduces and elaborates on the fundamental principles, syntax, and practical applications of inheritance, a cornerstone of Object-Oriented Programming (OOP). The document aims to equip students with a deep understanding of how inheritance facilitates code reusability, promotes hierarchical classification, and enables polymorphism in Java applications.
The content progresses from basic definitions and the rationale behind using inheritance to more advanced topics such as different types of inheritance, the `super` and `final` keywords, method overriding, abstract classes, interfaces, and polymorphism. It meticulously explains each concept with clear definitions, rules, and illustrative Java code examples, ensuring that learners grasp both the theoretical underpinnings and the practical implementation details. Furthermore, the document highlights the benefits of employing inheritance, such as improved code maintainability and reduced redundancy, while also addressing its potential limitations.
Overall, this PDF acts as a foundational guide for understanding how to design robust and scalable object-oriented systems in Java by leveraging inheritance effectively. It covers essential Java features and constructs related to inheritance, providing a holistic view necessary for developing well-structured and efficient software.
MAIN TOPICS AND CONCEPTS
Inheritance is a fundamental concept in Object-Oriented Programming (OOP) that allows a class to inherit properties and behaviors (fields and methods) from another class. It establishes an "IS-A" relationship between classes, where a subclass (child class) is a specialized version of a superclass (parent class). The primary goals of inheritance are code reusability and the establishment of a hierarchical classification of objects. For example, a "Dog IS-A Animal," meaning a Dog inherits characteristics common to all Animals.
What is Inheritance?Inheritance is a mechanism where one object acquires all the properties and behaviors of a parent object. The class that inherits is called the subclass (or child class, derived class), and the class from which properties are inherited is called the superclass (or parent class, base class). It represents an "IS-A" relationship, signifying that the subclass is a type of the superclass.
Why use Inheritance?The main reasons for using inheritance in Java are:
* Code Reusability: It allows subclasses to reuse methods and fields of the superclass, reducing redundant code and making the program more efficient.
* Method Overriding (Runtime Polymorphism): Inheritance enables method overriding, a mechanism where a subclass provides a specific implementation for a method that is already defined in its superclass. This is crucial for achieving runtime polymorphism.
Types of InheritanceJava supports several types of inheritance, but not all types directly through classes:
* Single Inheritance: A class inherits from only one superclass.
* Example: `Class B extends Class A { ... }`
* Multilevel Inheritance: A class inherits from another class, which in turn inherits from another class.
* Example: `Class C extends Class B { ... }` where `Class B extends Class A { ... }`
* Hierarchical Inheritance: Multiple classes inherit from a single superclass.
* Example: `Class B extends Class A { ... }` and `Class C extends Class A { ... }`
* Multiple Inheritance: A class inherits from multiple superclasses. Java does not support multiple inheritance through classes to avoid the "diamond problem" (ambiguity when two parent classes have methods with the same signature). However, it can be achieved to some extent using interfaces.
* Hybrid Inheritance: A combination of two or more types of inheritance. Since Java doesn't support multiple inheritance via classes, hybrid inheritance involving multiple class parents is also not directly supported.
Inheritance in JavaIn Java, inheritance is implemented using the `extends` keyword. Java supports single, multilevel, and hierarchical inheritance. It explicitly avoids multiple inheritance with classes to maintain simplicity and prevent complex issues like the diamond problem, where a class inherits from two classes that both inherit from a common ancestor, leading to ambiguity about which method implementation to use.
The `extends` KeywordThe `extends` keyword is used to indicate that a class is inheriting from another class.
* Syntax:
```java
class Subclass extends Superclass {
// fields and methods
}
```
* Example:
```java
class Animal {
void eat() { System.out.println("eating..."); }
}
class Dog extends Animal {
void bark() { System.out.println("barking..."); }
}
```
Here, `Dog` inherits the `eat()` method from `Animal`.
`super` KeywordThe `super` keyword in Java is a reference variable that refers to the immediate parent class object. It is used for three main purposes:
1. To refer to immediate parent class instance variable: When a subclass has a field with the same name as a field in its superclass, `super.variableName` is used to access the superclass's field.
* Example:
```java
class Animal { String color = "white"; }
class Dog extends Animal {
String color = "black";
void printColor() {
System.out.println(color); // prints black
System.out.println(super.color); // prints white
}
}
```
2. To invoke immediate parent class method: When a subclass overrides a method from its superclass, `super.methodName()` is used to call the superclass's version of that method.
* Example:
```java
class Animal { void eat() { System.out.println("eating..."); } }
class Dog extends Animal {
void eat() {
System.out.println("dog eating bread...");
super.eat(); // calls Animal's eat()
}
}
```
3. To invoke immediate parent class constructor: `super()` is used to call the constructor of the immediate superclass. It must be the first statement in the subclass constructor.
* Example:
```java
class Animal { Animal(String name) { System.out.println(name + " is an animal."); } }
class Dog extends Animal {
Dog() {
super("Buddy"); // calls Animal's constructor
System.out.println("Dog created.");
}
}
```
Method OverridingMethod overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. The method in the subclass must have the same name, same parameters (signature), and same return type (or a covariant return type) as the method in the superclass.
* Rules for Method Overriding:
* The method must have the same name as in the parent class.
* The method must have the same parameter list as in the parent class.
* The method must have the same return type (or a covariant return type) as in the parent class.
* The access modifier of the overriding method cannot be more restrictive than the overridden method (e.g., `public` can override `protected`, but `protected` cannot override `public`).
* `private` and `final` methods cannot be overridden.
* `static` methods cannot be overridden; if a subclass defines a static method with the same signature as a static method in its superclass, it's called "method hiding," not overriding.
* Example:
```java
class Vehicle {
void run() { System.out.println("Vehicle is running"); }
}
class Bike extends Vehicle {
@Override // Annotation for clarity and compile-time check
void run() { System.out.println("Bike is running safely"); }
}
```
`final` KeywordThe `final` keyword is used to restrict the user. It can be applied to variables, methods, and classes:
* `final` variable: Makes a variable a constant. Its value cannot be changed once initialized.
* Example: `final int SPEED_LIMIT = 90;`
* `final` method: Prevents a method from being overridden by subclasses.
* Example: `class A { final void display() { ... } }`
* `final` class: Prevents a class from being inherited by other classes.
* Example: `final class Bike { ... }`
`instanceof` OperatorThe `instanceof` operator is a binary operator used to test if an object is an instance of a particular class, a subclass of that class, or an interface that the class implements. It returns `true` if the object is an instance of the specified type, and `false` otherwise.
* Syntax: `object instanceof ClassName`
* Example:
```java
class Animal {}
class Dog extends Animal {}
public class Test {
public static void main(String args[]) {
Dog d = new Dog();
System.out.println(d instanceof Animal); // true
Animal a = new Animal();
System.out.println(a instanceof Dog); // false
}
}
```
Abstract Classes and MethodsAn `abstract` class is a class that cannot be instantiated directly. It can contain both abstract methods (methods without a body) and concrete methods (methods with a body). An `abstract` method is a method declared without an implementation.
* Rules for Abstract Classes/Methods:
* An abstract class must be declared with the `abstract` keyword.
* It cannot be instantiated (you cannot create objects of an abstract class).
* It can have constructors, static methods, and `final` methods.
* An abstract method must be declared with the `abstract` keyword and have no body.
* If a class has at least one abstract method, the class itself must be declared abstract.
* A concrete subclass inheriting from an abstract class must provide implementations for all its abstract methods, or it must also be declared abstract.
* Example:
```java
abstract class Shape {
abstract void draw(); // abstract method
void display() { System.out.println("This is a shape."); } // concrete method
}
class Circle extends Shape {
void draw() { System.out.println("drawing circle"); } // implementation
}
```
InterfacesAn interface in Java is a blueprint of a class. It contains `public static final` variables and `public abstract` methods (before Java 8). From Java 8 onwards, interfaces can also have `default` and `static` methods, and from Java 9, `private` methods. Interfaces are used to achieve abstraction and multiple inheritance of type (not implementation).
* Key Characteristics:
* Declared using the `interface` keyword.
* All fields are implicitly `public static final`.
* All methods are implicitly `public abstract` (before Java 8).
* A class uses the `implements` keyword to inherit from an interface.
* A class can implement multiple interfaces, thereby achieving a form of multiple inheritance.
* Interfaces cannot be instantiated.
* Example:
```java
interface Drawable {
void draw(); // implicitly public abstract
// default void msg() { System.out.println("default method"); } // Java 8+
}
class Circle implements Drawable {
public void draw() { System.out.println("drawing circle"); }
}
```
PolymorphismPolymorphism means "many forms." In Java, it refers to the ability of an object to take on many forms. It allows objects of different classes to be treated as objects of a common type.
* Types of Polymorphism:
1. Compile-time Polymorphism (Method Overloading): Achieved when there are multiple methods with the same name but different parameter lists within the same class. The compiler determines which method to call based on the arguments passed.
* Example: `add(int a, int b)` and `add(int a, int b, int c)`
2. Runtime Polymorphism (Method Overriding): Achieved through inheritance and method overriding. A superclass reference variable can refer to an object of a subclass. The actual method invoked is determined at runtime based on the actual object type. This is also known as dynamic method dispatch.
* Example:
```java
class Animal { void eat() { System.out.println("animal eating"); } }
class Dog extends Animal { void eat() { System.out.println("dog eating"); } }
class Cat extends Animal { void eat() { System.out.println("cat eating"); } }
public class TestPoly {
public static void main(String args[]) {
Animal a;
a = new Dog();
a.eat(); // Calls Dog's eat()
a = new Cat();
a.eat(); // Calls Cat's eat()
}
}
```
Benefits of Inheritance* Code Reusability: Reduces code duplication by allowing subclasses to reuse superclass members.
* Reduced Redundancy: Avoids writing the same code multiple times.
* Improved Maintainability: Changes in the superclass automatically propagate to subclasses (unless overridden), simplifying updates.
* Runtime Polymorphism: Enables flexible and extensible code through method overriding.
* Hierarchical Classification: Helps organize classes in a logical, tree-like structure.
Limitations of Inheritance* Tight Coupling: Subclasses are tightly coupled to their superclass, making changes to the superclass potentially impact all subclasses.
* Increased Execution Time: Method lookup in an inheritance hierarchy can sometimes incur a slight overhead compared to direct method calls.
* Complexity: Deep inheritance hierarchies can become complex and difficult to manage or understand.
* Parent Class Changes: Modifying the superclass can break the functionality of subclasses if not carefully managed.
KEY DEFINITIONS AND TERMS
* Inheritance: A mechanism in OOP where one class (subclass) acquires the properties and behaviors (fields and methods) of another class (superclass), establishing an "IS-A" relationship.
* Superclass (Parent Class/Base Class): The class whose properties and methods are inherited by another class.
* Subclass (Child Class/Derived Class): The class that inherits properties and methods from a superclass.
* `extends` Keyword: Used in Java to establish an inheritance relationship between two classes, indicating that one class is a subclass of another.
* `super` Keyword: A reference variable in Java that refers to the immediate parent class object. It is used to access parent class variables, invoke parent class methods, and call parent class constructors.
* Method Overriding: A feature in Java where a subclass provides its own specific implementation for a method that is already defined in its superclass, having the same method signature.
* `final` Keyword: A modifier in Java that can be applied to variables (to make them constants), methods (to prevent overriding), and classes (to prevent inheritance).
* `instanceof` Operator: A binary operator in Java used to test if an object is an instance of a particular class, a subclass, or an interface. It returns a boolean value.
* Abstract Class: A class declared with the `abstract` keyword that cannot be instantiated. It can contain both abstract methods (without implementation) and concrete methods.
* Abstract Method: A method declared without an implementation (body) in an abstract class. Subclasses must implement these methods unless they are also abstract.
* Interface: A blueprint of a class in Java that defines a set of abstract methods (and from Java 8, default/static methods) and `public static final` variables. Classes `implement` interfaces to adhere to a contract.
* Polymorphism: An OOP concept meaning "many forms." In Java, it allows objects of different classes to be treated as objects of a common type, achieved through method overloading (compile-time) and method overriding (runtime).
* Method Overloading (Compile-time Polymorphism): Defining multiple methods in the same class with the same name but different parameter lists.
* Runtime Polymorphism (Dynamic Method Dispatch): The ability of a superclass reference variable to refer to a subclass object, with the actual method invoked determined at runtime based on the object's type.
IMPORTANT EXAMPLES AND APPLICATIONS
- Basic Inheritance with `extends`:
```java
class Animal {
void eat() { System.out.println("Animal eats food."); }
}
class Dog extends Animal {
void bark() { System.out.println("Dog barks."); }
}
// Application:
Dog myDog = new Dog();
myDog.eat(); // Inherited from Animal
myDog.bark(); // Specific to Dog
```
This demonstrates how `Dog` inherits the `eat()` method from `Animal`, showcasing code reusability.
- Using `super` to invoke parent constructor and method:
```java
class Vehicle {
String type;
Vehicle(String type) { this.type = type; }
void displayType() { System.out.println("Vehicle type: " + type); }
}
class Car extends Vehicle {
String model;
Car(String type, String model) {
super(type); // Invokes Vehicle's constructor
this.model = model;
}
void displayInfo() {
super.displayType(); // Invokes Vehicle's displayType()
System.out.println("Car model: " + model);
}
}
// Application:
Car myCar = new Car("Sedan", "Civic");
myCar.displayInfo();
```
This example illustrates how `super()` is used to initialize the parent class's state and `super.method()` to call the parent's method, especially useful when methods are overridden.
- Method Overriding and Runtime Polymorphism:
```java
class Bank {
float getRateOfInterest() { return 0; }
}
class SBI extends Bank {
@Override
float getRateOfInterest() { return 8.4f; }
}
class ICICI extends Bank {
@Override
float getRateOfInterest() { return 7.3f; }
}
// Application:
Bank b; // Reference variable of type Bank
b = new SBI();
System.out.println("SBI Rate of Interest: " + b.getRateOfInterest()); // Calls SBI's method
b = new ICICI();
System.out.println("ICICI Rate of Interest: " + b.getRateOfInterest()); // Calls ICICI's method
```
This is a classic example of runtime polymorphism, where the specific `getRateOfInterest()` method invoked depends on the actual object type (SBI or ICICI) at runtime, even though the reference variable is of the `Bank` type.
- Abstract Class and Interface for defining contracts:
```java
abstract class Figure {
abstract void calculateArea(); // Abstract method
void displayMessage() { System.out.println("Calculating area of a figure."); }
}
interface Resizable {
void resize(int percentage); // Abstract method
}
class Rectangle extends Figure implements Resizable {
int length, width;
Rectangle(int l, int w) { this.length = l; this.width = w; }
@Override
void calculateArea() { System.out.println("Area: " + (length * width)); }
@Override
public void resize(int percentage) {
this.length = this.length * (100 + percentage) / 100;
this.width = this.width * (100 + percentage) / 100;
System.out.println("Resized to " + percentage + "%");
}
}
// Application:
Rectangle rect = new Rectangle(10, 5);
rect.displayMessage();
rect.calculateArea();
rect.resize(20);
rect.calculateArea();
```
This demonstrates how abstract classes provide a base for common functionalities and abstract methods that must be implemented by subclasses, while interfaces define a contract for behaviors that can be implemented by any class, allowing for multiple inheritance of type.
DETAILED SUMMARY
The provided PDF document, "Xirius-JavaInheritance1-COS201.pdf," offers a thorough exploration of inheritance in Java, a core principle of Object-Oriented Programming (OOP). It begins by defining inheritance as a mechanism for code reusability and establishing "IS-A" relationships between classes, where a subclass acquires properties and behaviors from a superclass. The document emphasizes that inheritance is crucial for reducing code redundancy and enabling runtime polymorphism through method overriding.
The discussion then delves into the various types of inheritance. It clarifies that Java supports single, multilevel, and hierarchical inheritance directly through classes, but explicitly does not support multiple inheritance via classes to avoid complexities like the "diamond problem." However, it notes that interfaces can be used to achieve a form of multiple inheritance of type. The `extends` keyword is introduced as the fundamental syntax for establishing an inheritance relationship between a subclass and a superclass.
A significant portion of the document is dedicated to the `super` keyword, explaining its three primary uses: referring to immediate parent class instance variables (to resolve naming conflicts), invoking immediate parent class methods (to call the superclass's version of an overridden method), and calling immediate parent class constructors (which must be the first statement in the subclass constructor). These uses are vital for proper interaction between parent and child classes.
Method overriding is explained in detail, outlining the rules that govern it, such as identical method signatures, compatible return types, and non-restrictive access modifiers. It also distinguishes method overriding from method hiding (for static methods) and clarifies that `private` and `final` methods cannot be overridden. The `final` keyword itself is covered, demonstrating its application to variables (for constants), methods (to prevent overriding), and classes (to prevent inheritance).
The document also introduces the `instanceof` operator, a runtime check to determine if an object is an instance of a particular class or interface. This is useful for type checking and safe casting.
Abstract classes and methods are presented as tools for achieving abstraction. An abstract class cannot be instantiated and can contain both abstract methods (without implementation) and concrete methods. Abstract methods must be implemented by concrete subclasses, enforcing a contract. Interfaces are then introduced as a more complete form of abstraction, acting as blueprints for classes. They primarily contain `public static final` variables and `public abstract` methods (with additions like `default` and `static` methods from Java 8). Interfaces are highlighted as Java's mechanism for achieving multiple inheritance of type.
Polymorphism, meaning "many forms," is thoroughly explained, differentiating between compile-time polymorphism (method overloading, where methods have the same name but different parameters) and runtime polymorphism (method overriding, where a superclass reference variable can point to a subclass object, and the actual method invoked is determined at runtime). Runtime polymorphism is illustrated with clear examples involving a superclass reference variable holding different subclass objects.
Finally, the document summarizes the key benefits of inheritance, including code reusability, reduced redundancy, improved maintainability, and the enablement of runtime polymorphism. It also candidly discusses the limitations, such as tight coupling between classes, potential increases in execution time due to method lookup, and the complexity that can arise from deep inheritance hierarchies. In conclusion, the PDF provides a well-rounded and practical guide to understanding and applying inheritance in Java for COS201 students.