Inheritance Concepts
The inheritance mechanism acts as a foundational element in object-oriented design, facilitating code reusability. It allows developers to extend an existing class while preserving its core characteristics, resulting in new classes known as derived classes. This structure establishes a hierarchical relationship within the system, reflecting a progression from basic constructs to complex implementations. The primary objectives of inheritance involve abstracting shared features to maximize efficiency and enabling polymorphism.
Consider a hierarchy where Vehicle represents a base class, while Car and Bicycle derive from it. Here, Vehicle is the superclass, and the others are subclasses. Upon establishing this link, child classes gain access to the parent's properties and behaviors. Consequently, developers focus solely on implementing unique features specific to the subclass, avoiding redundant code.
Syntax Implementation
To definee an inheritance relationship in Java, the extends keyword is utilized:
Modifier class SubClass extends SuperClass {
// implementation details
}
A concrete example demonstrates how fields and methods flow from a parent to a child entity:
class ElectronicDevice {
protected String manufacturer;
protected int powerCapacity;
protected boolean isActive;
public void startSystem() {
System.out.println("Device starting sequence initiated.");
}
public void chargeBattery() {
System.out.println("Charging process completed.");
}
}
class Smartphone extends ElectronicDevice {
public void makeCall() {
System.out.println("Placing a call via " + manufacturer);
}
}
class Tablet extends ElectronicDevice {
public void browseInternet() {
System.out.println("Connected network interface active.");
}
}
public class SystemTest {
public static void main(String[] args) {
Smartphone phone = new Smartphone();
phone.manufacturer = "TechCorp";
phone.powerCapacity = 4000;
// Inherits startSystem() and chargeBattery()
phone.startSystem();
phone.chargeBattery();
// Unique to Smartphone
phone.makeCall();
}
}
Key observations regarding this syntax include:
- All accessible members from the superclass are automatically available within the subclass.
- Subclasses must introduce distinct functionality to justify their existence; otherwise, inheritance provides no architectural benefit.
Accessing Superclass Members
Variable Scope and Shadowing
Interactions between subclass and superclass variibles depend on naming conventions.
Scenario A: Disjoint Names
When member variable names do not conflict, direct assignment works seamlessly:
class Configuration {
int timeoutValue;
int retryCount;
}
class AdvancedConfig extends Configuration {
int bufferLimit;
public void setLimits() {
timeoutValue = 100; // Accessed from parent
retryCount = 5; // Accessed from parent
bufferLimit = 2000; // Accessed from self
}
}
Scenario B: Duplicate Names (Shadowing)
If a subclass defines a variable with the same name as the parent, the subclass variable takes precedence within its own scope:
class DataStore {
public int level = 10;
public int count = 20;
public float speed = 5.0f;
}
class CachedData extends DataStore {
public int level = 99; // Overrides integer type
public long count = 100L; // Overrides with different primitive type
public void analyzeState() {
System.out.println(level); // Prints 99 (Subclass local)
System.out.println(count); // Prints 100 (Subclass local)
System.out.println(speed); // Prints 5.0f (Inherited from parent)
// Accessing parent member explicitly
System.out.println(super.level);
System.out.println("------------");
// Both keywords work for self-defined members
System.out.println(super.count);
System.out.println(this.count);
}
}
Resolution rules for member variables:
- If the subclass declares a variable, it shadows the parent's variable. Local access retrieves the subclass version.
- If the subclass does not declare the variable, the lookup traverses up to the superclass.
- If neither contains the variable, the compiler generates an error.
This behavior follows the principle of locality: explicit declarations take priority over inherited ones. To explicitly access the hidden parent member, the super keyword is required.
Method Interaction
Accessing methods involves determining whether signatures match or differ.
Method Names Differ:
The subclass inherits all public methods from the parent without restriction, allowing independent calls.
class HardwareBase {
public void connectPeripheral() {
System.out.println("Connecting external device...");
}
}
class SmartHomeController extends HardwareBase {
public void controlLights() {
System.out.println("Managing lighting protocols.");
}
// Can call inherited method alongside its own
public void setupSystem() {
connectPeripheral();
controlLights();
}
}
Variable Access Rules Summary
In scenarios involving inheritance, variable visibility adheres to strict scoping rules. If a derived class implements a member identcial to the base, the base member becomes hidden unless referenced via super. This distinction is crucial when understanding state management within object hierarchies.