Skip to content

Object the Cosmic Superclass

Info

Semua file yang ada pada contoh pada catatan ini ada pada package Ch5/J_5_2_Objects_The_Cosmic_Class

Class Objetcs adalah super parent dari semual class yang ada didalam Java. Namun kita tidak perlu menuliskan secara langsung extends pada class tersebut

Code

public class Employee extends Objects{
    ...
}

Karena semua class menurunkan dari class Objects, maka dari itu sangat penting bagi kita untuk mengetahui service yang diberikan oleh class ini.

Variable of Type Objects

Kita dapat menggunakan type object untuk merujuk (reference) ke objek apapun itu

Code

Object employee = new Employee("Farras",
                new BigDecimal(13_000_000), LocalDate.now());

Penggunaan type object hanya berguna sebagai penampungan umum (Generic holder) untuk nilai apapun. Untuk melakukan hal yang spesifik misalnya method pada sebauh class, kita harus mengetahui type asli dari object referencenya dan melakukan casting.

Code

package Ch5.J_5_2_Objects_The_Cosmic_Class;

import Ch5.J_5_1_Classes_Superclasses_Subclasses.Example1.Employee;

import java.math.BigDecimal;
import java.time.LocalDate;

public class J_1_Variable_Type_Objects {
    public static void main(String[] args) {
        Object employee = new Employee("Farras",
                new BigDecimal(13_000_000), LocalDate.now());

        System.out.println(employee);
        System.out.println();

        // cast to Employee if want getMethod in class Employee
        System.out.println(((Employee) employee).getName());
    }
}
Output
Name            : Farras
Salary          : 13,000,000.00
Hire Day        : 2023-08-20

Farras

The Equals Method

Method yang berada didalam object class berguna untuk menguji apakah object tersebut memilik refference yang sama dangen objek yang lainnya.

Code

public class J_2_The_Equals_Method {
    public static void main(String[] args) {

        Object employee1 = new Employee("Farras",new BigDecimal("9500000"), LocalDate.now());
        Object employee2 = new Employee("Farras",new BigDecimal("9500000"), LocalDate.now());
        Object copyOfEmployee1 = employee1;

        System.out.println(employee1.equals(employee2)); //false
        System.out.println(employee1.equals(copyOfEmployee1)); //true
        System.out.println(copyOfEmployee1.equals(employee1)); //true
    }
}

Terdapat 3 objek, employee1, employee2, dan copyOfEmployee1. Return value equals antara employee1 dan employee2 adalah false, walaupun pada saat membuat constructore kita memberikan nilai yang sama. Mengapa ? karena method equals pada class Object hanya mengabalikan nilai True jika objek memliki refference yang sama. Dibuktikan dengan penggunaan method equals antara employee1 dan copyOfEmployee1 yang mengembalikan nilai True karena refference keduanya adalah Identical.

Code

public boolean equals(Object obj) {
        return (this == obj);
    }

Selanjutnya mari kita putuskan, objek employee kita katakan sama jika memliki nama, gaji dan tanggal rekrutment yang sama. Mari kita override method equals pada class Employee.

Code

public class Employee{

    // ... Code dipotong

    @Override
    public boolean equals(Object obj) {


        // Return true, jelas identical
        if (this == obj) return true;

        // mengembalikan false jika eksplisti parameter bernilai null
        if (obj == null) return false;

        // Objek sama jikai class instancenya sama
        if (getClass() != obj.getClass()) return false;

        // sekarang kita tahu, explisti parameter bukan null

        // Casting explisit parameter ke Employee
        Employee eksplisitEmployee = (Employee) obj;

        // Membandingkan nilai dari field
        return this.getName().equals(eksplisitEmployee.getName())
                && this.getSalary().compareTo(eksplisitEmployee.getSalary()) == 0
                && this.getHireDay().isEqual(eksplisitEmployee.getHireDay());
    }
}

Sekarangkan jalankan kode yang sama saat membandingkan employee1, employee2, dan copyOfEmployee1. Terutama antaran employee1 dan employee2 akan mengembalikan nilai true dari yang sebelumnya false.

Equality Testing and Inheritance

Katakan, employee2 sekarang menjadi seorang manager, tidak ada perubahan termasuk gaji (hikss 😢), yang berubah hanya bonus. Apakah employee1 dan employee2 tetap mengambalikan nilai True ?

Jawabannya adalah tidak. Karena method equals yang telah kita override akan mengembalikan nilai false jika bukan dari class yang sama. Sedangkan class Employee dan class Manger berbeda. Banyak programmer menggunakan instance of ketika berhubungan dengan perbandingan antara instance dengan inheritance. Namun penggunan instanceof ini menjadi kontervesi.

if (!(obj instanceof Employee)) return false;

Kode diatas memungkina bawah objek obj adalah instance dari subclass Employee. Namun pendekatan tersebut bisa menjadi masalah. Mengapa ? Karena Java Langauage Specification mewajibkan method equals memiliki properties berikut;

  1. Reflexsive, untuk setiap non-null refferences, x, nilai x.equals(x) harus bernilai true.
  2. Symetri, untuk setipa non-null refferences, x dan y, jika nilai dari x.equals(y) benar, maka y.equals(x) harus benar pula.
  3. Transitive, untuk setiap non-null refferences, x, y dan z, jikai x.equals(y) benar, y.equals(z) benar, maka x.equals(z) harus benar pula.
  4. Consistent, selama tidak ada perubahan antara instance yang diuji, maka kembalian method equals harus selalu sama.
  5. untuk setiap non-null refferences, x, x.equals(null) selalu bernilai salah.

Code

public class J_2_The_Equals_Method_2 {
    public static void main(String[] args) {

        Employee employee1 = new Employee("Farras",new BigDecimal("9500000"), LocalDate.now());
        Manager employee2 = new Manager("Farras",new BigDecimal("9500000"), LocalDate.now());
        employee2.setBonus(new BigDecimal("1000000"));

        System.out.println(employee1.equals(employee2)); //false
        System.out.println(employee2.equals(employee1)); //true
        // this equals method doesn't symmetric
    }
}
public class Manager extends Employee {
    // Dipotong

    @Override
    public boolean equals(Object obj) {

        // jika null tetap false
        if (obj == null) return false;


        if (obj instanceof Employee) return true;

        Manager manager = (Manager) obj;

        return this.getName().equals(manager.getName())
                && this.getSalary().compareTo(manager.getSalary()) == 0
                && this.getHireDay().isEqual(manager.getHireDay());
    }
}