Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Core Java Concepts: Data Structures, OOP, and Polymorphism

Tech 2

Data Types and Collections

Java provides several core data structures for storing and managing data.

public class CoreExamples {
    public static void main(String[] args) {
        // Array
        int[] numberArray = new int[]{10, 20, 30};
        System.out.println(numberArray[0]); // Prints 10
        numberArray[2] = 40; // Modify element

        // ArrayList
        ArrayList<String> stringList = new ArrayList<>();
        stringList.add("Alpha");
        stringList.set(0, "Beta");
        String element = stringList.get(0);
        stringList.remove(0);
        int listSize = stringList.size();
        
        // HashMap
        HashMap<String, Integer> scoreMap = new HashMap<>();
        scoreMap.put("Alice", 95);
        System.out.println(scoreMap.get("Alice")); // Prints 95
        scoreMap.remove("Alice");
        scoreMap.forEach((key, value) -> System.out.println(key + ": " + value));
        
        // Immutable List (Java 9+)
        List<String> immutableList = List.of("One", "Two", "Three");
        // Immutable Map (Java 9+)
        Map<String, String> immutableMap = Map.of("K1", "V1", "K2", "V2");
    }
}

Object-Oriented Programming: Constructors

A constructor is a special method invoked when an object is instantiated.

  • The constructor name must match the class name exactly.
  • It has no return type, not even void.
  • Its primary purpose is to initialize the object's member variables (fields).
  • A default no-argument constructor is provided automatically if no other constructors are defined.
  • Defining any constructor (e.g., a parameterized one) removes the default constructor. A no-argument constructor must then be explicitly written if needed.
  • Using constructors for initialization is more convenient then setting fields individually after object creation.

Object-Oriented Programming: Static Variables

Static variables (class variables) differ from instance variables.

  • A static variable belongs to the class itself, not to any specific object instance. Only one copy exists and is shared among all instances.
  • An instance variable belongs to an object; each object has its own separate copy.
  • Static variables are initialized when the class is loaded by the JVM. Instance variables are initialized when an object is created.
  • Static variables can be accessed directly via the class name (ClassName.variableName) or through an object reference, though the former is preferred.

Object-Oriented Programming: Static Methods

Static methods are associated with the class rather than instances.

  • Use static methods for functionality that does not depend on or manipulate instance data (e.g., utility functions).
  • A static method can access only static members (variables and methods) of the class. It cannot directly access instance members.
  • An instance method can access both static and instance members.
  • The this keyword cannot be used within a static method, as there is no current object instance.
  • Static methods cannot be overridden in the traditional sense; method hiding may occur.

Object-Oriented Programming: Inheritance

Inheritance allows a class too acquire the properties and behaviors of another class.

  • Java supports single inheritance for classes (a class can extend only one parent class).
  • A subclass inherits all non-private fields and methods from its superclass.
  • A subclass can override inherited methods to provide specific implementations.
  • If a subclass field or method has the same name as one in the superclasss, the superclass member can be accessed using the super keyword (e.g., super.methodName()).
  • When accessing a member, the JVM looks first in the subclass, then proceeds up the inheritance chain.

Object-Oriented Programming: Method Overriding

Overriding allows a subclass to provide a specific implementation of a method already defined in its superclass.

  • The overriding method's access modifier must be at least as permissive as the overridden method's (e.g., a protected method can be overridden as public but not as private).
  • The method signature (name, return type, and parameter list) must match exactly.
  • Methods declared as private, final, or static cannot be overridden.

Object-Oriented Programming: Constructor Chaining

When creating a subclass object, its constructor implicitly calls the superclass constructor first.

  • The call to the superclass constructor (super()) must be the first statement in a subclass constructor, if used.
  • The this() keyword can be used within a constructor to call another constructor in the same class (a "brother" constructor).
  • this() and super() cannot both be present in the same constructor, as each must be the first statement.

Object-Oriented Programming: Polymorphism

Polymorphism enables an object to take on many forms, typically through inheritance and method overriding.

  • Requirements: an inheritance hierarchy, method overriding, and a superclass reference pointing to a subclass object.
  • With a polymorphic reference, you cannot directly invoke methods that are unique to the subclass.
  • Method calls are resolved at runtime based on the actual object type (dynamic binding). The overridden version in the subclass is executed.
  • Field access is resolved at compile time based on the reference type. The field from the superclass is accessed.
  • To invoke a subclass-specific method, the reference can be cast to the subclass type.
  • Before performing a cast, use the instanceof operator to check the object's type to avoid ClassCastException.
class Human {
    String identity = "Human";
    void move() {
        System.out.println("Human moving...");
    }
}

class Pupil extends Human {
    String identity = "Pupil";
    @Override
    void move() {
        System.out.println("Pupil running...");
    }
    void study() {
        System.out.println("Pupil studying...");
    }
}

class Instructor extends Human {
    String identity = "Instructor";
    @Override
    void move() {
        System.out.println("Instructor walking...");
    }
    void teach() {
        System.out.println("Instructor teaching...");
    }
}
public class PolymorphismDemo {
    public static void main(String[] args) {
        Human ref1 = new Instructor();
        Human ref2 = new Pupil();
        
        ref1.move(); // Output: Instructor walking...
        ref2.move(); // Output: Pupil running...
        
        System.out.println(ref1.identity); // Output: Human (field from reference type)
        System.out.println(ref2.identity); // Output: Human
        
        // ref1.teach(); // Compile error: Cannot resolve method 'teach' in 'Human'
        
        Pupil pupilObj = new Pupil();
        // Casting
        Pupil anotherPupilRef = (Pupil) pupilObj;
        anotherPupilRef.study(); // Output: Pupil studying...
        
        // Type checking with instanceof
        if (ref1 instanceof Instructor) {
            Instructor instructorRef = (Instructor) ref1;
            instructorRef.teach(); // Output: Instructor teaching...
        }
    }
}

Interfaces

An interface defines a contract that implementing classes must fulfill.

  • Fields in an interface are implicitly public, static, and final (constants).
  • Methods declared in an interface are implicitly public and abstract (unless default or static).
  • Abstract methods in an interface cannot have a method body.
  • Interfaces cannot be instantiated directly.
  • A class implements an interface using the implements keyword.
  • A non-abstract class must provide concrete implementations for all abstract methods declared in the interface. Otherwise, the class itself must be declared abstract.

Interface Method Types

Modern Java interfaces support several method types:

  • default methods: Provide a default implementation. Implementing classes can override them.
  • private methods: Helper methods usable only within the interface itself.
  • static methods: Utility methods associated with the interface, callable via the interface name.
Tags: Java

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.