images
12/01/2021 06:34 am

Lập trình hướng đối tượng trong Java - Phần 1

Bài viết này sẽ giới thiệu đến bạn cách lập trình hướng đối tượng trong Java.



Class & Object


- Classes – là định nghĩa về các hàm (thủ tục), các thuộc tính với kiểu dữ liệu được xác định


- Objects – là thể hiện cụ thể của một class


Chúng ta có thể xem bảng ví dụ sau: Với Lớp Car, chúng ta có thể có thuộc tính là từng loại xe: BMW, TOYOTA. Tổng quát hoá, nếu ta coi People là lớp thì đối tượng thể hiện của lớp này là những con người cụ thể: Nam, Hoa


Class

Object

Car

BMW

TOYOTA

People

Nam

Hoa


Trong class của JAVA, có 2 thành phần chính:


- Thuộc tính: Một class có tập hợp các thuộc tính, nó nói lên tính chất của đối tượng.

Thuộc tính trong class được thể hiện là các biến.


- Phương thức: Là thành phần mô tả hành vi của đối tượng. Phương thức trong class chính là các method hay function.



Để khởi tạo một class, JAVA bắt buộc phải sử dụng một phương thức Khởi tạo: Constructor. Phương thức này có tên trùng với tên class. Mặc định thì JAVA luôn sinh ra một phương thức Constructor không có tham số, như dưới đây:



Nhưng nếu bạn khai báo một phương thức khởi tạo của riêng mình thì phương thức khởi tạo mặc định sẽ không tồn tại nữa.



Trường hợp trên, nếu ta có phương thức khởi tạo nhận đối số là name thì ta không thể khởi tạo Car theo cách cũ: new Car().  Bạn sẽ nhận thông báo lỗi khi viết khởi tạo như vậy.



Inheritance: Tính kế thừa


Tính kế thừa cho phép một class có thể kế thừa toàn bộ các thuộc tính của lớp cha. Trong lập trình OOP của Java, class chỉ được kế thừa duy nhất một lớp cha. Dưới đây là minh hoạ lớp ElectricCar là lớp Con kế thừa từ lớp Cha là Car.


class ElectricCar extends Car {



   public ElectricCar(String name) {

       super(name);

   }


   public void charge() {

       System.out.println("I'm charging");

   }


}


Car electricCar = new ElectricCar("Tesla")

electricCar.getName();


Trong trường hợp thừa kế này, phương thức khởi tạo lớp con phải gọi phương thức khởi tạo lớp cha. Bạn hãy nhìn vào phương thức khởi tạo ElectricCar, trong phương thức này ta sẽ phải gọi đến khởi tạo của lớp cha thông qua từ khóa super. Nếu bạn không viết như vậy, bạn sẽ nhận một lỗi về compile. Hãy xem thêm về super ở bên dưới.



Polymorphism


Tính đa hình hay là tính đa hình thái tức là một đối tượng có thể thể hiện dưới nhiều hình thái khác nhau. Ví dụ ta có loại Car và ElectricCar như dưới đây. 2 lớp này đều có phương thức là run. Do tính kế thừa nên ta có thể khai báo một danh sách các đối tượng Car() tuy nhiên danh sách này lại chứa các đối tượng thuộc 2 lớp khác nhau. Khi ta gọi đến phương thức run() thì tuỳ xem đó là đối tượng thuộc lớp nào thì phương thức gắn với lớp đó được chạy.

class Car {

   public void run() {

       System.out.println("I'm running");

   }

}


class ElectricCar extends Car {

   public void run() {

       System.out.println("I'm surfing!");

   }

}


List<Car> cars = new ArrayList<>();

cars.add(new Car(“bmw”));

cars.add(new ElectricCar(“tesla”));


for(Car car: cars) {

   car.run();

}


Kết quả: bạn nhận được 2 dòng:

I'm running

I'm surfing!



Abstraction


Tính trừu tượng: Khi ta khai báo phương thức cho một đối tượng, ví dụ với trường hợp của Car ta khai báo thêm phương thức khởi động start(). Thực tế khi start() thì đối tượng có thể có nhiều action khác nhau để hoàn thành việc start, tuy nhiên trong lập trình hướng đối tượng, các logic thuộc về nội tại của đối tượng thì sẽ không cần hiển thị đối với bên ngoài. Nếu như trong lập trình hàm, ta phải làm nhiều bước như: turnon(), ignition(),putMoreGas()... thì với lập trình hướng đối tượng, đứng ở vai trò là người sử dụng, ta chỉ quan tâm tới phương thức start() mà không cần quan tâm tới chi tiết bên trong.


class Car {

   public void start() {

       // turn on

       // Ignition

       // put more gas

      // Display monitor screen

   }


}


class ElectricCar extends Car {

   public void start() {

// turn on

         // Display monitor screen

    }

}



Encapsulation


Tính đóng gói và tính trừu tượng có liên hệ mật thiết với nhau. Tính đóng gói cho phép chúng ta ẩn đi các chi tiết nội tại của đối tượng và chỉ cung cấp ra bên ngoài các phương thức đặc trưng riêng của đối tượng đó để bên ngoài sử dụng. Do đó trong Java, khi muốn ẩn đi các phương thức nội tại, ta dùng từ khóa private, ngược lại khi muốn phương thức của đối tượng được sử dụng ở bên ngoài, ta sử dụng từ khóa public trước mỗi phương thức.


class Car {

   public void start() {

       // turn on

       // Ignition

       // put more gas

      // Display monitor screen

   }

   

   private void turnon() {

      System.out.println("I'm on");

  }


}

// We don’t care the private method, we don't know it



this and super


Từ khóa this để truy cập vào các thuộc tính của một object. Từ khóa super để truy cập vào thuộc tính cha của một object. 2 từ khóa này được sử dụng trong phạm vi của 1 class.

class Car {

   public void start() {

       System.out.println("Car is starting");

   }

}


class ElectricCar extends Car {

   public void start() {

       System.out.println("ElectricCar is starting");

   }

   public void  run() {

       super.start();

       this.start();

   }

}



Ví dụ trong đoạn code trên khi ta chạy method run(), ta sẽ gọi phương thức start() của đối tượng cha, sau đó gọi phương thức start() của chính đối tượng hiện tại. Kết quả là bạn có:


Car is starting

ElectricCar is starting


Các bảng dưới đây sẽ liệt kê các từ khoá đi kèm với phương thức và thuộc tính cho phép thay đổi các mức truy cập vào từng biến hoặc phương thức của đối tượng.



Access & Modifier class


Modifier

Mô tả

public

Class được truy cập từ bất kì đâu

default

Chỉ truy cập được trong cùng package



Properties, Methods, Constructors


Modifier

Description

public

Code được truy cập ở mọi nơi

private

Code chỉ được truy cập ở trong class đó

default

Được truy cập trong cùng Package

protected

Được truy cập trong cùng Package và ở các subclass


Lưu ý: Method override thì không thể thu hẹp modifier



Non-Access Modifier


Đây là các từ khoá đi kèm với thuộc tính hoặc phương thức nhưng không chịu trách nhiệm về việc kiểm soát truy cập.


Modifier

Description

final

Class không thể được mở rộng. Method không thể mở rộng

Biến không thể được thay đổi

abstract

Class không thể được khởi tạo, method chưa được cài đặt

static

Áp dụng cho thuộc tính hay phương thức, khi đó nó sẽ thuộc về class không phải thuộc về object

Kết hợp lại ta có:

public static final X = 5; //Khai báo hằng số.

transient

Biến không được lưu lại khi serialize object

synchronized

Tránh việc truy cập đồng thời khi có nhiều luồng cùng hoạt động (Đa luồng)

volatile

Giữ cho giá trị luôn được cập nhật khi sử dụng biến trong đa luồng



@Override


Là một annotation trong Java. Giúp cho compiler có thể dễ dàng kiểm tra việc override của 1 hàm là có hợp lệ hay không


class Car {

   public void run() {

       System.out.println("Car run ");

   }

}

class ElectricCar extends Car {

   @Override

   public void run(String name) {

       System.out.println("ElectricCar run ");

   }

}



Mời các bạn xem thêm bài Java Annotation


- Tech Zone -

Thư giãn chút nào!!!

Bài viết liên quan