Kế thừa trong Java

Trong bài viết này kynangcntt.info sẽ giới thiệu tới các bạn một khái niệm quan trọng trong lập trình hướng đối tượng là kế thừa.

Kế thừa là hình thức định nghĩa một lớp mới trên cơ sở một lớp có sẵn. Kế thừa là mối quan hệ giữa một lớp với các lớp khác định nghĩa dựa trên nó nên nó định nghĩa mối quan hệ “là một” giữa các loại dữ liệu.

Lớp có sẵn được gọi là super class và lớp mới được tạo ra dựa trên lớp có sẵn đó gọi là sub class.

Định nghĩa kế thừa:

Để khai báo kế thừa chúng ta sử dụng từ khóa extends theo cú pháp sau:

class <Tên lớp> extends <Tên lớp cha>{

//  Thân lớp

}

Trong đó: <Tên lớp>  là tên của lớp đang được cài đặt, <Tên lớp cha>là tên của lớp được dẫn xuất hay còn gọi là lớp cha.

Từ khóa super: đại diện cho super class của lớp hiện tại.

Hàm khởi tạo của lớp con: lời gọi hàm khởi tạo của lớp cha phải được chèn vào dòng đầu tiên trong hàm khởi tạo của lớp con. Quá trình thực hiện các hàm khởi tạo tuân theo nguyên tắc từ trên xuống trong cấu trúc phân cấp thừa kế.

Ví dụ minh họa: Một công ty được giao nhiệm vụ quản lý các phương tiện giao thông gồm các loại: ô tô, xe máy, xe tải.

Mỗi loại phương tiện giao thông cần quản lý: hãng sản xuất, năm sản xuất, giá bán, màu.

Ngoài ra, ô tô cần quản lý thêm kiểu động cơ, số chỗ ngỗi. Xe máy cần quản lý thêm công suất và xe tải cần quản lý thêm trọng tải.

Các anh chị hãy xây dựng lớp XeTai, Xe May, OTo kế thừa lớp PTGT.

Xây dựng các hàm để truy nhập, hiển thị và kiểm tra các thuộc tính của lớp.

Xây dựng lớp quản lý phương tiện giao thông để thực hiện các chức năng: nhập và xuất danh sách phương tiện giao thông, tìm phương tiện giao thông theo màu, ….

HƯỚNG DẪN

Trước hết chúng ta tạo lớp PTGT như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package kynangcntt.info;
/**
 *
 * @author kynangcntt.info
 */
public class PTGT {
    private String hangSX,namSX,giaBan,mau;
    public PTGT() {
    }
    public PTGT(String hangSX, String namSX, String giaBan, String mau) {
        this.hangSX = hangSX;
        this.namSX = namSX;
        this.giaBan = giaBan;
        this.mau = mau;
    }
    public String getHangSX() {
        return hangSX;
    }
    public void setHangSX(String hangSX) {
        this.hangSX = hangSX;
    }
    public String getNamSX() {
        return namSX;
    }
    public void setNamSX(String namSX) {
        this.namSX = namSX;
    }
    public String getGiaBan() {
        return giaBan;
    }
    public void setGiaBan(String giaBan) {
        this.giaBan = giaBan;
    }
    public String getMau() {
        return mau;
    }
    public void setMau(String mau) {
        this.mau = mau;
    }
}

Tiếp đến chúng ta tạo lớp OTo như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package kynangcntt.info;
/**
 *
 * @author kynangcntt.info
 */
public class OTo extends PTGT{
    private String dongCo,soChoNgoi;
    public OTo() {
    }
    public OTo(String dongCo, String soChoNgoi, String hangSX, String namSX, String giaBan, String mau) {
        super(hangSX, namSX, giaBan, mau);
        this.dongCo = dongCo;
        this.soChoNgoi = soChoNgoi;
    }
    public String getDongCo() {
        return dongCo;
    }
    public void setDongCo(String dongCo) {
        this.dongCo = dongCo;
    }
    public String getSoChoNgoi() {
        return soChoNgoi;
    }
    public void setSoChoNgoi(String soChoNgoi) {
        this.soChoNgoi = soChoNgoi;
    }   
}

Tiếp đến tạo lớp XeMay như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package kynangcntt.info;
/**
 *
 * @author kynangcntt.info
 */
public class XeMay extends PTGT{
    private String congSuat;
    public XeMay() {
    }
    public XeMay(String congSuat, String hangSX, String namSX, String giaBan, String mau) {
        super(hangSX, namSX, giaBan, mau);
        this.congSuat = congSuat;
    }
    public String getCongSuat() {
        return congSuat;
    }
    public void setCongSuat(String congSuat) {
        this.congSuat = congSuat;
    }
}

Rồi tạo lớp XeTai như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package khamphacntt.com.vn;
/**
 *
 * @author khamphacntt.com.vn
 */
public class XeTai extends PTGT{
    private String trongTai;
    public XeTai() {
    }
    public XeTai(String trongTai, String hangSX, String namSX, String giaBan, String mau) {
        super(hangSX, namSX, giaBan, mau);
        this.trongTai = trongTai;
    }
    public String getTrongTai() {
        return trongTai;
    }
    public void setTrongTai(String trongTai) {
        this.trongTai = trongTai;
    }      
}

Cuối cùng chúng ta tạo lớp QuanLy để thực hiện các chức năng chính của chương trình:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package kynangcntt.info;
import java.util.ArrayList;
import java.util.Scanner;
/**
 *
 * @author kynangcntt.info
 */
public class QuanLy {
    private ArrayList<PTGT> pTGTs;
    private Scanner reader;
    public QuanLy() {
        pTGTs = new ArrayList<>();
        reader = new Scanner(System.in);
    }
    
    private OTo taoOTo(){
        OTo oTo = new OTo();
        System.out.println("Hãng sản xuất:");
        oTo.setHangSX(reader.nextLine());
        System.out.println("Năm sản xuất:");
        oTo.setNamSX(reader.nextLine());
        System.out.println("Giá bán:");
        oTo.setGiaBan(reader.nextLine());
        System.out.println("Màu:");
        oTo.setMau(reader.nextLine());
        System.out.println("Động cơ:");
        oTo.setDongCo(reader.nextLine());
        System.out.println("Số chỗ ngồi:");
        oTo.setSoChoNgoi(reader.nextLine());
        return oTo;
    }
    private XeMay taoXeMay(){
        XeMay xeMay = new XeMay();
        System.out.println("Hãng sản xuất:");
        xeMay.setHangSX(reader.nextLine());
        System.out.println("Năm sản xuất:");
        xeMay.setNamSX(reader.nextLine());
        System.out.println("Giá bán:");
        xeMay.setGiaBan(reader.nextLine());
        System.out.println("Màu:");
        xeMay.setMau(reader.nextLine());
        System.out.println("Công suất:");
        xeMay.setCongSuat(reader.nextLine());       
        return xeMay;
    }
    
    private XeTai taoXeTai(){
        XeTai xeTai = new XeTai();
        System.out.println("Hãng sản xuất:");
        xeTai.setHangSX(reader.nextLine());
        System.out.println("Năm sản xuất:");
        xeTai.setNamSX(reader.nextLine());
        System.out.println("Giá bán:");
        xeTai.setGiaBan(reader.nextLine());
        System.out.println("Màu:");
        xeTai.setMau(reader.nextLine());
        System.out.println("Trọng tải:");
        xeTai.setTrongTai(reader.nextLine());       
        return xeTai;
    }
    
    private void hienThiThongTin(PTGT ptgt){
        System.out.println("Hãng sản xuất: " + ptgt.getHangSX());
        System.out.println("Năm sản xuất: " + ptgt.getNamSX());
        System.out.println("Giá bán: " + ptgt.getGiaBan());
        System.out.println("Màu: " + ptgt.getMau());
        
        if (ptgt instanceof OTo) {
            OTo oTo = (OTo) ptgt;
            System.out.println("Động cơ: " + oTo.getDongCo());
            System.out.println("Số chỗ ngồi: " + oTo.getSoChoNgoi());
        }else{
            if (ptgt instanceof XeMay) {
                XeMay xeMay = (XeMay) ptgt;
                System.out.println("Công suất: " + xeMay.getCongSuat());
            }else{
                XeTai xeTai = (XeTai) ptgt;
                System.out.println("Trọng tải:" + xeTai.getTrongTai());
            }
        }
    }
    
    public void nhapDanhSachPTGT(){
        System.out.println("Nhập 1 - Tạo mới ô tô");
        System.out.println("Nhập 2 - Tạo mới xe máy");
        System.out.println("Nhập 3 - Tạo mới xe tải");
        System.out.println("Nhập 4 - Kết thúc nhâp");
        int giaTriDuocChon;
        
        do {           
            System.out.println("Bạn chọn: ");
            giaTriDuocChon= Integer.parseInt(reader.nextLine());
            
            switch(giaTriDuocChon){
                case 1:
                    pTGTs.add(taoOTo());
                    break;
                case 2:
                    pTGTs.add(taoXeMay());
                    break;
                case 3:
                    pTGTs.add(taoXeTai());
                    break;
            }
        } while (giaTriDuocChon!=4);       
    }
    
    public void xuatThongTin(){
        for (PTGT ptgt : pTGTs) {
            hienThiThongTin(ptgt);
        }
    }
    
    public static void main(String[] args) {
        QuanLy quanLy = new QuanLy();
        quanLy.nhapDanhSachPTGT();
        quanLy.xuatThongTin();
    }
}

Các bạn hãy bổ sung thêm một số tính năng:

  1. Hãy liệt kê danh sách phương tiện giao thông theo loại được chỉ định bởi người sử dụng.
  2. Liệt kê danh sách các phương tiên giao thông theo hãng sản xuất được chỉ định bởi người sử dụng.
  3. Liệt kê danh sách phương tiện giao thông theo màu chỉ định bởi người sử dụng.
  4. Liệt kê danh sách phương tiện giao thông có giá bán nhỏ nhất.
  5. Liệt kê danh sách phương tiện giao thông có giá bán lớn nhất.
  6. Liệt kê danh sách phương tiện giao thông có giá bán nhỏ nhất của hãng được chỉ định theo loại phương tiện được chỉ định.

Gợi ý code câu b. Liệt kê danh sách phương tiện giao thông theo hãng được chỉ định:

1
2
3
4
5
6
7
publicvoidxuatThongTinTheoHang(String hangSX){
    for(PTGT ptgt : pTGTs) {
        if(ptgt.getHangSX().equalsIgnoreCase(hangSX)) {
            hienThiThongTin(ptgt);
        }
    }
}

Bài tiếp theo : Bài tập về Kế thừa trong Java