01/10/2018, 09:02

Quan hệ HAS-A trong java

Hi all. Mình vừa học java đến phần quan hệ HAS-A trong java hay còn gọi là Java Composition. Mình có đọc nhưng không hiểu về quan hệ HAS-A trong java này lắm. Theo mình được biết thì quan hệ này có nghĩa là nếu có 2 lớp A và B và lớp B chỉ sử dụng một phần code của lớp A(phương thức, thuộc tính) mà không sửa đổi gì về nội dung của lớp A thì gọi là Composition. Dùng tính năng này để tăng tính tái sử dụng lại code. Mình có thể hiểu tới đây nhưng không hiểu nó sử dụng lại như thế nào.Mình có tham khảo 3 bài tập nhưng khi code lại ko chạy. Các bạn giúp mình nhé.

//Khai báo class job

package com.techmaster.composition;

public class Job {
private String role;
private long salary;
private int id;
    
public String getRole() {
    return role;
}
public void setRole(String role) {
    this.role = role;
}
public long getSalary() {
    return salary;
}
public void setSalary(long salary) {
    this.salary = salary;
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
   }

//Khai báo class person

package com.techmaster.composition;

public class Person {

//COMPOSITION cho mối quan hệ người có-một việc ( has - a)
private Job job;

public Person(){
    this.job=new Job();
    job.setSalary(1000L);
}
public long getSalary() {
    return job.getSalary();
}

}

//Khai báo hàm main

package com.techmaster.composition;

public class TestPerson {

public static void main(String[] args) {
    Person person = new Person();

long salary = person.getSalary();//Khi thực thi dòng này bị lỗi không chạy được. 
 }
 }

Vậy trong 3 bài tập trên tính năng Compostion được sử dụng như thế nào vậy. Mong các bạn chỉ giúp

Nguyen Ca viết 11:16 ngày 01/10/2018

Nhin code thì chạy được chứ nhỉ

Bao Trung Tran viết 11:04 ngày 01/10/2018

long salary = person.getSalary();

Khong chay duoc ban oi. Dong nay bi loi long salary = person.getSalary();. No bao ko tim thay bien getSalary

Bao Trung Tran viết 11:07 ngày 01/10/2018

Mình fix được rồi nhưng cho mình hỏi là trong ví dụ trên tính has-a được sử dụng ntn vậy. Thank all

Tâm Ninja viết 11:13 ngày 01/10/2018

Hi all. Mình vừa học java đến phần quan hệ HAS-A trong java hay còn gọi là Java Composition. Mình có đọc nhưng không hiểu về quan hệ HAS-A trong java này lắm. Theo mình được biết thì quan hệ này có nghĩa là nếu có 2 lớp A và B và lớp B chỉ sử dụng một phần code của lớp A(phương thức, thuộc tính) mà không sửa đổi gì về nội dung của lớp A thì gọi là Composition. Dùng tính năng này để tăng tính tái sử dụng lại code. Mình có thể hiểu tới đây nhưng không hiểu nó sử dụng lại như thế nào.Mình có tham khảo 3 bài tập nhưng khi code lại ko chạy. Các bạn giúp mình nhé.

Cần sửa lại bài tập hay cần hiểu về composition? Nếu cần sửa bài chắc phải nhờ bạn khác còn nếu cần hiểu thì:

Java Composition được hiểu là dạng quan hệ has-a (Phân biệt với is-a/inheritance) theo đó thì một class A được coi là compostition với class B khi trong khai báo B chứa A (hay nói cách khác là A thuộc về B) Điều này phân biệt với associaion khi mà associaion là mối quan hệ B sử dụng A (tức A nằm trong B nhưng chỉ được gọi thông qua phương thức không phải khai báo) thông qua cách gọi b.a với binstance của class B còn ainstance của class A.
Composition có hai dạng là Composition (quả trám đen) và Aggregation (quả trám trắng). Với Composition thì A được khởi tạo từ bên trong của B. Nên khi B bị hủy thì A cũng đồng thời bị hủy. Còn với Aggregation thì A được truyền vào B từ bên ngoài hay nói cách khác là thuộc tính của B đang tham chiếu đến 1 thực thể ở bên ngoài. Nên khi B bị hủy thì A vẫn tồn tại.

Nếu giải thích như trên thì có vẻ đầy đủ nhưng lại khó hiểu. Vậy từ code Java thể hiện của AB như sau:

###Asociasion:

class B {
    void method(A a) {
        a.doSomeThing();
    }
}

###Composition:

class B {
    A a;
    B() {
        a = new A();
    }
}

###Aggregation:

class B {
    A a;
    B(A a) {
        this.a = a;
    }
}

hoặc
class B {
    A a;
    setA(A a) {
        this.a = a;
    }
}
hoặc
class B {
    A a;
    method(A a) {
        this.a = a;
    }
}

Bài trên thì Person chứa Job, Job là một phần của Person, được khai báo trong Person và được khởi tạo trong Person nên nó là quan hệ Job composition Person.

Bao Trung Tran viết 11:12 ngày 01/10/2018

thank bạn nhé. Code mình fix được rồi

Tynk Huynk viết 11:07 ngày 01/10/2018

Nói chung là 1 class mà có biến instance thuộc kiểu class khác thì gọi là composition đúng ko bạn ?

Phan Hoàng viết 11:17 ngày 01/10/2018

@TamNinja trả lời khá ok rồi. Mình xin bổ sung thêm 1 chút nếu đứng dưới góc độ database và business logic nhé.

Đa phần ai cũng hiểu quan hệ has-a là quan hệ sở hữu, tuy nhiên has-a cũng có thể sử dụng là quen hệ thuộc về. Mình lấy ví dụ trong database có quan hệ 1-n giữa Teacher và Student (1 giáo viên có nhiều sinh viên theo học). CÓ 4 cách thiết kế has-a như sau

  • Nested Object
Teacher {
   Student[] students;
}
  • Denomalize: ngược với nested
class Student {
   Teacher teacher;
}
  • Parent-child: như nested, nhưng thay vì mảng Student[], mình embed int[] students;

  • Side-join: như denomalize, thay vì Teacher, mình embed int teacherId

Việc truyền data thì thực chất là có 4 kiểu association:
1- Temp association: như ví dụ đầu tiên, B chỉ dùng tạm A (value) trong 1 function.
2- Composition association: A là bộ phận cấu thành của B, không có không được.
3- Aggregration association: A được inject vào B qua constructor. B sử dụng object A (chứ không phải value) và nếu B bị phá huỷ thì A vẫn tồn tại và lại có thể inject vào thằng B’. Cái này còn được gọi là quan hệ yếu.
4- Direct association: A được inject vào B qua method. Không nhất thiết B cần A luôn (vì method này đâu phải lúc nào cũng cần)

Đa phần mọi người hay sử dụng Aggregration vì 2 class sẽ không phụ thuộc vào nhau quá nhiều (DI). Việc làm test cũng dễ dàng hơn khi fix cứng như kiểu Composition. Ngoài ra, việc thiết kế class kiểu Composition/Aggregration cũng linh hoạt hơn trong việc build object (so với Inheritance)

class TonNgoKhong {
   TinhNguoi nguoi;
   TinhKhi khi;
   DanhYeu killer;
}

ví dụ với TonNgoKhong, nó sẽ được cấu thành từ 3 bộ phận: Tính người (nói chuyện, học võ, …), Tính khỉ (hiếu động, kêu khẹt khẹt), … và Đánh yêu (giết). Giả sử mình cần thêm TruBatGioi, mình sẽ dùng chung được 2 bộ phận:

class TruBatGioi {
   TinhNguoi nguoi;
   TinhLon lon;
   DanhYeu killer;
}

(Decorator là design thể hiện rõ nhất về composition / aggregration)

Tâm Ninja viết 11:10 ngày 01/10/2018

Nói chung là 1 class mà có biến instance thuộc kiểu class khác thì gọi là composition đúng ko bạn ?

Mới đúng 1 nửa vì không có từ dùng chung dành cho trạng thái đó.

Nói chung là 1 class mà có biến instance thuộc kiểu class khác thì khi class nằm trong được khởi tạo bên trong class chứa nó thì mối quan hệ đó gọi là composition đúng ko bạn ?

Tynk Huynk viết 11:06 ngày 01/10/2018

Hay quá, mấy cái trên có phải thuộc về Design Pattern vậy ạ ? Tại em mới đọc cuốn Head First Design Pattern và trong sách có nói sơ về phần này

Nguyen Ca viết 11:17 ngày 01/10/2018

Thực ra khi hoc UML cũng nói về mối quan hệ này

Bài liên quan
0