Thứ Sáu, 28 tháng 12, 2018

Học lập trình Java - Ghi đè

Trong chương trước, chúng ta đã nói về siêu lớp và các lớp con. Nếu một lớp kế thừa một phương thức từ siêu lớp của nó, thì có khả năng ghi đè phương thức với điều kiện là nó không được đánh dấu cuối cùng.

Lợi ích của việc ghi đè là: khả năng xác định một hành vi dành riêng cho loại lớp con, có nghĩa là một lớp con có thể thực hiện một phương thức lớp cha dựa trên yêu cầu của nó.

Khóa học lập trình Java
Khóa học lập trình Java

Khóa học lập trình Java Theo thuật ngữ hướng đối tượng, ghi đè có nghĩa là ghi đè chức năng của một phương thức hiện có.

Chúng ta hãy xem xét một ví dụ.

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
   }
}

Điều này sẽ tạo ra kết quả sau


Animals can move
Dogs can walk and run

Trong ví dụ trên, bạn có thể thấy rằng mặc dù b là một loại Động vật, nó vẫn chạy phương thức di chuyển trong lớp Dog. Lý do cho điều này là: 

Trong thời gian biên dịch, kiểm tra được thực hiện trên loại tham chiếu. Tuy nhiên, trong thời gian chạy, JVM chỉ ra loại đối tượng và sẽ chạy phương thức thuộc về đối tượng cụ thể đó.

Khóa học lập trình Java Do đó, trong ví dụ trên, chương trình sẽ biên dịch đúng vì lớp Animal có phương thức di chuyển. Sau đó, tại thời gian chạy, nó chạy phương thức cụ thể cho đối tượng đó.
class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      b.bark();
   }
}

Điều này sẽ tạo ra kết quả sau

TestDog.java:26: error: cannot find symbol
      b.bark();
       ^
  symbol:   method bark()
  location: variable b of type Animal
1 error

Chương trình này sẽ đưa ra lỗi thời gian biên dịch do kiểu tham chiếu của b Animal không có phương thức bằng tên của vỏ cây.

Quy tắc ghi đè phương thức

Khóa học lập trình Java Danh sách đối số phải giống hệt như phương thức được ghi đè.

Kiểu trả về phải giống hoặc một kiểu con của kiểu trả về được khai báo trong phương thức ghi đè ban đầu trong lớp cha.

Mức truy cập không thể hạn chế hơn mức truy cập của phương thức bị ghi đè. Ví dụ: Nếu phương thức siêu lớp được khai báo công khai thì phương thức ghi đè trong lớp con có thể là riêng tư hoặc được bảo vệ.

Các phương thức sơ thẩm chỉ có thể được ghi đè nếu chúng được kế thừa bởi lớp con.

Một phương thức được tuyên bố cuối cùng không thể được ghi đè.

Một phương thức được khai báo tĩnh không thể bị ghi đè nhưng có thể được khai báo lại.

Nếu một phương thức không thể được kế thừa, thì nó không thể bị ghi đè.

Một lớp con trong cùng một gói như siêu lớp của cá thể có thể ghi đè bất kỳ phương thức siêu lớp nào không được khai báo là riêng tư hoặc cuối cùng.

Khóa học lập trình Java Một lớp con trong một gói khác nhau chỉ có thể ghi đè các phương thức không phải là cuối cùng được khai báo công khai hoặc được bảo vệ.

Một phương thức ghi đè có thể đưa ra bất kỳ ngoại lệ không được kiểm tra nào, bất kể phương thức ghi đè đó có ném ngoại lệ hay không. 

Tuy nhiên, phương thức ghi đè không được đưa ra các ngoại lệ được kiểm tra là mới hoặc rộng hơn so với phương pháp được ghi đè bằng phương thức ghi đè. Phương thức ghi đè có thể đưa ra các ngoại lệ hẹp hơn hoặc ít hơn so với phương thức ghi đè.

Con constructor không thể bị ghi đè.

Sử dụng siêu từ khóa

Khi gọi một phiên bản siêu lớp của một phương thức được ghi đè, siêu từ khóa được sử dụng.
class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      super.move();   // invokes the super class method
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal b = new Dog();   // Animal reference but Dog object
      b.move();   // runs the method in Dog class
   }
}

Điều này sẽ tạo ra kết quả sau

Animals can move
Dogs can walk and run

Thứ Năm, 27 tháng 12, 2018

Học lập trình Java - Kế thừa

Kế thừa có thể được định nghĩa là quá trình trong đó một lớp có được các thuộc tính (phương thức và trường) của lớp khác. Với việc sử dụng tính kế thừa, thông tin được quản lý theo thứ tự phân cấp.

Khóa học lập trình Java Lớp kế thừa các thuộc tính của lớp khác được gọi là lớp con (lớp dẫn xuất, lớp con) và lớp có các thuộc tính được kế thừa được gọi là lớp cha (lớp cơ sở, lớp cha).

Khóa học lập trình Java
Khóa học lập trình Java

mở rộng từ khóa


extends là từ khóa được sử dụng để kế thừa các thuộc tính của một lớp. Sau đây là cú pháp mở rộng từ khóa.

class Super {
   .....
   .....
}
class Sub extends Super {
   .....
   .....
}

Mã mẫu

Sau đây là một ví dụ minh họa sự kế thừa Khóa học lập trình Java. Trong ví dụ này, bạn có thể quan sát hai lớp là Tính toán và My_Calculation.

Sử dụng từ khóa mở rộng, My_Calculation kế thừa các phương thức phép cộng () và phép trừ () của lớp Tính toán.

Sao chép và dán chương trình sau vào một tệp có tên My_Calculation.java
class Calculation {
   int z;
 
   public void addition(int x, int y) {
      z = x + y;
      System.out.println("The sum of the given numbers:"+z);
   }
 
   public void Subtraction(int x, int y) {
      z = x - y;
      System.out.println("The difference between the given numbers:"+z);
   }
}

public class My_Calculation extends Calculation {
   public void multiplication(int x, int y) {
      z = x * y;
      System.out.println("The product of the given numbers:"+z);
   }
 
   public static void main(String args[]) {
      int a = 20, b = 10;
      My_Calculation demo = new My_Calculation();
      demo.addition(a, b);
      demo.Subtraction(a, b);
      demo.multiplication(a, b);
   }
}
Biên dịch và thực thi mã trên như dưới đây.

javac My_Calculation.java
java My_Calculation

Sau khi thực hiện chương trình, nó sẽ tạo ra kết quả như sau

The sum of the given numbers:30
The difference between the given numbers:10
The product of the given numbers:200

Trong chương trình đã cho, khi một đối tượng cho lớp My_Calculation được tạo, một bản sao nội dung của siêu lớp được tạo trong nó. Đó là lý do tại sao, bằng cách sử dụng đối tượng của lớp con, bạn có thể truy cập các thành viên của siêu lớp.

Biến tham chiếu Superclass có thể giữ đối tượng lớp con, nhưng sử dụng biến đó bạn chỉ có thể truy cập các thành viên của siêu lớp, vì vậy, để truy cập các thành viên của cả hai lớp, nên luôn luôn tạo biến tham chiếu cho lớp con.

Nếu bạn xem xét chương trình trên, bạn có thể khởi tạo lớp như được đưa ra dưới đây. Nhưng bằng cách sử dụng biến tham chiếu siêu lớp ( cal trong trường hợp này), bạn không thể gọi phương thức nhân () , thuộc lớp con My_Calculation.
Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);
Các từ khóa siêu tương tự như từ khóa này . Sau đây là các tình huống mà siêu từ khóa được sử dụng.

Nó được sử dụng để phân biệt các thành viên của siêu lớp với các thành viên của lớp con, nếu chúng có cùng tên.

Nó được sử dụng để gọi hàm tạo của lớp bậc trên từ lớp con.

Phân biệt các thành viên


Nếu một lớp đang kế thừa các thuộc tính của lớp khác. Và nếu các thành viên của siêu lớp có tên giống như lớp con, để phân biệt các biến này, chúng tôi sử dụng siêu từ khóa như dưới đây.

super.variable
super.method();

Phần này cung cấp cho bạn một chương trình thể hiện việc sử dụng siêu từ khóa.

Trong chương trình đã cho, bạn có hai lớp là Sub_group và Super_group , cả hai đều có một phương thức có tên display () với các cách triển khai khác nhau và một biến có tên num với các giá trị khác nhau. 

Khóa học lập trình Java Chúng tôi đang gọi phương thức display () của cả hai lớp và in giá trị của num biến của cả hai lớp. Ở đây bạn có thể quan sát rằng chúng tôi đã sử dụng siêu từ khóa để phân biệt các thành viên của siêu lớp với lớp con.

Sao chép và dán chương trình trong một tệp có tên Sub_group.java.Biên dịch và thực thi mã trên bằng cú pháp sau.

javac Super_Demo
java Super

Khi thực hiện chương trình, bạn sẽ nhận được kết quả sau

This is the display method of subclass
This is the display method of superclass
value of the variable named num in sub class:10
value of the variable named num in super class:20

Gọi siêu xây dựng

Nếu một lớp đang kế thừa các thuộc tính của một lớp khác, lớp con sẽ tự động có được hàm tạo mặc định của lớp cha. Nhưng nếu bạn muốn gọi một hàm tạo tham số của siêu lớp, bạn cần sử dụng siêu từ khóa như dưới đây.

super(values);

Chương trình được đưa ra trong phần này trình bày cách sử dụng siêu từ khóa để gọi hàm tạo tham số của siêu lớp.

Chương trình này chứa một siêu lớp và một lớp con, trong đó siêu lớp chứa một hàm tạo được tham số hóa chấp nhận một giá trị nguyên và chúng tôi đã sử dụng siêu từ khóa để gọi hàm tạo tham số của siêu lớp.

Sao chép và dán chương trình sau vào một tệp có tên Subgroup.java
class Superclass {
   int age;

   Superclass(int age) {
      this.age = age;    
   }

   public void getAge() {
      System.out.println("The value of the variable named age in super class is: " +age);
   }
}

public class Subclass extends Superclass {
   Subclass(int age) {
      super(age);
   }

   public static void main(String argd[]) {
      Subclass s = new Subclass(24);
      s.getAge();
   }
}
Biên dịch và thực thi mã trên bằng cú pháp sau.

javac Subclass
java Subclass

Khi thực hiện chương trình, bạn sẽ nhận được kết quả sau

The value of the variable named age in super class is: 24

Mối quan hệ IS-A

Khóa học lập trình Java IS-A là một cách nói: Đối tượng này là một loại đối tượng đó. Hãy cho chúng tôi xem làm thế nào từ khóa mở rộng được sử dụng để đạt được sự kế thừa.
công lớp Animal { }   


lớp học công cộng Động vật có vú mở rộng Động vật { }     


Lớp công khai Bò sát kéo dài Động vật { }     


lớp công cộng Chó kéo dài Động vật có vú { }     
Bây giờ, dựa trên ví dụ trên, theo thuật ngữ Hướng đối tượng, những điều sau đây là đúng -

Động vật là siêu lớp của động vật có vú.

Động vật là siêu lớp của lớp Bò sát.

Động vật có vú và bò sát là các lớp con của lớp Động vật.

Chó là lớp con của cả hai lớp Động vật có vú và Động vật.

Bây giờ, nếu chúng ta xem xét mối quan hệ IS-A, chúng ta có thể nói -

Động vật có vú IS-A

Bò sát IS-A Animal

Chó IS-A động vật có vú

Do đó: Chó IS-A Animal cũng vậy

Với việc sử dụng từ khóa mở rộng, các lớp con sẽ có thể kế thừa tất cả các thuộc tính của siêu lớp ngoại trừ các thuộc tính riêng của siêu lớp.

Chúng tôi có thể đảm bảo rằng Động vật có vú thực sự là một Động vật với việc sử dụng toán tử cá thể.
class Animal {
}

class Mammal extends Animal {
}

class Reptile extends Animal {
}

public class Dog extends Mammal {

   public static void main(String args[]) {
      Animal a = new Animal();
      Mammal m = new Mammal();
      Dog d = new Dog();

      System.out.println(m instanceof Animal);
      System.out.println(d instanceof Mammal);
      System.out.println(d instanceof Animal);
   }
}
Điều này sẽ tạo ra kết quả sau

true
true
true

Vì chúng tôi hiểu rõ về từ khóa mở rộng , chúng ta hãy xem xét cách sử dụng từ khóa thực hiện để có được mối quan hệ IS-A.

Nói chung, từ khóa thực hiện được sử dụng với các lớp để kế thừa các thuộc tính của giao diện. Các giao diện không bao giờ có thể được mở rộng bởi một lớp.
public interface Animal {
}

public class Mammal implements Animal {
}

public class Dog extends Mammal {
}

Ví dụ từ khóa

Chúng ta hãy sử dụng toán tử instanceof để kiểm tra xem liệu Mammal có thực sự là Động vật hay không và chó có thực sự là Động vật hay không.
interface Animal{}
class Mammal implements Animal{}

public class Dog extends Mammal {

   public static void main(String args[]) {
      Mammal m = new Mammal();
      Dog d = new Dog();

      System.out.println(m instanceof Animal);
      System.out.println(d instanceof Mammal);
      System.out.println(d instanceof Animal);
   }
}

Điều này sẽ tạo ra kết quả sau

true
true
true

Có một mối quan hệ

Những mối quan hệ này chủ yếu dựa trên việc sử dụng. Điều này xác định xem một lớp nhất định ĐÃ-Một điều nhất định. Mối quan hệ này giúp giảm trùng lặp mã cũng như lỗi.
public class Vehicle{}
public class Speed{}

public class Van extends Vehicle {
   private Speed sp;
} 
Điều này cho thấy lớp Van HAS-A Speed. Bằng cách có một lớp riêng cho Tốc độ, chúng ta không phải đặt toàn bộ mã thuộc về tốc độ bên trong lớp Van, điều này cho phép sử dụng lại lớp Tốc độ trong nhiều ứng dụng.

Trong tính năng Hướng đối tượng, người dùng không cần bận tâm về đối tượng nào đang thực hiện công việc thực sự. 

Để đạt được điều này, lớp Van ẩn các chi tiết triển khai từ những người dùng của lớp Van. Vì vậy, về cơ bản những gì xảy ra là người dùng sẽ yêu cầu lớp Van thực hiện một hành động nhất định và lớp Van sẽ tự thực hiện công việc hoặc yêu cầu một lớp khác thực hiện hành động đó.

Các kiểu thừa kế

Có nhiều loại thừa kế như được trình bày dưới đây.

Một thực tế rất quan trọng cần nhớ là Khóa học lập trình Java không hỗ trợ nhiều kế thừa. Điều này có nghĩa là một lớp không thể mở rộng nhiều hơn một lớp. Do đó, sau đây là bất hợp pháp
public class extends Animal, Mammal{} 
Tuy nhiên, một lớp có thể thực hiện một hoặc nhiều giao diện, điều này đã giúp Khóa học lập trình Java thoát khỏi sự bất khả thi của nhiều kế thừa.

Lập trình Java - Ngoại lệ

Một ngoại lệ (hoặc sự kiện đặc biệt) là một vấn đề phát sinh trong quá trình thực hiện chương trình. Khi xảy ra Ngoại lệ , luồng bình thường...