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
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
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());
}
}
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.
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.
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;
- Reflexsive, untuk setiap non-null refferences,
x
, nilaix.equals(x)
harus bernilaitrue
. - Symetri, untuk setipa non-null refferences,
x
dany
, jika nilai darix.equals(y)
benar, makay.equals(x)
harus benar pula. - Transitive, untuk setiap non-null refferences,
x
,y
danz
, jikaix.equals(y)
benar,y.equals(z)
benar, makax.equals(z)
harus benar pula. - Consistent, selama tidak ada perubahan antara instance yang diuji, maka kembalian method
equals
harus selalu sama. - 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());
}
}