Trọng tâm của OOP
là khuynh hướng đối tượng hóa tất cả các thành phần trong chương trình mà chúng ta xây dựng, để các yếu tố này có khả năng đóng vai trò như các chủ thể hành động và tương tác với nhau tạo ra logic hoạt động mà chúng ta mong muốn cho ứng dụng.
objectA.doSomethingTo (objectB)
Vì vậy nên chúng ta có công cụ khởi đầu là class
- hỗ trợ định nghĩa mô phỏng tổng quan cho các Object
cùng dạng thiết kế và giảm thiểu code lặp. Trong JavaScript
, thường thì chúng ta chỉ sử dụng class
khi muốn tạo ra các Object
có chức năng giống nhau nhưng lại có các thuộc tính đặc tả khác nhau, ví dụ như các Object
mô phỏng người dùng trong cùng một ứng dụng; Còn trong Java
, việc sử dụng class
là điều bắt buộc để khởi tạo một Object
bất kỳ.
Class Members
Các thành phần có mặt trong một class
bất kỳ trong Java
cũng có thể được chia thành hai nhóm căn bản như JavaScript
là:
static
- thuộc vềobject
duy nhất đại biểu choclass
, và có thể được tham chiếu từ tênclass
.instance (non-static)
- thuộc về cácobject
cụ thể được tạo ra từ phép thực thinew
, và có thể được tham chiếu từ các biến lưu trữ địa chỉ của cácobject
này.
package app; import java.io.*; class Person { // -- instance members String name = ""; int age = 0; Person ( String $name, int $age ) { this.name = $name; this.age = $age; // -- Person.countInstance (); } void greet (Person $someone) { System.out.println ("Hello, " + $someone.name + " !"); System.out.println ("I'm " + this.name + ", " + this.age + " years old."); } // -- static members static int instanceCounter = 0; static { System.out.println ("static constructor"); } static void countInstance () { Person.instanceCounter += 1; System.out.println ("Created " + Person.instanceCounter + " instance(s)."); } } // -- end class
Ở đây chúng ta có class Person
mô phỏng các thực thể người với khả năng thực hiện hành động chào hỏi greet()
, và các thành phần static
hỗ trợ theo dõi số lượng object
đã được tạo ra từ class
này. Điểm đáng lưu ý duy nhất so với những kiến thức mà chúng ta đã có trước đó là các trình khởi tạo của Java
không có tên phương thức và trình khởi tạo instance
phải có thông tin định kiểu dữ liệu trả về tương tự như các phương thức khác.
Tại trình khởi chạy main
, chúng ta sẽ tạo ra hai instance
từ class Person
và chạy thử tương tác greet()
:
package app; class Main { public static void main (String[] args) { Person $me = new Person ("Semi Dev_", 1001); Person $anotherMe = new Person ("The Yogi", 1001); // -- $anotherMe.greet ($me); } } // -- end class
Bây giờ chúng ta mở cửa sổ dòng lệnh và cd
chuyển thư mục làm việc tới learn-java
, cập nhật danh sách các tệp mã nguồn vào src.txt
, chạy lệnh bên dịch, và sau đó chạy ứng dụng.
cd learn-java
... > src.txt
javac @src.txt
java app.Main
Kết quả vận hành:
static constructor
Created 1 instance(s).
Created 2 instance(s).
Hello, Semi Dev_ !
I'm The Yogi, 1001 years old.
Thao tác cập nhật danh sách các tệp mã nguồn vàosrc.txt
sẽ chỉ cần thiết khi chúng ta tạo ra thêm tệp code .java
mới. Còn việc chạy lệnh biên dịch lại bộ mã nguồn mỗi khi chỉnh sửa code ví dụ thì chắc chắn là luôn luôn cần thiết. Mình sẽ mặc định là bạn đã quen với các thao tác này và chỉ copy/paste
kết quả vận hành của code vào các bài viết kể từ thời điểm này trở đi.
Inheritance
Tính năng kế thừa inheritance
được sử dụng với mục đích giảm thiểu lượng code phải viết lặp lại khi chúng ta cần định nghĩa nhiều class
có điểm chung. Chẳng hạn từ class Person
chúng ta có thể tận dụng code này để tạo ra các class
mở rộng là Worker
và Teacher
.
package app; class Worker
extends Person { int stamina = 0; Worker ( String $name, int $age, int $stamina ) { super ($name, $age); this.stamina = $stamina; } } // -- end Worker
Trong code của các class
mở rộng, để tham chiếu tới class
ban đầu thì chúng ta sử dụng con trỏ super
giống như JavaScript
. Ở đây chúng ta sẽ định nghĩa lại phương thức greet()
cho class Teacher
để mở rộng tính năng.
package app; import java.io.*; class Teacher
extends Person { int intellect = 0; Teacher ( String $name, int $age, int $intellect ) { super ($name, $age); this.intellect = $intellect; } void greet (Person $someone) { super.greet ($someone); System.out.println ("I'm a yoga teacher."); } } // -- end class
Và code sử dụng tại main
:
package app; class Main { public static void main (String[] $args) { Worker $me = new Worker ("Semi Dev_", 1001, 9); Teacher $anotherMe = new Teacher ("The Yogi", 1001, 9); // -- $anotherMe.greet ($me); } } // -- end class
Kết quả vận hành:
static constructor
Created 1 instance(s).
Created 2 instance(s).
Hello, Semi Dev_ !
I'm The Yogi, 1001 years old.
I'm a yoga teacher.
Về căn bản thì các class
mở rộng sẽ được mặc định kế thừa lại toàn bộ tài nguyên đã được định nghĩa từ class super
ban đầu. Tuy nhiên, chúng ta cũng còn những công cụ khác nữa để tùy chỉnh logic kế thừa sẽ được nói đến trong bài viết tiếp theo.
(chưa đăng tải) [Object-Oriented + Java] Bài viết #3 - Access Modifiers & Encapsulation