2008-10-28 8 views
7

Xét đoạn mã sau:Từ phương pháp lớp cơ sở dụ gọi trẻ em đã được ghi đè

Public Class Animal 

Public Overridable Function Speak() As String 
    Return "Hello" 
End Function 

End Class 

Public Class Dog 
    Inherits Animal 

    Public Overrides Function Speak() As String 
     Return "Ruff" 
    End Function 

End Class 

Dim dog As New Dog 
Dim animal As Animal 
animal = CType(dog, Animal) 
// Want "Hello", getting "Ruff" 
animal.Speak() 

Làm thế nào tôi có thể chuyển đổi/CTYPE trường hợp của chó đến động vật và có Animal.Speak được gọi là?

Trả lời

10

Bạn không; phương thức của lớp con ghi đè phương thức của lớp cha, theo định nghĩa của kế thừa.

Nếu bạn muốn có phương thức ghi đè, hãy hiển thị phương thức đó trong lớp con, ví dụ:

Public Class Dog 
    Inherits Animal 
    Public Overrides Function Speak() As String 
     Return "Ruff" 
    End Function 
    Public Function SpeakAsAnimal() As String 
     Return MyBase.Speak() 
    End Function 
End Class 
0

Tôi không nghĩ bạn có thể.

Vấn đề là đối tượng vẫn là chó. hành vi mà bạn mô tả (nhận được "ruff" từ đối tượng được đúc thay vì "hello") là tiêu chuẩn vì bạn muốn có thể sử dụng lớp động vật để cho một loạt các loại động vật khác nhau nói.

Ví dụ, nếu bạn đã có một lớp thứ ba là như sau:

Public Class Cat 
    Inherits Animal 

    Public Overrides Function Speak() As String 
     Return "Meow" 
    End Function 
End Class 

Sau đó, bạn sẽ có thể truy cập chúng như vậy:

protected sub Something 
    Dim oCat as New Cat 
    Dim oDog as New Dog 

    MakeSpeak(oCat) 
    MakeSpeak(oDog) 
End sub 

protected sub MakeSpeak(ani as animal) 
    Console.WriteLine(ani.Speak()) 
end sub 

gì bạn đang nói về việc cơ bản phá vỡ chuỗi thừa kế. Bây giờ, điều này có thể được thực hiện, bằng cách thiết lập chức năng Đọc để chấp nhận tham số cho phép trả về giá trị cơ bản hoặc không hoặc hàm SPEAK riêng biệt cho giá trị cơ sở, nhưng ngoài hộp, bạn sẽ không để có được những hành động theo cách này.

+0

"Một lựa chọn khác, là để khai báo các đối tượng như một con vật, và sau đó bỏ nó vào một DOG khi bạn cần tính mở rộng của con chó . " Phần cuối cùng đó không đúng. Kiểu khai báo của biến là vô nghĩa khi nói đến cách một cá thể đã cho hoạt động đa hình. –

+0

Đó là sự thật, tôi đã suy nghĩ về mặt giao diện. –

1

Tôi sẽ hỏi tại sao bạn đang cố gắng để có được loại hành vi này. Dường như với tôi rằng thực tế bạn cần gọi thực hiện lớp cha của một phương thức là một dấu hiệu cho thấy bạn có một lỗ hổng thiết kế ở một nơi khác trong hệ thống.

Tóm lại, như những người khác đã tuyên bố không có cách nào để gọi triển khai lớp cha mẹ theo cách bạn đã cấu trúc các lớp của bạn. Bây giờ trong lớp Dog bạn có thể gọi

MyBase.Speak() 

sẽ gọi thực hiện lớp cha mẹ, nhưng từ bên ngoài lớp Dog không có cách nào để thực hiện.

1

Tôi nghĩ nếu bạn thả "Ghi đè" và thay đổi "Ghi đè" thành "Mới", bạn sẽ nhận được những gì bạn muốn.

Public Class Animal 

Public Function Speak() As String 
    Return "Hello" 
End Function 

End Class 

Public Class Dog 
    Inherits Animal 

    Public New Function Speak() As String 
     Return "Ruff" 
    End Function 

End Class 

Dim dog As New Dog 
Dim animal As Animal 
dog.Speak() ' should be "Ruff" 
animal = CType(dog, Animal) 
animal.Speak() ' should be "Hello" 
+2

Từ khóa mới là cách bạn thực hiện trong C#. Tương đương trong VB là Shadows. Nó thường là một ý tưởng tồi để sử dụng Shadows. Nó là một thực hành Object Orientated Design kém. Nó vi phạm Nguyên tắc thay thế Liskov. –

0

Tôi biết điều này đã được đăng một vài tháng trước, nhưng tôi vẫn sẽ cố gắng trả lời, có thể chỉ vì mục đích hoàn chỉnh.

Bạn được thông báo rằng bạn có thể truy cập phương pháp được ghi đè từ trong vòng lớp dog và sau đó bạn có thể hiển thị nó bằng một tên khác. Nhưng những gì về việc sử dụng một điều kiện?

Bạn chỉ có thể làm:

Public Class Animal 

Public Overridable Function Speak(Optional ByVal speakNormal as Boolean = False) As String 
    Return "Hello" 
End Function 

End Class 

Public Class Dog 
    Inherits Animal 

    Public Overrides Function Speak(Optional ByVal speakNormal as Boolean = False) As String 
     If speakNormal then 
      return MyBase.Speak() 
     Else 
      Return "Ruff" 
     End If 
    End Function 

End Class 

Và sau đó gọi cho họ thích:

Dim dog As New Dog 
Dim animal As new Animal 
animal.Speak() //"Hello" 
dog.Speak()//"Ruff" 
dog.Speak(true)//"Hello" 

Ngoài ra, bạn có thể getTheAnimalInTheDog và làm Speak():

Bạn chỉ có thể làm:

Public Class Animal 

Public Overridable Function Speak() As String 
    Return "Hello" 
End Function 

Public MustOverride Function GetTheAnimalInMe() As Animal 

End Class 

Public Class Dog 
    Inherits Animal 

    Public Overrides Function Speak() As String 
     Return "Ruff" 
    End Function 

    Public Overrides Function GetTheAnimalInMe() As Animal 
     Dim a As New Animal 
     //Load a with the necessary custom parameters (if any) 
     Return a 
    End Function 
End Class 

Và sau đó một lần nữa:

Dim dog As New Dog 
Dim animal As new Animal 
animal.Speak() //"Hello" 
dog.Speak()//"Ruff" 
dog.GetTheAnimalInMe().Speak()//"Hello" 

Hy vọng nó giúp;)