Arrays of Objects, Methods Overloading and Encapsulation

Arrays of Objects

  • Arrays of objects are created similarly to arrays of primitive data types.
  • Base_Type refers to a class type.
  • Java arrays of objects are lists of reference variables holding addresses of individual objects.
  • Creating an array of objects in Java does not create instances of those objects.

Creating an Array of Objects - Example

  • Each element in progStudents is an object.

  • "null" indicates that elements of progStudents[] (objects) have not been created yet.

  • You cannot access progStudents[0] if it is null.

  • For arrays of objects, each object must be created separately for each element in the array.

  • Step 1: Declare a Student array variable.

  • Step 2: Create new Student objects and assign them to array elements using:

    arrayName[index] = new classConstructor(argument list);
    

Accessing Elements in Array of Objects

  • You can directly access any element using its index but must specify which instance variable to change.

  • Example:

    public class Student {
        public String name;
        public long id;
        public String year;
    public Student(String sName, long sID, String sYear) {
        this.name = sName;
        this.id = sID;
        this.year = sYear;
    }
    
    public static void main(String[] args) {
        Student[] progStudents = new Student[10];
        progStudents[0] = new Student("Ali", 123456789, "Freshman");
        progStudents[1] = new Student("Ahmad", 127457293, "Freshman");
    
        progStudents[0].name = "Mohammad";
        progStudents[0].id = 0;
        progStudents[0].year = "Freshman";
    }
    
    }
  • You can also use loop statements for accessing elements.

  • Example:

    public class Student {
        public String name;
        public long id;
        public String year;
    public Student(String sName, long sID, String sYear) {
        this.name = sName;
        this.id = sID;
        this.year = sYear;
    }
    
    public void displayStudentInfo() {
        System.out.print("Name: " + this.name + ", ID: " + this.id + " Year: " + this.year);
    }
    
    public static void main(String[] args) {
        Student[] progStudents = new Student[10];
        progStudents[0] = new Student("Ali", 123456789, "Freshman");
    
        for (int i = 0; i < progStudents.length; i++) {
            if (progStudents[i] != null)
                progStudents[i].displayStudentInfo();
        }
    }
    
    }

Method Overloading

  • Method overloading occurs when two or more methods have the same name within the same class.

  • Java distinguishes overloaded methods by the number, order, and types of parameters.

  • A method's name, number, and type of parameters constitute its signature.

  • Example:

    public class Overload {
        public static void main(String[] args) {
            double average1 = Overload.getAverage(40.0, 50.0);
            double average2 = Overload.getAverage(1.0, 2.0, 3.0);
            char average3 = Overload.getAverage('a', 'c');
        System.out.println("average1 = " + average1);
        System.out.println("average2 = " + average2);
        System.out.println("average3 = " + average3);
    }
    
    public static double getAverage(double first, double second) {
        return (first + second) / 2.0;
    }
    
    public static double getAverage(double first, double second, double third) {
        return (first + second + third) / 3.0;
    }
    
    public static char getAverage(char first, char second) {
        return (char) (((int) first + (int) second) / 2);
    }
    
    }

    Sample screen output:

    average1 = 45.0
    average2 = 2.0
    average3 = b
    
  • Example 2 Methods with Different Number of Parameters:

    public class TestMethodOverloading {
        public static void main(String[] args) {
            System.out.println("The maximum between 3 and 4 is " + max(3, 4));
            System.out.println("The maximum between 3.0 and 5.4 is " + max(3.0, 5.4));
            System.out.println("The maximum between 3.0, 5.4, and 10.14 is "
                    + max(3.0, 5.4, 10.14));
        }
    /** Return the max between two int values */
    public static int max(int num1, int num2) {
        if (num1 > num2)
            return num1;
        else
            return num2;
    }
    
    /** Find the max between two double values */
    public static double max(double num1, double num2) {
        if (num1 > num2)
            return num1;
        else
            return num2;
    }
    
    /** Return the max among three double values */
    public static double max(double num1, double num2, double num3) {
        return max(max(num1, num2), num3);
    }
    
    }

Ambiguous Invocation

  • Ambiguous invocation occurs when there are two or more possible matches for a method invocation, but the compiler cannot determine the most specific match, resulting in a compilation error.

  • Example:

    public class AmbiguousOverloading {
        public static void main(String[] args) {
            System.out.println(max(1, 2));
        }
    public static double max(int num1, double num2) {
        if (num1 > num2)
            return num1;
        else
            return num2;
    }
    
    public static double max(double num1, int num2) {
        if (num1 > num2)
            return num1;
        else
            return num2;
    }
    
    }

Overloading and Return Type

  • You cannot overload a method based solely on the return type.
  • Methods with the same signature but different return types are illegal.

Encapsulation

  • Encapsulation is wrapping data (variables) and methods into a single unit (class).
  • It is also known as "Data hiding" because it protects data prone to change.
  • It involves making class fields (variables) private and providing access through public methods.
  • Variables of a class are hidden from other classes and can be accessed only through the methods of their current class.

Data Hiding vs. Encapsulation

FeatureEncapsulationData Hiding
DefinitionBinding data members and methods in a class.Declaring data variables as private.
FocusHiding the complexity of the system.Ensuring data security.
AccessProvided through public gettersProtect data which is prone to change
GoalBind data members and methods togetherSecure data from unauthorized access
  • Example:

    public class Feel {
        private int posRow;
        private int posColumn;
    public void setNewPos(int newRow, int newColumn) {
        if (validate(newRow, newColumn)) {
            posRow = newRow;
            posColumn = newColumn;
        }
    }
    
    public boolean validate(int newRow, int newColumn) {
        // check if the new position is available, return true otherwise false
        return true; // Placeholder
    }
    
    public static void main(String[] args) {
        int newRow = 0;
        int newColumn = 2;
        Feel feel = new Feel();
        feel.setNewPos(newRow, newColumn);
    }
    
    }

Set and Get Methods

  • Set and Get methods are a data encapsulation pattern allowing controlled access to class data.

  • Instead of directly accessing class variables, you define getter and setter methods.

  • Get and set methods of the current class can be used to access its variables from another class.

  • Setters/Mutators: Methods that modify a class’s fields.

    • Use setters to validate data before changing the object state.
  • Getters/Accessors: Methods that access fields but do not modify them; they return information about the state of an object.

    • Use getters to format data before returning the object’s state.
  • Set methods have a void return type.

  • Get methods have a specified return type.

  • Commonly, a field has two associated methods: a mutator for setting the value and an accessor for getting the value, typically with names starting with set or get.

  • Example:

    public class Person {
        private int age;
    public void setAge(int a) {
        // validate here
        if (age > 0 && age < 180)
            age = a;
    }
    
    public int getAge() {
        // format here
        return age;
    }
    
    }

Summary

  • Arrays can be of a class type, where each element is an object of that class.
  • Arrays of class types can be passed by reference to methods.
  • Methods can return arrays of objects.
  • Methods with the same name but different signatures are overloaded methods.
  • A well-encapsulated class has all its instance variables private and includes public getters and setters for each instance variable.