Sunday, August 9, 2015

Bài 10 - Kế thừa , Đa hình , Abstracts và Interface (Inheritance, Polymorphism, Abstracts & Interface)

Trong Java là một ngôn ngữ hướng đối tượng mạnh . Việc kế thừa là một công cụ rất mạnh mẽ và quan trọng trong việc phát triển của Java. Đặc điểm kế thừa này làm cho tính đa hình của Java được thể hiện rõ ràng và cụ thể hơn . Tăng tính tái sử dụng code khi viết chương trình.
I. Kế thừa (Inheritance)
1. Định nghĩa
Một class C1 extend từ một class C2 , thì nó sẽ kế thừa tất cả các đặc điểm về thuộc tính cũng như phương thức của class C2 . Và người ta gọi đó là sự kế thừa . Class C1 gọi là class con (subclass) , class C2 là class cha (supper class).
Một class con chỉ kế thừa từ một class cha , nhưng một class cha có thể được nhiều class con khác nhau kế thừa .
Cú pháp
public class GeometricObject {
// your code
}
public class Circle extends GeometricObject {
//your code
}
Trong UML design thì người ta thể hiện sử kế thừa như sau .
2. Cách sử dụng từ khóa supper
subclass muốn kế thừa các đặc tính của data fields và method của class cha thì phải có từ khóa supper để làm điều đó.
a. Gọi supperclass Contructors
Cú pháp
super(), or super(parameters);
Có từ khóa supper trong contructor của class con thì nó sẽ kế thừa contructors của cha nó.
Ví dụ :
public class SupperClass {
 int a;
 public SupperClass(int a) {
  this.a = a;
 }
 public SupperClass() {
  super();
 } 
}
public class SubClass extends SupperClass{
 public SubClass(int a) {
  super(a);
 }
}
b. Gọi tới Superclass Methods
Từ khóa supper còn được sử dụng để gọi tới method khác với contructors của lớp cha.
Cú pháp
super.method(parameters);
Ví dụ :
public void printCircle() {
  System.out.println("The circle is created " +
    super.getDateCreated() + " and the radius is " + radius);
}
3. Overriding Methods
Khi một subclass kế thừa một supper class mà có một method trùng tên với class cha của nó thì nó sẽ thực hiện ghi đè lên nội dùng của class cha nó.
Nhưng nó chỉ ghi đè được những method giống tham số ,mà không ghi đè được  method khác tham số
Ví dụ :
public class SupperClass {
 int a;
 public SupperClass(int a) {
  this.a = a;
 }
 public SupperClass() {
  super();
 }
 void tinhYeu(){
  System.out.println("Tinh yeu mau nang!");
 }
 void tinhYeu(int c , String b){
  System.out.println("tinh yeu la gi :" + a + " " + b);
 }
}
public class SubClass extends SupperClass{
 public SubClass(int a) {
  super(a);
  // TODO Auto-generated constructor stub
 }
 void tinhYeu(){
  System.out.println("han thu tram nam");
 }
 void tinhYeu(int b ){
  System.out.println("Tinh yeu va thu han " + b);
 }
 public static void main(String[] args) {
  SubClass sub = new SubClass(3);
  sub.tinhYeu();
  sub.tinhYeu(32);
 }
}
Sự khác nhau giữa override và overloading :
Như đã nói ở trên : override là phương thức xuất hiện ở lớp cha, lớp con cũng xuất hiện thì sẽ overload
Còn overload thì khi 2 method trong cùng 1 class cùng tên nhưng khác tham số , thì gọi tới method này thì sẽ overload tham số còn lại.
II . Abstract (Trừu tượng)
Lớp trừu tượng là một lớp cha , tuy nhiên điểm khác biệt là có từ khóa abstracts trước và nó chỉ cho lớp con kế thừa , không cho phép tạo instance hay không cho tạo thêm object trong đó.Và trong method abstract không có nội dung .
Biểu diễn của nó trong UML như sau .
Trong code nó có cú pháp như sau :
public abstract class GeometricObject {
 private String color = "white";
 private boolean filled;
 private java.util.Date dateCreated;
 /** Construct a default geometric object */
 protected GeometricObject() {
  dateCreated = new java.util.Date();
 }

 /** Return color */
 public String getColor() {
  return color;
 }
 /** Set a new color */
 public void setColor(String color) {
  this.color = color;
 }
 /**
  * Return filled. Since filled is boolean, so, the get method name is
  * isFilled
  */
 public boolean isFilled() {
  return filled;
 }
 /** Set a new filled */
 public void setFilled(boolean filled) {
  this.filled = filled;
 }
 /** Get dateCreated */
 public java.util.Date getDateCreated() {
  return dateCreated;
 }
 /** Return a string representation of this object */
 public String toString() {
  return "created on " + dateCreated + "\ncolor: " + color
    + " and filled: " + filled;
 }
 /** Abstract method getArea */
 public abstract double getArea();
 /** Abstract method getPerimeter */
 public abstract double getPerimeter();
}
LƯU Ý : Abstract class chỉ cho lớp khác kế thừa. Vì thế nên các method của nó không bao h được viết là private :)
III. Interface
Trong Java vì một class con không thể kế thừa từ nhiều class cha . Hay hiểu nôm na là mộtCon thì chỉ có 1 cha , nếu có hai cha thì cha kia không phải là cha (nghe rất hàn lâm :P)
Vì thế Java cung cấp một cái gọi là Interface , như một người bảo mẫu . Và một class con thì có thể implement nhiều bảo mẫu (interface) . Chúng có thêm một khái niệm về multi - Inheritance
Cách khai báo interface như sau :
modifier interface InterfaceName {
  /** Constant declarations */
  /** Method signatures */
}
Điểm đặc biệt là trong interface thì tất cả các method đều không có nội dung và phải khai báo bằng public và default . Không được dùng private và protected . Lưu ý nhé các bạn . Đây cũng là một câu hỏi có thể nhà tuyển dụng sẽ hỏi các bạn. Còn data field thì chỉ được khai báo hằng số . Không được phép khai báo biến . Tại sao vậy ? Câu trả lời là kiểu nó phải thế :D
public interface Comparable{
  public int compareTo(Object o)
}
Để class có thể kế thừa hay cài đặt interface người ta dùng từ khóa implements
Ví dụ :
public interface DemoInterfaces {
 final int a = 100;
 public int a();
 public void hienThi();
 void nhap();
}
public interface DemoInterface2 {
 public void hienThiNoiDung();
 public int tinhTong(int a , int b);
}
public class Result implements DemoInterfaces , DemoInterface2{
 @Override
 public void hienThiNoiDung() {
  // TODO Auto-generated method stub 
 }
 @Override
 public int tinhTong(int a, int b) {
  // TODO Auto-generated method stub
  return 0;
 }
 @Override
 public int a() {
  // TODO Auto-generated method stub
  return 0;
 }
 @Override
 public void hienThi() {
  // TODO Auto-generated method stub 
 }
 @Override
 public void nhap() {
  // TODO Auto-generated method stub
  
 }
}
Các bạn custom vào class con đã cài đặt interface là được . Như vậy chúng ta sẽ tiết kiệm được cách code đến cả hàng trăm dòng , nếu dùng điều này.
IV . Tính đa hình .
Các bạn trên mạng nói tính đa hình là nạp chồng của đối tượng này kia . Nhưng theo mình hiểu thì tính đa hình là sự thể hiện đa dạng của một đối tượng . Thành các đối tượng khác , giữ được các đặc điểm cũ đã tồn tại.
Nó rất dễ hiểu thôi , như cha các bạn sinh ra khoảng 8 người con chả hạn , người thì giống mũi , người thì giống mắt , người thì giống dáng đi vân vân . Thì mỗi thể hiện của người con , sẽ mang một số đặc điểm cố hữu của người cha . Nhưng có thêm các nét bổ sung mới . 
Trong lập trình Java cũng vậy , các đặc tính chung thì các bạn có thểm gộp vào 1 lớp cha . Các đặc tính riêng biệt của mỗi đối tượng khác nhau thì các bạn viết riêng , nhưng kế thừa lớp cha có các đặc tính chung đã tạo trước đó .
Như vậy gọi là đa hình.
Đơn giản đúng không nào :P
V. Một số method khác của đối tượng.
Dưới đây là một số method rất quan trọng vốn có của đối tượng :
- public boolean equals(Object object)
- public int hashCode()
- protected void finalize() throws Throwable
- protected native Object clone() throws CloneNotSupportedException
- public final native Class getClass()
a. equals method
Để kiểm tra 2 đối tượng có giống nhau không . Nếu giống trả về true , và ngược lại
Cú pháp :
object1.equals(object2);
The default implementation of the equals method in the Object class is:
public boolean equals(Object obj) {
  return (this == obj);
}
Ví dụ :
public boolean equals(Object o) {
  if (o instanceof Circle) {
  return radius == ((Circle)o).radius;
}
else
  return false;
}
b . hashCode method
hashCode là một phương thức trả về một số nguyên lưu trữ đối tượng trong bộ nhỡ băm đểlấy ra một cách nhanh chóng
cú pháp :
public int hashCode() {
  return (int)(radius * 1999711);
}
c . finalize method :
Khi một đối tượng không được xử dụng nữa thì được coi là rác , method này có chức năng là thu gom rác của chương trình . Nếu một lớp con ghi đè method này thì nó sẽ tự động thu gom rác nếu cần thiết
Cụ thể như sau :
public class FinalizationDemo {
   public static void main(String[] args) {
     Cake a1 = new Cake(1);
  Cake a2 = new Cake(2);
     Cake a3 = new Cake(3);
     // To dispose the objects a2 and a3
     a2 = a3 = null;
     System.gc(); // Invoke the Java garbage collector
   }
 }
 class Cake extends Object {
   private int id;
   public Cake(int id) {
     this.id = id;
     System.out.println("Cake object " + id + " is created");
   }
   protected void finalize() throws java.lang.Throwable {
     super.finalize();
     System.out.println("Cake object " + id + " is disposed");
    }
}
Result :
Cake object 1 is created
Cake object 2 is created
Cake object 3 is created
Cake object 2 is disposed
Cake object 3 is disposed
d. clone method.
Đôi khi bạn cần một bản sao của đối tượng . Cú pháp gán như sau :
newObject = someObject;
//Sẽ dẫn tới duplicate object
Chúng ta sử dụng như sau :
newObject = someObject.clone();
Ví dụ :
java.util.Date date = new java.util.Date();
java.util.Date date1 = (java.util.Date)(date.clone());
hoặc
int[] targetArray = (int[])sourceArray.clone();
e. getClass method
Một lớp được load để sử dụng .Nó tạo ra một đối tượng chứa thông tin của class như tên , contructors , method . Đối tượng này là instance của java.lang.Class . Chứa thông tin của calss.
Ví dụ :
Object obj = new Object();
Class metaObject = obj.getClass();
System.out.println("Object obj's class is " + metaObject.getName());
Result :
Object obj's class is java.lang.Object
OK , bài hướng dẫn hôm nay tạm dừng ở đây .
Tất nhiên chúng ta không quên bài tập vận dụng .
Nào cố lên đi các chiến binh .
Bài tập 1:
a. Xây dựng 1 lớp hình chữ nhật với các thuộc tính chiều dài , chiều rộng , viết các hàm tính chu vi và diện tích.
b. Xây dựng lớp hình vuông kế thừa lớp hình chữ nhật.
c. viết chương trình tính chu vi & diện tích hình vuông với độ dài nhập vào.
Code tham khảo : here
Bài tập 2:
Một trung tâm tin học cần quản lý giảng viên cố hữu và giảng viên thỉnh giảng.
Giảng viên cố hữu  ký hợp đồng lao động lớn hơn 1 năm  được hưởng lương hàng tháng  bao gồm lương thỏa thuận và lương cộng thêm theo quy định vượt giờ quy định trong tháng (số giờ quy định trong tháng là 40)
Giảng viên  tham gia giảng dạy thỉnh giảng ký hợp đồng lao động theo từng giờ học  được hưởng lương hàng tháng theo số giờ đứng lớp . Biết rằng mỗi giờ 200000d.
Thông tin giảng viên  cố hữu : tên giảng viên, email , địa chỉ , số giờ giảng dạy trong tháng , lương thỏa thuận, số giờ quy định chung.
Thông tin giảng viên thỉnh giảng : tên giảng viên , email,  địa chỉ , điện thoại ,  cơ quan làm việc , số giờ giảng dạy trong tháng.
Hãy xây dựng một chương trình cho phép nhân viên  trung tâm tin học  có thể thực hiện được các chức năng sau :
  1. Nhập thông tin giảng viên.
  2. xuất danh sách toàn bộ giảng viên .
  3. Xuất danh sách giảng viên thỉnh giảng
  4. Xuất danh sách giảng viên cố hữu.
  5. Tính tổng số tiền lương
  6. Tìm giảng viên có tổng lương cao nhất.
Sau đây là code tham khảo : here
pass extract : https://coderandtutorial.blogspot.com

2 comments:

  1. không mở được file zip bác ơi !

    ReplyDelete
  2. TH mình chỉ dùng 1 mảng GV ko tách ra 2 loại CH và TG thì câu 3. Xuất DS GVCH làm thế nào ?

    ReplyDelete