Recent Posts

Thừa kế và đa hình trong lập trình Java

-

1- Giới thiệu 

Thừa kế và đa hình - đây là 1 khái niệm cực kỳ quan trọng trong  lập trình Java. Mà bạn bắt buộc phải hiểu nó.

2- Class, đối tượng và cấu tử 


Bạn cần hiểu 1 phương pháp rạch ròi về class, cấu tử và đối tượng trước khi bắt đầu mua hiểu quan hệ thừa kế trong java. Chúng ta xem class Person, mô tả 1 con người với các thông tin tên, năm sinh, năm mất.
  • Person.java
?
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
packageorg.o7planning.tutorial.inheritance.basic;

publicclassPerson {

   // Trường name - thông tin tên người
   privateString name;
   // Trường bornYear - thông tin năm sinh
   privateInteger bornYear;
   // Trường diedYear - thông tin năm mất
   privateInteger diedYear;

   // Cấu tử 3 tham số. Mục đích nhằm để khởi tạo các giá trị cho các trường
   // của Person.Chỉ định rõ tên, năm sinh, năm mất của 1 người.
   publicPerson(String name, Integer bornYear, Integer diedYear) {
       this.name = name;
       this.bornYear = bornYear;
       this.diedYear = diedYear;
   }

   // Cấu tử 2 tham số. Mục đích khởi tạo giá trị cho 2 trường tên và năm sinh
   // cho Person. Năm mất không được khởi tạo, nghĩa là người đang còn sống.
   publicPerson(String name, Integer bornYear) {
       this.name = name;
       this.bornYear = bornYear;
   }

   publicString getName() {
       returnname;
   }

   publicvoidsetName(String name) {
       this.name = name;
   }

   publicInteger getBornYear() {
       returnbornYear;
   }

   publicvoidsetBornYear(Integer bornYear) {
       this.bornYear = bornYear;
   }

   publicInteger getDiedYear() {
       returndiedYear;
   }

   publicvoidsetDiedYear(Integer diedYear) {
       this.diedYear = diedYear;
   }
}
  • PersonDemo.java
?
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
packageorg.o7planning.tutorial.inheritance.basic;

publicclassPersonDemo {

   publicstaticvoidmain(String[] args) {

       // Đối tượng: Thomas Edison.
       Person edison = newPerson("Thomas Edison", 1847, 1931);

       System.out.println("Info:");
       System.out.println("Name: "+ edison.getName());
       System.out.println("Born Year: "+ edison.getBornYear());
       System.out.println("Died Year: "+ edison.getDiedYear());

       // Đối tượng: Bill Gates
       Person billGates = newPerson("Bill Gate", 1955);

       System.out.println("Info:");
       System.out.println("Name: "+ billGates.getName());
       System.out.println("Born Year: "+ billGates.getBornYear());
       System.out.println("Died Year: "+ billGates.getDiedYear());

   }

}

Phân biệt Class, cấu tử và đối tượng:

Class Person mô phỏng 1 lớp người, nó là 1 thiết bị gì ấy trìu tượng, nhưng nó sở hữu các trường để sở hữu thông tin, trong ví dụ trên là tên, năm sinh, năm mất.

Cấu tử - Người ta còn gọi là "Hàm khởi tạo"

  • Cấu tử luôn sở hữu tên giống tên class
  • 1 class sở hữu 1 hoặc phổ biến cấu tử.
  • Cấu tử với hoặc không có tham số, cấu tử không sở hữu tham số còn gọi là cấu tử mặc định.
  • Cấu tử là cách để tạo ra 1 đối tượng của class.
Như vậy Person (Mô tả lớp người) là vật dụng trìu tượng, nhưng khi chỉ rõ vào bạn hoặc tôi thì đó là 2 đối tượng thuộc lớp người. Và cấu tử là thiết bị tạo ra đối tượng, cấu tử sẽ gán các giá trị của các trường trong class.

Hãy xem minh họa, khởi tạo đối tượng từ cấu tử như thế nào.

3- Thừa kế trong java 

Chúng ta phải 1 vài class tham gia vào minh họa.
  • Animal: Class mô phỏng 1 lớp Động vật.
  • Duck: Class mô phỏng lớp vịt, là 1 class con của Animal.
  • Cat: Class mô phỏng lớp mèo, là 1 class con của Animal
  • Mouse: Class mô phỏng lớp chuột, là 1 class con của Animal.
Thừa kế và đa hình trong lập trình Java

Ở đây chúng ta có class Animal, có 1 method không sở hữu nội dung.
  • public abstract String getAnimalName();
Method này là 1 method trìu tượng (abstract), tại các class con nên nên khai báo và triển khai nội dung của nó. Method này sở hữu ý nghĩa là trả về tên loài động vật.
Class Animal có 1 hàm trìu tượng nó cũng buộc phải được khai báo là trìu tượng (abstract). Class trìu tượng với các cấu tử nhưng bạn không thể khởi tạo đối tượng từ nó.

  • Về bản chất nghĩa là bạn muốn tạo 1 đối tượng động vật, bạn nên tạo từ 1 loại đông vật cụ thể, trong ví như này bạn cần khởi tạo từ cấu tử của CatMouse hoặc Duck.
  • Animal.java
?
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
packageorg.o7planning.tutorial.inheritance.animal;

// Class với ít nhất 1 method trìu tượng nên khai báo là trìu tượng.
publicabstractclassAnimal {

  // Tên, ví dụ Mèo Tom, Chuột Jerry.
  privateString name;

  // Cấu tử mặc định
  publicAnimal() {
      // Gán tên mặc định
      this.name = this.getAnimalName();
  }

  publicAnimal(String name) {
      this.name = name;
  }

  publicString getName() {
      returnname;
  }

  publicvoidsetName(String name) {
      this.name = name;
  }

  // Trả về tên của loài động vật này.
  // 1 method trìu tượng.
  // Nội dung cụ thể của method này được viết tại class con.
  publicabstractString getAnimalName();

}

Tiếp theo xem class Cat, thừa kế từ Animal.

Cat cũng có các cấu tử của nó, và cũng sở hữu {các|những} trường của nó. Trong loại trước tiên của cấu tử bao giờ cũng phải gọi super(..) nghĩa là gọi lên cấu tử cha, để khởi tạo giá trị cho {các|những} trường của class cha. ví như bạn {không|ko} gọi mặc định Java hiểu là đã gọi super(), nghĩa là gọi cấu tử mặc định của class cha.
  • Cat.java
?
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
packageorg.o7planning.tutorial.inheritance.animal;

publicclassCat extendsAnimal {

  privateintage;
  privateintheight;

  publicCat(intage, intheight) {
      // Gọi {đến|tới} cấu tử mặc định của class cha (Animal)
      // Nhằm mục đích khởi tạo {các|những} trường trên class cha.
      super();
      // Sau {đó|ấy|đấy} mới {đến|tới} việc khởi tạo giá trị cho {các|những} trường của nó
      this.age = age;
      this.height = height;
  }

  publicCat(String name, intage, intheight) {
      // Gọi {đến|tới} cấu tử của class cha (Animal)
      // Nhằm mục đích khởi tạo {các|những} trường trên class cha.
      super(name);
      // Sau {đó|ấy|đấy} mới {đến|tới} việc khởi tạo giá trị cho {các|những} trường của nó
      this.age = age;
      this.height = height;
  }

  publicintgetAge() {
      returnage;
  }

  publicvoidsetAge(intage) {
      this.age = age;
  }

  publicintgetHeight() {
      returnheight;
  }

  publicvoidsetHeight(intheight) {
      this.height = height;
  }

  // Triển khai nội dung cho method trìu tượng khai báo tại class cha.
  @Override
  publicString getAnimalName() {
      return"Cat";
  }

}

khi bạn khởi tạo 1 đối tượng Cat điều gì xẩy ra?

Xem class Mouse, thừa kế từ Animal.

  • Mouse.java
?
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
packageorg.o7planning.tutorial.inheritance.animal;

publicclassMouse extendsAnimal {

  privateintweight;

  // Cấu tử mặc định
  publicMouse() {
      // Gọi {đến|tới} cấu tử Mouse(int)
      this(100);
  }

  // Cấu tử 1 tham số
  publicMouse(intweight) {
      // Tại đây {không|ko} gọi super
      // Mặc định java hiểu gọi {đến|tới} cấu tử mặc định của class cha.
      this.weight = weight;
  }

  // Cấu tử 2 tham số
  publicMouse(String name, intweight) {
      super(name);
      this.weight = weight;
  }

  publicintgetWeight() {
      returnweight;
  }

  publicvoidsetWeight(intweight) {
      this.weight = weight;
  }

  @Override
  publicString getAnimalName() {
      return"Mouse";
  }
}
  • InstanceofDemo.java
?
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
packageorg.o7planning.tutorial.inheritance.demo;

importorg.o7planning.tutorial.inheritance.animal.Animal;
importorg.o7planning.tutorial.inheritance.animal.Cat;
importorg.o7planning.tutorial.inheritance.animal.Mouse;

publicclassInstanceofDemo {

  publicstaticvoidmain(String[] args) {

      // Khởi tạo 1 đối tượng động vật.
      // Animal là class trìu tượng
      // nó {không|ko} thể tạo đối tượng từ cấu tử của nó.
      Animal tom = newCat("Tom", 3, 20);

      System.out.println("name: "+ tom.getName());
      System.out.println("animalName: "+ tom.getAnimalName());

      // {sử dụng|tiêu dùng|dùng} toán tử instanceof để kiểm tra xem
      // 1 đối tượng {với|có|sở hữu|mang} {phải|cần|nên|buộc phải|bắt buộc} kiểu nào {đó|ấy|đấy} không.

      booleanisMouse = tom instanceofMouse;
      System.out.println("Tom is mouse? "+ isMouse);

      booleanisCat = tom instanceofCat;
      System.out.println("Tom is cat? "+ isCat);

      booleanisAnimal = tom instanceofAnimal;
      System.out.println("Tom is animal? "+ isAnimal);

  }

}
Kết quả chạy ví dụ:
  • InheritMethodDemo.java
?
{1|một}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
packageorg.o7planning.tutorial.inheritance.demo;

importorg.o7planning.tutorial.inheritance.animal.Cat;

publicclassInheritMethodDemo {

   publicstaticvoidmain(String[] args) {

       // Tạo {1|một} đối tượng Cat
       Cat tom = newCat("Tom", 3, 20);
        
        
       // Gọi {các|những} method thừa kế được từ class cha.
       System.out.println("name: "+ tom.getName());
       System.out.println("animalName: "+ tom.getAnimalName());
        
       System.out.println("-----------------");

       // Gọi {các|những} method khai báo trên class Cat.
       System.out.println("Age: "+ tom.getAge());
       System.out.println("Height: "+ tom.getHeight());
   }

}
Kết quả chạy ví dụ:

Ép kiểu (Cast) trong Java

  • CastDemo.java
?
{1|một}
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
packageorg.o7planning.tutorial.inheritance.demo;

importjava.util.Random;

importorg.o7planning.tutorial.inheritance.animal.Animal;
importorg.o7planning.tutorial.inheritance.animal.Cat;
importorg.o7planning.tutorial.inheritance.animal.Mouse;

publicclassCastDemo {

   // Method trả về {ngẫu nhiên|tự nhiên|tự dưng|trùng hợp|khi không} {1|một} con vật.
   publicstaticAnimal getRandomAnimal() {
       // Trả về giá trị {ngẫu nhiên|tự nhiên|tự dưng|trùng hợp|khi không} 0,1
       intrandom = newRandom().nextInt(2);

       Animal animal = null;
       if(random == 0) {
           animal = newCat("Tom", 3, 20);
       } else{
           animal = newMouse("Jerry", 5);
       }
       returnanimal;
   }

   publicstaticvoidmain(String[] args) {

       Animal animal = getRandomAnimal();

       if(animal instanceofCat) {
           // Ép kiểu về Cat.
           Cat cat = (Cat) animal;

           // Và gọi method của class Cat.
           System.out.println("Cat height: "+ cat.getHeight());
       } elseif(animal instanceofMouse) {
           // Ép kiểu về Mouse
           Mouse mouse = (Mouse) animal;

           // Và gọi method của class Mouse.
           System.out.println("Mouse weight: "+ mouse.getWeight());
       }

   }

}

4- Tính đa hình trong Java 

Class AsianCat là {1|một} class thừa kế từ Cat.
  • AsianCat.java
?
{1|một}
2
3
4
5
6
7
8
9
10
11
12
13
14
packageorg.o7planning.tutorial.inheritance.animal;

publicclassAsianCat extendsCat {

   publicAsianCat(String name, intage, intheight) {
       super(name, age, height);
   }

   // Ghi đè method của class cha (Cat)
   @Override
   publicString getAnimalName() {
       return"Asian Cat";
   }
}
Tính đa hình của Java được gói gọi trong hình minh họa dưới đây:
  • PolymorphismDemo.java
?
{1|một}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
packageorg.o7planning.tutorial.polymorphism;

importorg.o7planning.tutorial.inheritance.animal.AsianCat;
importorg.o7planning.tutorial.inheritance.animal.Cat;

publicclassPolymorphismDemo {

   publicstaticvoidmain(String[] args) {

       Cat cat1 = newCat("Tom", 3, 20);

       Cat cat2 = newAsianCat("ATom", 2, 19);

       System.out.println("Animal Name of cat1: "+ cat1.getAnimalName());

       System.out.println("Animal Name of cat2: "+ cat2.getAnimalName());

   }

}
Kết quả chạy ví dụ:




Klik untuk melihat kode: :) =( :s :D :-D ^:D ^o^ 7:( :Q :p T_T @@, :-a :W *fck* x@