Công Nghệ Thông Tin, it, phầm mềm, website, web, mobile app, trí tuệ nhân tạo, blockchain, AI, machine learning - Công Nghệ Thông Tin, it, phầm mềm, website, web, mobile app, trí tuệ nhân tạo, blockchain, AI, machine learning - Lập trình Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 1 Bài thực hành 03: Lập trình hướng đối tượng với Java (OOP with Java) -------------------------------------------- NỘI DUNG: Thừa kế và đa hình trong Java .................................................................................................................. 2 1- Giới thiệu .......................................................................................................................................... 2 2- Class, cấu tử và đối tượng (Class, Constructor, instance) ................................................................ 2 3- Thừa kế trong java ............................................................................................................................ 5 4- Tính đa hình trong Java .................................................................................................................. 12 Abstract class và Interface trong Java ..................................................................................................... 15 1- Giới thiệu ........................................................................................................................................ 15 2- Class trừu tượng (Abstract Class) ................................................................................................... 15 3- Ví dụ với lớp trừu tượng ................................................................................................................. 16 4- Tổng quan về Interface ................................................................................................................... 19 5- Cấu trúc của một Interface.............................................................................................................. 20 6- Class thực hiện Interface ................................................................................................................ 22 Access modifier trong Java ..................................................................................................................... 26 1- Modifier trong Java ........................................................................................................................ 26 2- Tổng quan về access modifier ........................................................................................................ 26 3- private access modifier ................................................................................................................... 26 4- private constructor .......................................................................................................................... 27 5- Access modifier mặc định .............................................................................................................. 28 6- protected access modifier ............................................................................................................... 30 7- public access modifier .................................................................................................................... 30 8- Ghi đè phương thức ........................................................................................................................ 31 ------------------------------------------- Xem thêm tài liệu khác TẠI ĐÂY ------------------------------------------- Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 2 Thừa kế và đa hình trong Java 1- Giới thiệu Thừa kế và đa hình (Inheritance polymorphism) - đây là một khái niệm vô cùng quan trọng trong Java. Mà bạn bắt buộc phải hiểu nó. 2- Class, cấu tử và đối tượng (Class, Constructor, instance) Bạn cần hiểu một cách rạch ròi về class, cấu tử (constructor) và đối tượng trước khi bắt đầu tìm hiểu quan hệ thừa kế trong java. Chúng ta xem class Person, mô tả một con người với các thông tin tên, năm sinh, nơi sinh. 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 package org.o7planning.tutorial.inheritance.basic; public class Person { Trường name - Thông tin tên người. private String name; Trường bornYear - thông tin năm sinh private Integer bornYear; Trường placeOfBirth - thông tin nơi sinh. private String placeOfBirth; Constructor có 3 tham số. Mục đích nhằm để gán các giá trị cho các trường của Person. Chỉ định rõ tên, năm sinh, nơi sinh của một người. public Person(String name, Integer bornYear, String placeOfBirth) { this.name = name; this.bornYear = bornYear; this.placeOfBirth = placeOfBirth; } Constructor có 2 tham số. Mục đích gán các giá trị cho 2 trường tên và năm sinh cho Person. Nơi sinh không được gán. public Person(String name, Integer bornYear) { this.name = name; this.bornYear = bornYear; } public String getName() { return name; } Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 3 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 public void setName(String name) { this.name = name; } public Integer getBornYear() { return bornYear; } public void setBornYear(Integer bornYear) { this.bornYear = bornYear; } public String getPlaceOfBirth() { return placeOfBirth; } public void setPlaceOfBirth(String placeOfBirth) { this.placeOfBirth = placeOfBirth; } } PersonDemo.java ? 1 2 3 package org.o7planning.tutorial.inheritance.basic; public class PersonDemo { Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 4 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public static void main(String args) { Đối tượng: Thomas Edison. Person edison = new Person("Thomas Edison", 1847); System.out.println("Info:"); System.out.println("Name: " + edison.getName()); System.out.println("Born Year: " + edison.getBornYear()); System.out.println("Place Of Birth: " + edison.getPlaceOfBirth() ); Đối tượng: Bill Gates Person billGates = new Person("Bill Gate", 1955, "Seattle, Washington"); System.out.println("Info:"); System.out.println("Name: " + billGates.getName()); System.out.println("Born Year: " + billGates.getBornYear()); System.out.println("Place Of Birth: " + billGates.getPlaceOfBirth()); } } Phân biệt Class, cấu tử (constructor) và đối tượng: Lớp Person mô phỏng một lớp người, nó là một thứ gì đó trừu tượng, nhưng nó có các trường để mang thông tin, trong ví dụ trên là tên, năm sinh, nơi sinh. Cấu tử (Constructor) - Người ta còn gọi là "Phương thức khởi tạo" Cấu tử luôn có tên giống tên lớp. Một class có một hoặc nhiều cấu tử. Cấu tử có hoặc không có tham số, cấu tử không có tham số còn gọi là cấu tử mặc định. Cấu tử được sử dụng để tạo ra một đối tượng của lớp. Như vậy lớp Person (Mô tả lớp người) là thứ trừu tượng, nhưng khi chỉ rõ vào bạn hoặc tôi thì đó là 2 đối tượng (instance) thuộc lớp Person. Và Constructor là phương thức đặc biệt để tạo ra đối tượng, Constructor sẽ gán các giá trị vào các trường (field) của class cho đối tượng.. Hãy xem minh họa, khởi tạo đối tượng từ cấu tử như thế nào. Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 5 3- Thừa kế trong java Chúng ta cần một vài class tham gia vào minh họa. Animal: Class mô phỏng một lớp Động vật. Duck: Class mô phỏng lớp vịt, là một class con của Animal. Cat: Class mô phỏng lớp mèo, là một class con của Animal Mouse: Class mô phỏng lớp chuột, là một class con của Animal. Ở đây chúng ta có class Animal, với một method không có nội dung. public abstract String getAnimalName(); Method này là một method trừu tượng (abstract), tại các class con cần phải khai báo và triển khai nội dung của nó. Method này có ý nghĩa là trả về tên loài động vật. Class Animal có 1 phương thức trừu tượng nó phải được khai báo là trìu tượng (abstract). Class trừu tượng có các cấu tử (constructor) 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 một đối tượng động vật, bạn cần tạo từ một loại đông vật cụ thể, trong trường hợp này bạn phải khởi tạo từ cấu tử (constructor) của Cat, Mouse hoặc Duck. Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 6 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 33 34 package org.o7planning.tutorial.inheritance.animal; Lớp có ít nhất 1 phương thức trừu tượng bắt buộc phải được khai báo là trừu tượng. public abstract class Animal { Tên, ví dụ Mèo Tom, Chuột Jerry. private String name; Constructor mặc định. public Animal() { Gán giá trị mặc định cho ''''name''''. this.name = this.getAnimalName(); } public Animal(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } Đây là một phương thức trừu tượng. Trả về tên của loài động vật này. Nội dung cụ thể của phương thức này sẽ được thực hiện (implemented) tại các lớp con. public abstract String 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 có các trường của nó. Trong dòng đầu 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 trường của class cha. Nếu bạn không 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 package org.o7planning.tutorial.inheritance.animal; public class Cat extends Animal { Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 7 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 private int age; private int height; public Cat(int age, int height) { Gọi tới Constructor mặc định của lớp cha (Animal). Nhằm mục đích gán tạo giá trị cho các trường (field) của lớp cha. super(); Sau đó mới gán giá trị cho các trường (field) của nó. this.age = age; this.height = height; } public Cat(String name, int age, int height) { Gọi tới Constructor của lớp cha (Animal) Nhằm mục đích gán tạo giá trị cho các trường (field) của lớp cha. super(name); Sau đó mới gán giá trị cho các trường (field) của nó. this.age = age; this.height = height; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } Thực hiện (implement) phương thức trừu tượng được khai báo tại lớp cha. Override public String getAnimalName() { return "Cat"; } } Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 8 Khi bạn khởi tạo một đố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 package org.o7planning.tutorial.inheritance.animal; public class Mouse extends Animal { private int weight; Constructor mặc định. public Mouse() { Gọi tới cấu tử Mouse(int) Call to constructor Mouse(int) this(100); } Constructor có 1 tham số public Mouse(int weight) { Nếu bạn không gọi bất kỳ một super(..) nào. Java sẽ gọi một super() mặc định. super(); this.weight = weight; } Constructor có 2 tham số. public Mouse(String name, int weight) { super(name); this.weight = weight; } public int getWeight() { return weight; } Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 9 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public void setWeight(int weight) { this.weight = weight; } Override public String 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 package org.o7planning.tutorial.inheritance.demo; import org.o7planning.tutorial.inheritance.animal.Animal; import org.o7planning.tutorial.inheritance.animal.Cat; import org.o7planning.tutorial.inheritance.animal.Mouse; public class InstanceofDemo { public static void main(String args) { Khởi tạo một đối tượng động vật. Animal là một lớp trừu tượng, bạn không thể tạo ra một đối tượng từ Constructor của Animal. Animal tom = new Cat("Tom", 3, 20); System.out.println("name: " + tom.getName()); System.out.println("animalName: " + tom.getAnimalName()); Sử dụng toán tử ''''instanceof'''' để kiểm tra xem một đối tượng có phải là một kiểu nào đó hay không. boolean isMouse = tom instanceof Mouse; System.out.println("Tom is mouse? " + isMouse); boolean isCat = tom instanceof Cat; System.out.println("Tom is cat? " + isCat); boolean isAnimal = tom instanceof Animal; System.out.println("Tom is animal? " + isAnimal); } } Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 10 30 31 32 Kết quả chạy ví dụ: ? 1 2 3 4 5 name: Tom animalName: Cat Tom is mouse? false Tom is cat? true Tom is animal? true InheritMethodDemo.java ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package org.o7planning.tutorial.inheritance.demo; import org.o7planning.tutorial.inheritance.animal.Cat; public class InheritMethodDemo { public static void main(String args) { Tạo một đối tượng Cat. Cat tom = new Cat("Tom", 3, 20); Gọi các phương thức thừa kế được từ lớp cha (Animal). System.out.println("name: " + tom.getName()); System.out.println("animalName: " + tom.getAnimalName()); System.out.println("-----------------"); Gọi các phương thức được khai báo trên lớp Cat. System.out.println("Age: " + tom.getAge()); System.out.println("Height: " + tom.getHeight()); } } Kết quả chạy ví dụ: ? Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 11 1 2 3 4 5 name: Tom animalName: Cat ----------------- Age: 3 Height: 20 Ép kiểu (Cast) trong Java CastDemo.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 package org.o7planning.tutorial.inheritance.demo; import java.util.Random; import org.o7planning.tutorial.inheritance.animal.Animal; import org.o7planning.tutorial.inheritance.animal.Cat; import org.o7planning.tutorial.inheritance.animal.Mouse; public class CastDemo { Phương thức này trả về ngẫu nhiên một con vật. public static Animal getRandomAnimal() { Trả về giá trị ngẫu nhiên 0 hoặc 1. int random = new Random().nextInt(2); Animal animal = null; if (random == 0) { animal = new Cat("Tom", 3, 20); } else { animal = new Mouse("Jerry", 5); } return animal; } public static void main(String args) { Animal animal = getRandomAnimal(); if (animal instanceof Cat) { Ép kiểu (cast) thành kiểu Cat. Cat cat = (Cat) animal; Và gọi một phương thức của lớp Cat. System.out.println("Cat height: " + cat.getHeight()); } else if (animal instanceof Mouse) { Ép kiểu (cast) thành kiểu Mouse. Mouse mouse = (Mouse) animal; Và gọi một phương thức của lớp Mouse. System.out.println("Mouse weight: " + mouse.getWeight()); } } Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 12 38 39 40 41 42 43 44 45 } 4- Tính đa hình trong Java Bạn có một con mèo nguồn gốc châu Á (AsianCat), bạn có thể nói nó là một con mèo (Cat) hoặc nói nó là một con vật (Animal) đó là một khía cạnh của từ đa hình. Hoặc một ví dụ khác: Trên lý lịch của bạn ghi rằng bạn là một người châu Á, trong khi đó bạn thực tế là một người Việt Nam. Ví dụ dưới đây cho bạn thấy cách hành sử giữa khai báo và thực tế Class AsianCat là một class thừa kế từ Cat AsianCat.java ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package org.o7planning.tutorial.inheritance.animal; public class AsianCat extends Cat { public AsianCat(String name, int age, int height) { super(name, age, height); } Ghi đè (override) phương thức của lớp cha (Cat) Override public String getAnimalName() { return "Asian Cat"; } } Tính đa hình của Java được giải thích trong hình minh họa dưới đây: Tự học lập trình với https:lap-trinh-may-tinh.blogspot.com TỰ HỌC LẬP TRÌNH JAVA 13 PolymorphismDemo.java ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package org.o7planning.tutorial.polymorphism; import org.o7planning.tutorial.inheritance.animal.AsianCat; impor...
Giới thiệu
Thừa kế và đa hình (Inheritance & polymorphism) - đây là một khái niệm vô cùng quan trọng trong
Java Mà bạn bắt buộc phải hiểu nó.
Class, cấu tử và đối tượng (Class, Constructor, instance)
Bạn cần hiểu một cách rạch ròi về class, cấu tử (constructor) và đối tượng trước khi bắt đầu tìm hiểu quan hệ thừa kế trong java Chúng ta xem class Person, mô tả một con người với các thông tin tên, năm sinh, nơi sinh
27 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 placeOfBirth - thông tin nơi sinh. privateString placeOfBirth;
// Mục đích nhằm để gán các giá trị cho các trường của Person.
// Chỉ định rõ tên, năm sinh, nơi sinh của một người. publicPerson(String name, Integer bornYear, String placeOfBirth) { this.name = name; this.bornYear = bornYear; this.placeOfBirth = placeOfBirth;
// Mục đích gán các giá trị cho 2 trường tên và năm sinh cho Person.
// Nơi sinh không được gán. publicPerson(String name, Integer bornYear) { this.name = name; this.bornYear = bornYear;
52 publicvoidsetName(String name) { this.name = name;
} publicvoidsetBornYear(Integer bornYear) { this.bornYear = bornYear;
} publicvoidsetPlaceOfBirth(String placeOfBirth) { this.placeOfBirth = placeOfBirth;
3 packageorg.o7planning.tutorial.inheritance.basic; publicclassPersonDemo {
Person edison = newPerson("Thomas Edison", 1847);
System.out.println("Name: "+ edison.getName());
System.out.println("Born Year: "+ edison.getBornYear());
System.out.println("Place Of Birth: "+ edison.getPlaceOfBirth() );
Person billGates = newPerson("Bill Gate", 1955, "Seattle, Washington");
System.out.println("Name: "+ billGates.getName());
System.out.println("Born Year: "+ billGates.getBornYear());
System.out.println("Place Of Birth: "+ billGates.getPlaceOfBirth());
Phân biệt Class, cấu tử (constructor) và đối tượng:
Lớp Person mô phỏng một lớp người, nó là một thứ gì đó trừu tượng, nhưng nó có các trường để mang thông tin, trong ví dụ trên là tên, năm sinh, nơi sinh
Cấu tử (Constructor) - Người ta còn gọi là "Phương thức khởi tạo"
• Cấu tử luôn có tên giống tên lớp
• Một class có một hoặc nhiều cấu tử
• Cấu tử có hoặc không có tham số, cấu tử không có tham số còn gọi là cấu tử mặc định
• Cấu tử được sử dụng để tạo ra một đối tượng của lớp
Như vậy lớp Person (Mô tả lớp người) là thứ trừu tượng, nhưng khi chỉ rõ vào bạn hoặc tôi thì đó là 2 đối tượng (instance) thuộc lớp Person Và Constructor là phương thức đặc biệt để tạo ra đối tượng,
Constructor sẽ gán các giá trị vào các trường (field) của class cho đối tượng
Hãy xem minh họa, khởi tạo đối tượng từ cấu tử như thế nào.
Thừa kế trong java
Chúng ta cần một vài class tham gia vào minh họa
• Animal: Class mô phỏng một lớp Động vật
• Duck: Class mô phỏng lớp vịt, là một class con của Animal
• Cat: Class mô phỏng lớp mèo, là một class con của Animal
• Mouse: Class mô phỏng lớp chuột, là một class con của Animal Ở đây chúng ta có class Animal, với một method không có nội dung
Method này là một method trừu tượng (abstract), tại các class con cần phải khai báo và triển khai nội dung của nó Method này có ý nghĩa là trả về tên loài động vật
Class Animal có 1 phương thức trừu tượng nó phải được khai báo là trìu tượng (abstract) Class trừu tượng có các cấu tử (constructor) 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 một đối tượng động vật, bạn cần tạo từ một loại đông vật cụ thể, trong trường hợp này bạn phải khởi tạo từ cấu tử (constructor) của Cat, Mouse hoặc Duck
34 packageorg.o7planning.tutorial.inheritance.animal;
// Lớp có ít nhất 1 phương thức trừu tượng
// bắt buộc phải được khai báo là trừu tượng. publicabstractclassAnimal {
// Tên, ví dụ Mèo Tom, Chuột Jerry. privateString name;
// Gán giá trị mặc định cho 'name'. this.name = this.getAnimalName();
} publicAnimal(String name) { this.name = name;
} publicvoidsetName(String name) { this.name = name;
// Đây là một phương thức trừu tượng.
// Trả về tên của loài động vật này.
// Nội dung cụ thể của phương thức này
// sẽ được thực hiện (implemented) tại các lớp 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 có các trường của nó Trong dòng đầu 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 trường của class cha
Nếu bạn không 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
2 packageorg.o7planning.tutorial.inheritance.animal; publicclassCat extendsAnimal {
48 privateintage; privateintheight; publicCat(intage, intheight) {
// Gọi tới Constructor mặc định của lớp cha (Animal).
// Nhằm mục đích gán tạo giá trị cho các trường (field) của lớp cha. super();
// Sau đó mới gán giá trị cho các trường (field) của nó. this.age = age; this.height = height;
} publicCat(String name, intage, intheight) {
// Gọi tới Constructor của lớp cha (Animal)
// Nhằm mục đích gán tạo giá trị cho các trường (field) của lớp cha. super(name);
// Sau đó mới gán giá trị cho các trường (field) của nó. this.age = age; this.height = height;
} publicvoidsetAge(intage) { this.age = age;
} publicvoidsetHeight(intheight) { this.height = height;
// Thực hiện (implement) phương thức trừu tượng được khai báo tại lớp cha.
@Override publicString getAnimalName() { return"Cat";
Khi bạn khởi tạo một đối tượng Cat điều gì xẩy ra?
Xem class Mouse, thừa kế từ Animal
26 packageorg.o7planning.tutorial.inheritance.animal; publicclassMouse extendsAnimal { privateintweight;
// Gọi tới cấu tử Mouse(int)
// Call to constructor Mouse(int) this(100);
// Constructor có 1 tham số publicMouse(intweight) {
// Nếu bạn không gọi bất kỳ một super( ) nào.
// Java sẽ gọi một super() mặc định.
// Constructor có 2 tham số. publicMouse(String name, intweight) { super(name); this.weight = weight;
40 publicvoidsetWeight(intweight) { this.weight = weight;
@Override publicString getAnimalName() { return"Mouse";
29 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 một đối tượng động vật.
// Animal là một lớp trừu tượng,
// bạn không thể tạo ra một đối tượng từ Constructor của Animal.
System.out.println("name: "+ tom.getName());
System.out.println("animalName: "+ tom.getAnimalName());
// Sử dụng toán tử 'instanceof' để kiểm tra xem
// một đối tượng có phải là một kiểu nào đó hay 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ụ:
23 packageorg.o7planning.tutorial.inheritance.demo; importorg.o7planning.tutorial.inheritance.animal.Cat; publicclassInheritMethodDemo { publicstaticvoidmain(String[] args) {
// Tạo một đối tượng Cat.
// Gọi các phương thức thừa kế được từ lớp cha (Animal).
System.out.println("name: "+ tom.getName());
System.out.println("animalName: "+ tom.getAnimalName());
// Gọi các phương thức được khai báo trên lớp Cat.
System.out.println("Age: "+ tom.getAge());
System.out.println("Height: "+ tom.getHeight());
Kết quả chạy ví dụ:
Height: 20 Ép kiểu (Cast) trong Java
37 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 {
// Phương thức này trả về ngẫu nhiên một con vật. publicstaticAnimal getRandomAnimal() {
// Trả về giá trị ngẫu nhiên 0 hoặc 1. intrandom = newRandom().nextInt(2);
Animal animal = null; if(random == 0) { animal = newCat("Tom", 3, 20);
Animal animal = getRandomAnimal(); if(animal instanceofCat) {
// Ép kiểu (cast) thành kiểu Cat.
// Và gọi một phương thức của lớp Cat.
System.out.println("Cat height: "+ cat.getHeight());
// Ép kiểu (cast) thành kiểu Mouse.
// Và gọi một phương thức của lớp Mouse.
System.out.println("Mouse weight: "+ mouse.getWeight());
Tính đa hình trong Java
Bạn có một con mèo nguồn gốc châu Á (AsianCat), bạn có thể nói nó là một con mèo (Cat) hoặc nói nó là một con vật (Animal) đó là một khía cạnh của từ đa hình
Hoặc một ví dụ khác: Trên lý lịch của bạn ghi rằng bạn là một người châu Á, trong khi đó bạn thực tế là một người Việt Nam
Ví dụ dưới đây cho bạn thấy cách hành sử giữa khai báo và thực tế
Class AsianCat là một class thừa kế từ Cat
14 packageorg.o7planning.tutorial.inheritance.animal; publicclassAsianCat extendsCat { publicAsianCat(String name, intage, intheight) { super(name, age, height);
// Ghi đè (override) phương thức của lớp cha (Cat)
@Override publicString getAnimalName() { return"Asian Cat";
Tính đa hình của Java được giải thích trong hình minh họa dưới đây:
20 packageorg.o7planning.tutorial.polymorphism; importorg.o7planning.tutorial.inheritance.animal.AsianCat; importorg.o7planning.tutorial.inheritance.animal.Cat; publicclassPolymorphismDemo { publicstaticvoidmain(String[] args) {
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ụ:
Animal Name of cat1: Cat
Animal Name of cat2: Asian Cat
Abstract class và Interface trong Java
Trong tài liệu hướng dẫn này tôi sẽ hướng dẫn về Interface và class trừu tượng (Abstract Class) Đồng thời phân tích sự giống và khác nhau giữa chúng.
Class trừu tượng (Abstract Class)
Abstract class (Class trừu tượng) Hãy xem ví dụ về một class như thế:
// Đây là một lớp trừu tượng.
// Nó bắt buộc phải khai báo là abstract
// vì trong nó có một phương thức trừu tượng publicabstractclassClassA {
// Đây là một phương thức trừu tượng.
// Nó không có thân (body).
// Access modifier của phương thức này là public. publicabstractvoiddoSomething();
// Access modifier của phương thức này là protected. protectedabstractString doNothing();
// Phương thức này không khai báo access modifier.
// Access modifier của nó là mặc định. abstractvoidtodo() ;
// Đây là một lớp trừu tượng.
// Nó được khai báo là abstract,
// mặc dù nó không có phương thức trừu tượng nào. publicabstractclassClassB {
} Đặc điểm của một class trừu tượng là:
1 Nó được khai báo abstract
2 Nó có thể khai báo 0, 1 hoặc nhiều method trừu tượng bên trong
3 Không thể khởi tạo 1 đối tượng trực tiếp từ một class trừu tượng.
Ví dụ với lớp trừu tượng
Hãy xem hình minh họa:
// Một lớp trừu tượng (Mô phỏng một công việc)
// Nó khai báo 2 phương thức trừu tượng. publicabstractclassAbstractJob { publicAbstractJob() {
// Đây là một phương thức trừu tượng.
// Method này trả về tên của công việc. publicabstractString getJobName();
// Đây là một phương thức trừu tượng. publicabstractvoiddoJob();
// Lớp này thực hiện hết các phương thức trừu tượng của lớp cha. publicclassJavaCoding extendsAbstractJob { publicJavaCoding() {
// Thực hiện phương thức trừu tượng khai báo tại lớp cha.
System.out.println("Coding Java ");
// Thực hiện phương thức trừu tượng khai báo tại lớp cha.
// Phương thức này sẽ có thân (body).
// Và trả về tên của công việc.
@Override publicString getJobName() { return"Coding Java";
// ManualJob - (Mô phỏng một công việc phổ thông)
// Lớp cha (AbstractJob) có 2 phương thức trừu tượng.
// Lớp này mới chỉ thực hiện 1 phương thức trừu tượng của lớp cha.
// Vì vậy nó bắt buộc phải khai báo là abstract. publicabstractclassManualJob extendsAbstractJob { publicManualJob() {
// Thực hiện phương thức trừu tượng của lớp cha.
@Override publicString getJobName() { return"Manual Job";
// Class này thừa kế từ class trìu tượng ManualJob
// BuildHouse không được khai báo là trừu tượng.
// Vì vậy nó cần thực hiện tất cả các phương thức trừu tượng còn lại. publicclassBuildHouse extendsManualJob { publicBuildHouse() {
// Thực hiện phương thức trừu tượng của lớp cha.
System.out.println("Build a House");
17 packageorg.o7planning.tutorial.abs; publicclassJobDemo { publicstaticvoidmain(String[] args) {
// Khởi tạo một đối tượng AbstractJob
// từ Constructor của lớp JavaCoding.
// Gọi phương thức doJob() job1.doJob();
// Phương thức getJobName là trừu tượng trong lớp AbstractJob.
// Nhưng nó đã được thực hiện tại một lớp con nào đó.
// Vì vậy bạn có thể gọi nó.
System.out.println("Job Name 1= "+ jobName);
// Khởi tạo một đối tượng AbstractJob
// từ Constructor của lớp BuildHouse.
AbstractJob job2 = newBuildHouse(); job2.doJob();
System.out.println("Job Name 2= "+ jobName2);
Kết quả chạy ví dụ:
Tổng quan về Interface
Chúng ta biết rằng một class chỉ có thể mở rộng từ một class cha
// Lớp B là con của lớp A, hoặc nói cách khác là B mở rộng từ A
// Java chỉ cho phép một lớp mở rộng từ duy nhất một lớp khác. publicclassB extendsA {
// Trong trường hợp không chỉ rõ lớp B mở rộng từ một lớp cụ thể nào.
// Mặc định, hiểu rằng B mở rộng từ lớp Object. publicclassB {
// Cách khai báo này, và cách phía trên là tương đương nhau. publicclassB extendsObject {
Nhưng một class có thể mở rộng từ nhiều Interface
// Một lớp chỉ có thể mở rộng từ 1 lớp cha.
// Nhưng có thể thực hiện (mở rộng) từ nhiều Interface. publicclassCat extendsAnimal implementsCanEat, CanDrink {
Các đặc điểm của interface
1 Interface luôn luôn có modifier là: public interface , cho dù bạn có khai báo rõ hay không
2 Nếu có các trường (field) thì chúng đều là: public static final , cho dù bạn có khai báo rõ hay không
3 Các method của nó đều là method trừu tượng, nghĩa là không có thân hàm, và đều có modifier là: public abstract , cho dù bạn có khai báo hay không
4 Interface không có Constructor (cấu tử).
Cấu trúc của một Interface
// Đây là một interface không chỉ định rõ 'access modifier'.
// Access modifier của nó là mặc định.
// Chỉ các lớp cùng package mới có thể thi hành interface này. interfaceNoAccessModifierInterface {
// Interface này định nghĩa một tiêu chuẩn
// về những thứ có khả năng di chuyển publicinterfaceCanMove {
// Các phương thức trong Interface đều là trừu tượng và public. publicabstractvoidrun();
// Cho dù bạn không viết rõ 'public abstract' thì java luôn hiểu là vậy. voidback();
// Interface này định nghĩa ra một tiêu chuẩn
// về những thứ có khả năng biết uống. publicinterfaceCanDrink {
// Các trường (field) trong Interface đều là 'public static final'.
// Cho dù bạn có khai báo rõ hay không java luôn hiểu ngầm vậy. publicstaticfinalString PEPSI = "PEPSI"; finalString NUMBER_ONE = "NUMBER ONE";
String SEVENUP = "SEVEN UP"; publicvoiddrink();
// Interface này định nghĩa ra một tiêu chuẩn
// về những thứ có khả năng biết ăn publicinterfaceCanEat { publicvoideat();
Class thực hiện Interface
20 packageorg.o7planning.tutorial.cls; importorg.o7planning.tutorial.itf.CanMove;
// Lớp này mở rộng từ lớp Object (Mặc dù không ghi rõ).
// Và được khai báo thực hiện hiện (hoặc gọi là thừa kế) interface CanMove.
// Interface CanMove có 3 phương thức trừu tượng.
// Lớp này chỉ thực hiện 1 phương thức.
// Vì vậy nó bắt buộc phải khai báo là abstract.
// Các phương thức trừu tượng còn lại sẽ được các lớp con thực hiện. publicabstractclassAnimal implementsCanMove {
// Thực hiện phương thức run() của interface CanMove.
System.out.println("Animal run ");
5 packageorg.o7planning.tutorial.cls; importorg.o7planning.tutorial.itf.CanDrink; importorg.o7planning.tutorial.itf.CanEat;
// Lớp Cat mở rộng từ lớp Animal và thi hành 2 interface CanEat, CanDrink.
// Cat là lớp thông thường (Nó không được khai báo là trừu tượng).
// Vì vậy nó phải thực hiện mọi phương thức trừu tượng của các Interface. publicclassCat extendsAnimal implementsCanEat, CanDrink { privateString name; publicCat(String name) { this.name = name;
// Thực hiện phương thức của interface CanMove.
System.out.println(name + " cat back ");
// Thực hiện phương thức của interface CanMove.
// Thực hiện phương thức của interface CanEat.
System.out.println(name + " cat eat ");
// Thực hiện phương thức của interface CanDrink.
System.out.println(name + " cat drink ");
28 importorg.o7planning.tutorial.itf.CanDrink; importorg.o7planning.tutorial.itf.CanEat; publicclassMouse extendsAnimal implementsCanEat, CanDrink {
System.out.println("Mouse back ");
System.out.println("Mouse drink ");
System.out.println("Mouse eat ");
17 packageorg.o7planning.tutorial.cls; importorg.o7planning.tutorial.itf.CanEat; publicclassAnimalDemo { publicstaticvoidmain(String[] args) {
// Thừa kế trường tĩnh từ interface CanDrink.
System.out.println("Drink "+ Cat.SEVENUP);
// Khởi tạo một đối tượng CanEat.
// Một đối tượng khai báo là CanEat.
// Nhưng thực tế là Cat.
// Một đối tượng khai báo là CanEat.
// Nhưng thực tế là Mouse.
// Tính đa hình (Polymorphism) thể hiện rõ tại đây.
// Java luôn biết một đối tượng là kiểu gì
// ==> Tom cat eat canEat1.eat();
// ==> Mouse eat canEat2.eat(); booleanisCat = canEat1 instanceofCat;
System.out.println("catEat1 is Cat? "+ isCat);
// Ép kiểu (Cast). if(canEat2 instanceofMouse) {
// Gọi phương thức drink (Thừa kế từ CanDrink). mouse.drink();
Kết quả chạy ví dụ:
Mouse eat catEat1 is Cat? true
Modifier trong Java
Có hai loại modifier trong java: access modifiers và non-access modifiers
Các access modifiers trong java xác định độ truy cập (Phạm vi) vào dữ liệu của của các trường, phương thức, cấu tử hoặc class
Có 4 kiểu của java access modifiers:
Và có một vài non-access modifiers chẳng hạn static, abstract, synchronized, native, volatile, transient, v.v Trong tài liệu này chúng ta sẽ học về access modifier.
Tổng quan về access modifier
Bảng minh họa dưới đây cho bạn cái nhìn tổng quan về cách sử dụng các access modifier
Truy cập bên trong class?
Truy cập bên trong package?
Truy cập bên ngoài package bởi class con?
Truy cập bên ngoài class và không thuộc class con? private Y
Bạn có thể hiểu chi tiết hơn theo các ví dụ dưới đây:
private access modifier
private access modifier chỉ cho phép truy cập trong nội bộ một class
Bạn không thể truy cập vào trường private từ bên ngoài class định nghĩa trường private đó Java sẽ thông báo lỗi tại thời điểm biên dịch class.
private constructor
Nếu bạn tạo một class, và có một cấu tử private, bạn không thể tạo một đối tượng của class này từ cấu tử private đó từ bên ngoài class này Hãy xem ví dụ minh họa:
Access modifier mặc định
Trong trường hợp bạn khai báo một trường, method, hoặc cấu tử (constructor), class, mà không ghi rõ ràng access modifier, điều đó có nghĩa là nó là access modifier mặc định
Phạm vi truy cập của access modifier mặc định là trong nội bộ package
// Một class với access modifier mặc định.
// (Không chỉ định public). classMyClass {
// Một trường private access modifier. privateintmyField;
// Một trường access modifier mặc định.
// (Không chỉ định public, protected, private).
// Một method với access modifier mặc định.
// (Không chỉ định public, protected, private). voidshowMe() {
Trong cùng một package bạn có thể truy cập vào các thành viên có access modifier mặc định
Và không được phép truy cập bên ngoài package, kể cả trong class con
Với Interface khi bạn khai báo một trường (Field) hoặc một phương thức (Method) bạn luôn phải khai báo là public hoặc để mặc định, nhưng Java luôn hiểu đó là public
// Đây là một trường, bạn không thể khai báo private hoặc protected.
// Đây là một trường, bạn để access modifier mặc định.
// Tuy nhiên Java coi đây là public. staticintMY_FIELD2 = 200;
// Đây là một method, bạn để access modifier mặc định.
// Tuy nhiên Java coi đây là public voidshowInfo();
protected access modifier
protected access modifier có thể truy cập bên trong package, hoặc bên ngoài package nhưng phải thông qua tính kế thừa protected access modifier chỉ áp dụng cho field, method và constructor Nó không thể áp dụng cho class (class, interface, enum, annotation).
public access modifier
public access modifier là mạnh mẽ nhất và có thể truy cập ở mọi nơi Nó có phạm vi truy cập rộng nhất so với các modifier khác.
Ghi đè phương thức
Bạn có thể ghi đè một method của class cha với một method cùng tên cùng tham số tại class con, tuy nhiên bạn không được phép làm hạn chế phạm vi truy cập của method này.