2015-07-15 17 views
5

Tôi đã từng tham gia Dlang gần đây vì C++ không được ngồi ngay với tôi sau khi sử dụng Python quá lâu. Trong khi dabbling, tôi đi qua những gì tôi nghĩ rằng sẽ là một bài tập rất đơn giản trong đa hình. Tôi cho rằng làm thế nào bạn mong đợi một cái gì đó để làm việc và những gì nó thực sự làm là hai điều hoàn toàn khác nhau vì lý do một người dùng cuối có lẽ không thể hiểu được. Điều đó đang được nói, đây là mã nguồn của "sandbox.D" của tôi:Tại sao cuộc gọi phương thức cha mẹ của lớp con này không đa hình?

import std.stdio; 

class Animal { 
    string voice = "--silence--"; 
    void speak() { 
     writeln(this.voice); 
    } 
} 

class Dog : Animal { 
    string voice = "Whoof!"; 
} 

int main() { 
    auto a = new Animal(); 
    auto d = new Dog(); 

    writeln(a.voice); // Prints "--silence--" 
    writeln(d.voice); // Prints "Whoof!" 

    a.speak(); // Prints "--silence--" 
    d.speak(); // Prints "--silence--" NOT "Whoof!" 

    return 0; 
} 

Tôi đoán vấn đề của tôi là tại sao từ khóa "này" dường như không hoạt động như thế nào bạn mong đợi ngôn ngữ kế thừa C++.

Trả lời

5

Phương pháp đa hình, các biến không. Vì vậy, thay vì làm cho giọng nói trở thành một biến, bạn muốn override speak ở trẻ em.

Ngoài ra, loại trả về auto không hoạt động với đa hình, bạn cần phải chỉ định các loại. (Lý do là trả về tự động tạo ra một mẫu chức năng trong trình biên dịch, mà theo lý thuyết có thể có nhiều khe có thể ghi đè trong bảng chức năng, vì vậy nó không cố gắng đặt nó vào.)

Vì vậy hãy thử điều này:

import std.stdio; 

class Animal { 
    void speak() { // changed to void instead of auto 
    writeln("--silence--"); 
    } 
} 

class Dog : Animal { 
    override void speak() { // the override tells it to override the base method 
    writeln("woof"); 
    } 
} 

int main() { 
    auto d = new Dog(); 
    d.speak(); 
    return 0; 
} 

Nếu bạn có nhiều chức năng được chia sẻ và muốn sử dụng lại một hàm có thay đổi nhỏ trong lớp con, bạn có thể tạo phương thức thay vì trả về thứ gì đó.

Giống như string voice() { return "woof"; }, sau đó nó có thể bị ghi đè ở trẻ em.

+0

Ah, tôi đánh giá cao phản hồi kịp thời như vậy! Tôi đang tranh luận xem có nên xóa một số từ khóa "tự động" hay không. Cuối cùng, tôi đã thử nó mà không cần tự động và tuyên bố các loại thích hợp nhưng nó đã không tạo sự khác biệt. Tôi đoán rằng kế thừa đối tượng theo định hướng không có vẻ khá hữu ích như tôi đã tưởng tượng: ( –

+2

Nó rất hữu ích, chỉ cần nhớ rằng chỉ có phương pháp có thể overridable, biến không. (Tôi không chắc chắn nếu nó là như nhau trong Python, nhưng nó thường làm việc theo cách đó trong rất nhiều ngôn ngữ OOP) Mặc dù, thừa kế không có giới hạn của nó, bạn có thể giải quyết rất nhiều thứ với nó, nhưng nó không phải lúc nào cũng là cách tốt nhất –

+0

Nó rất hữu ích. Bạn chỉ cần hiểu làm thế nào để sử dụng nó, và bạn hiểu sai cách nó hoạt động như thế nào. Bạn chỉ cần ghi đè hàm thay vì biến thành viên, và nó hoạt động tốt.Độ dài mã không khác nhau nhiều Và nếu bạn muốn thay vào đó, hãy ghi đè lên biến thành viên, chỉ cần bọc nó trong một hàm để trả về giá trị của nó và sử dụng hàm thay vì sử dụng biến trực tiếp. sẽ có nghĩa là bao nhiêu ng họ trong các chức năng bên dưới mui xe anyway. –

1

Một cách khác là sử dụng mẫu tham số này:

import std.stdio; 

class Animal { 
    string voice; 

    void speak(this C)() { 
     writeln((cast(C)this).voice); 
    } 
} 

class Dog : Animal { 
    string voice = "Whoof!"; 
} 

int main() { 
    auto a = new Animal(); 
    auto d = new Dog(); 

    a.speak(); // Prints "" 
    d.speak(); // Prints "Whoof!" 

    return 0; 
} 

Hoặc khi bạn không cần phải có tiếng nói như một thành viên:

import std.stdio; 

class Animal { 
    static immutable voice = ""; 

    void speak(this C)() { 
     writeln(C.voice); 
    } 
} 

class Dog : Animal { 
    static immutable voice = "Whoof!"; 
} 

int main() { 
    auto a = new Animal(); 
    auto d = new Dog(); 

    a.speak(); // Prints "" 
    d.speak(); // Prints "Whoof!" 

    return 0; 
} 
+0

Cảm ơn bạn đã phản hồi. Sự lúng túng của sự nhầm lẫn của tôi chỉ với "điều này" không đề cập đến giọng nói của con chó mà thay vào đó là giọng của Động vật cơ bản. Tôi đoán tài sản không hoàn toàn giống nhau trong Dlang như tôi nghĩ họ sẽ là :) –

Các vấn đề liên quan