Bạn có thể nghĩ đến việc tạo một phương thức tĩnh cuối cùng, hãy xem xét những điều sau:
Có các lớp sau:
class A {
static void ts() {
System.out.print("A");
}
}
class B extends A {
static void ts() {
System.out.print("B");
}
}
Bây giờ cách 'chính xác' để gọi các phương thức này sẽ là
A.ts();
B.ts();
điều này sẽ dẫn đến AB
nhưng bạn cũng có thể gọi các phương thức trên các trường hợp:
A a = new A();
a.ts();
B b = new B();
b.ts();
mà cũng sẽ dẫn đến AB
.
Bây giờ hãy xem xét những điều sau:
A a = new B();
a.ts();
mà sẽ in A
. Điều đó có thể làm bạn ngạc nhiên vì bạn đang thực sự có một đối tượng của lớp B
. Nhưng vì bạn đang gọi nó từ một loại tham chiếu A
, nó sẽ gọi A.ts()
. Bạn có thể in B
bằng mã sau:
A a = new B();
((B)a).ts();
Trong cả hai trường hợp, đối tượng bạn có thực sự là từ lớp B
. Nhưng tùy thuộc vào con trỏ trỏ đến đối tượng, bạn sẽ gọi phương thức from A
hoặc from B
.
Bây giờ giả sử bạn là người phát triển lớp A
và bạn muốn cho phép phân lớp con. Nhưng bạn thực sự muốn phương thức ts()
, bất cứ khi nào được gọi, ngay cả từ một lớp con, nó sẽ thực hiện những gì bạn muốn nó làm và không bị ẩn bởi một phiên bản lớp con. Sau đó, bạn có thể tạo nó final
và ngăn nó bị ẩn trong lớp con. Và bạn có thể chắc chắn rằng đoạn mã sau sẽ gọi phương thức từ lớp của bạn A
:
B b = new B();
b.ts();
Ok, thừa nhận rằng nó được xây dựng bằng cách nào đó, nhưng nó có thể có ý nghĩa đối với một số trường hợp.
Bạn không nên gọi các phương thức tĩnh trên các cá thể mà trực tiếp trên các lớp - thì bạn sẽ không gặp vấn đề đó. Ngoài ra, IntelliJ IDEA chẳng hạn sẽ hiển thị cho bạn một cảnh báo, nếu bạn gọi một phương thức tĩnh trên một phiên bản và cũng như nếu bạn thực hiện một phương thức tĩnh cuối cùng.