Bạn đọc câu trả lời của mình nhắc đến rất nhiều Reference Variable, rất nhiều người code java mà không hiểu nó là gì đó.
Bản chất của câu hỏi này là hiểu rõ Reference Variable là gì
Hỏi về Reference Variable Type trong Java
Thế sao không để animal có kiểu Horse từ đầu mà phải để Animal rồi lại ép sang Horse ạ?
Đấy là mục đích sử dụng tinh kế thừa inheritance, còn đây chỉ là ví dụ của trường hợp này thôi bạn.
bạn có thể đọc bài Object Orientation để hiểu rõ hơn nhé.
Em cũng đọc topic đó rồi nhưng vẫn còn lơ mơ quá anh cho em xin một ví dụ thực tế mà cần phải khai báo kiểu “cọc cạch” như thế này được k ạ
Thực tế sau nàu bạn đi làm, tham gia 1 dự án nào đó về java sẽ gặp rất nhiều trường hợp này. Java sinh ra để đáp ứng nhu cầu của các hệ thống cực lớn như ngân hàng, quản trị doanh nghiệp… Vì thế nó phải rất chặt chẽ, chính là tuân thủ OOP.
Còn đây là các ví dụ trương trình nhỏ, để bạn học cơ bản. Chứ không có mục đích sử dụng nào ở đây cả :d. Hi vọng bạn hiểu ý mình.
Lời khuyên của mình là bạn nên đọc Book pdf mà mình đính kèm ở topic, rất đầy đủ.
Theo quan điểm của mình thì bạn đang hiểu sai ý nghĩa của khái niệm Reference Variable. Khái niệm này nhằm ám chỉ cách thức tổ chức cửa biến trên ô nhớ nhằm phân biệt việc một biến lưu trữ địa chỉ của ô nhớ nhằm mục đích tham chiếu đến giá trị được ô nhớ đó lưu trữ với cả cách biến lưu trữ ngay một giá trị có kiểu dữ liệu nguyên thủy.
Cái trên của bạn chỉ hợp lí khi đưa ra ví dụ của kế thừa. Với Reference Variable ngày ta hãy có những bài toán như sau:
public static void main(String args){
A a = new A();
a.b = "c";
change(a);
notChange(a);
print a;
}
private static void change(A a){
a.c = "d";
}
private static void notChange(A a){
a = new A();
a.b = "e";
}
Ý kiến của mình như bạn ở trên.
Thực ra ví dụ trên đang dùng biến con trỏ chứ k phải tham chiếu.
Biến tham chiếu là biến tham chiếu trực tiếp đến vùng nhớ của biến. Ví dụ trên ta đang tham chiếu đến 1 đối tượng Horse thông qua 1 con trỏ Animal. Việc run() không được bởi vì đọc vùng nhớ theo kiểu của Animal.
Theo định nghĩa thì " Animal animal = new Horse( )": thực chất chỉ tạo ra một biến tham chiếu animal có kiểu Animal trỏ đến đối tượng Horse () có kiểu Horse. Bản chất của nó giống như một biến con trỏ trong C++. Java là một ngôn ngữ kiểu chặt nên trong câu lệnh này đã Gán sai kiểu giá trị cho một biến dẫn đến lỗi biên dịch. Chính vì vậy mà ta cần phải ép kiểu dữ liệu cho nó: “((Horse) animal).run()” .Cho nên ý của chủ thớt muốn mọi người hiểu rõ hơn biến tham chiếu (Reference Variable).
Theo quan điểm của mình thì bạn đang hiểu sai ý nghĩa của khái niệm Reference Variable. Khái niệm này nhằm ám chỉ cách thức tổ chức cửa biến trên ô nhớ nhằm phân biệt việc một biến lưu trữ địa chỉ của ô nhớ nhằm mục đích tham chiếu đến giá trị được ô nhớ đó lưu trữ với cả cách biến lưu trữ ngay một giá trị có kiểu dữ liệu nguyên thủy.
Nói thật là tớ đọc mãi vẫn không hiểu ý của bạn lắm , còn cái ví dụ của bạn đúng là ví dụ về Reference Variable, nhưng nó là 1 khía cạnh khác. Của mình nói về “Kiểu của Reference Variable”, luôn luôn là duy nhất (trong vd là Animal), định nghĩa 1 lần và không bao h thay đổi (ý là không bao h thành kiểu Horse). Mình sẽ sửa cái tiêu đề cho bạn đỡ confuse.
@dkstorm13 trong java không có khái niệm con trỏ, nó chính là Reference Variable, hiểu nó như con trỏ cũng không sai. Còn giải thích của bạn thì chuẩn 100% rồi
Tớ gửi 1 hình vẽ miêu tả rõ hơn về Reference Variable. Ví dụ của tớ để mọi người biết về Reference Variable, rất nhiều bạn không biết khái niệm này.
Riêng tớ sẽ có hẳn 1 phần nói về cái này trong topic Object Orientation, chắc chắn sẽ có Ví Dụ của bạn
Tóm lại cho dễ hiểu
Object type (Horse) sẽ quyết định overridden method tại thời điểm chạy (run time). Reference type (tức animal) sẽ quyết định hàm overloaded tại thời điểm compile time.
Code mẫu trên chủ thớt gọi animal.run() tức là đã gọi 1 reference type, compiler sẽ đi tìm run() của animal tại thời điểm compile time nhưng tiếc là kiếm đếch được nên sẽ la làng lên.
Mình cũng hiểu ý bạn.
Ý mình tức là thế này: Chúng ta có 1 biến kiểu Animal để lưu trữ địa chỉ của đối tượng của class Horse, và biến kiểu Animal này là biến tham chiếu, khi tham chiếu đến biến animal ta sẽ được địa chỉ của đối tượng của class Horse. Mà thực chất thì biến animal chính là 1 con trỏ đang trỏ đến đối tượng Horse.
Về việc tại sao lại gọi run() báo lỗi, theo mình nghĩ như này:
- Đối tượng của class Animal sẽ lưu trữ 100 bytes (giả dụ).
- Vì class Horse kế thừa từ class Animal nên nó sẽ kế thừa 100 bytes của class Animal và nó có thêm 50 bytes riêng của nó (vì nó có thêm phương thức run()).
- Bởi vì biến animal có kiểu Animal nên biến animal chỉ đọc được 100 bytes của đối tượng của class Horse, và trong 100 bytes đó không có phương thức run() nên nó không thực hiện được.
Mình biết ít nên có gì pro sửa giúp. Thanks
làm sao mà các bác có thể biết rõ nó như thế vậy, ở trường mình chỉ dạy làm như thế nào chứ không có rõ ràng như vậy
đọc sách, tìm diễn đàn về ngôn ngữ đó đoc, viết code demo. chạy debug để coi lỗi sai. Trường dạy chỉ lý thuyết không làm sao biết đúng sai.
Ở trường không thể dạy sâu như thế này được vì rất tốn time và không cần thiết :). Họ chỉ dạy bác biết nó là gì, hiểu cơ bản thôi. Còn bác muốn hiểu sâu hơn thì phải đọc thêm sách.
bác download Book ở trong bài viết này, nó nói rất rõ đó.
Hoặc là đọc bản mới hơn của bác @GDGHN_AndroidTeam (Java7).
Cảm ơn các bác, cơ mà tiếng anh đang cùi lắm chưa thể tự hiểu được
Moị người giải thích giùm em là tại sao trong trường hợp này khi chạy lệnh b.move() lại chạy method move() trong class Dog mà không bị lỗi như ví dụ của anh Cương Nguyễn ạ.
Vấn đề mà mọi người thảo luận ở đây là về Method Call Binding trong Java.
Có thể hiểu đơn giản về ví dụ của Cương Nguyễn và bạn Duy Nguyen như sau:
Đầu tiên Animal animal = new Dog(); thì animal là một biến kiểu Animal và có giá trị là 1 object Dog.
Viết lệnh animal.run() thì Java tại thời điểm biên dịch sẽ kiểm tra đến hàm run() của class Animal trước và không có nên báo lỗi ở ví dụ của bạn Cương Nguyễn.
Nếu Animal có hàm run() thì compile time không báo lỗi và tại run time Java sẽ kiểm tra đến class Dog là giá trị của biến, nếu không có thì chạy run() của Animal nếu có thì chạy hàm đã được override lại của Dog.
Developer javaDev = new JavaDeveloper();
Developer newDev = javaDev;
javaDev = new JavaDeveloper();
Trong này, mình có thắc mắc là biến javaDev ở dòng thứ 1 và thứ 3 đều trỏ tới JavaDevloper mà lại bị coi là khác nhau vậy ae nhỉ?
nó trỏ đến 2 vùng nhớ khác nhau trên heap đó chứ …