Đa hình là gì, nó dùng để làm gì và nó được sử dụng như thế nào?


564

Đa hình là gì, nó dùng để làm gì và nó được sử dụng như thế nào?


19
@ John: +1 Tôi đồng ý rằng đó là một hiện tượng thú vị nhất. Tôi chắc chắn rằng Unkwntech không phải là cá nhân có kiến ​​thức, có khả năng duy nhất có những lỗ hổng trong những gì người khác sẽ coi là một từ vựng cơ bản. Chỉ cần đi để hiển thị lập trình là một chủ đề rất rộng.
AnthonyWJones

9
Anh ta có thể sử dụng nó, chỉ cần không đặt tên cho nó.
Aiden Bell

10
@Aamir: Tôi không chắc rằng hợp lý khi cho rằng ai đó với 8k sẽ biết tất cả các nguyên tắc cơ bản trong tất cả các lĩnh vực lập trình. Ngoài ra tôi không nghĩ rằng nó chỉ ra hệ thống danh tiếng là không hoàn hảo. Ai đó có thể đạt được danh tiếng đáng kể bằng cách hỏi rất nhiều câu hỏi hay. Tôi nghĩ rằng phản ứng tự nhiên của chúng ta đối với sự mặc khải này chỉ đơn giản chứng tỏ rằng chúng ta (lập trình viên) có xu hướng tự nhiên hơi hẹp hòi (không phải là điều xấu khi chúng ta cần phải thực sự tốt trong một số lĩnh vực kỹ thuật cụ thể) và điều đó có nhược điểm.
AnthonyWJones

43
Các bạn dường như có một cái nhìn rất hạn chế về lập trình. Tôi biết những người đang thực hiện phát triển nhúng mà không có kiến ​​thức về (hoặc cần) các khái niệm OO nào cả. Tóm tắt của họ là vắt từng nguyên tử hiệu suất cuối cùng từ mã và đó là - mã họ đang làm việc sẽ không bao giờ đi vào thế giới của các đối tượng và họ may mắn đủ gần để nghỉ hưu mà họ không phải lo lắng về học các khái niệm mới giống như đối tượng, đa hình và tên biến có nhiều hơn hai chữ cái :-)
paxdiablo

29
Làm thế nào để bạn học được một cái gì đó? Không ai đến thế giới này biết PHP OOP và các mẫu thiết kế, vì vậy tất cả các bạn tại một số điểm phải học nó, ở trường đại học, một câu trả lời ở đây, v.v. Đừng nói về ai đó "không dám biết các quy trình mã phức tạp ", Và thay vì xem xét họ ở đây muốn tìm hiểu nó, đó là một điều tốt và điểm của trang web này. Sử dụng thời gian của bạn để giúp đỡ họ, vì tôi chắc chắn rằng bạn đã được giúp đỡ trong quá khứ. Nếu trong suốt lịch sử của con người, thay vì chia sẻ kiến ​​thức, câu trả lời là "Cái gì? Ha! Bạn không biết điều đó sao? .." tất cả chúng ta vẫn ở trong thời kỳ đen tối ..
James

Câu trả lời:


544

Nếu bạn nghĩ về nguồn gốc Hy Lạp của thuật ngữ này, nó sẽ trở nên rõ ràng.

  • Poly = many: polygon = many-side, polystyrene = many styrenes (a) , polyglot = nhiều ngôn ngữ, v.v.
  • Morph = thay đổi hoặc hình thức: morphology = nghiên cứu về hình thức sinh học, Morpheus = vị thần của những giấc mơ Hy Lạp có thể có bất kỳ hình thức nào.

Vì vậy, đa hình là khả năng (trong lập trình) để trình bày cùng một giao diện cho các hình thức cơ bản khác nhau (các kiểu dữ liệu).

Ví dụ, trong nhiều ngôn ngữ, số nguyên và số float hoàn toàn là đa hình vì bạn có thể thêm, trừ, nhân và v.v., bất kể thực tế là các loại khác nhau. Chúng hiếm khi được coi là đối tượng trong thuật ngữ thông thường.

Nhưng, trong đó theo cùng một cách, một lớp học như BigDecimalhoặc Rationalhoặc Imaginarycũng có thể cung cấp những hoạt động, mặc dù họ hoạt động trên các kiểu dữ liệu khác nhau.

Ví dụ cổ điển là Shapelớp và tất cả các lớp có thể kế thừa từ nó (hình vuông, hình tròn, hình khối, hình đa giác không đều, splat, v.v.).

Với tính đa hình, mỗi lớp này sẽ có dữ liệu cơ bản khác nhau. Một hình dạng điểm chỉ cần hai tọa độ (tất nhiên giả sử nó ở trong không gian hai chiều). Một vòng tròn cần một tâm và bán kính. Một hình vuông hoặc hình chữ nhật cần hai tọa độ cho các góc trên cùng bên trái và dưới cùng bên phải và (có thể) một vòng quay. Một đa giác không đều cần một loạt các dòng.

Bằng cách làm cho lớp chịu trách nhiệm về mã cũng như dữ liệu của nó, bạn có thể đạt được tính đa hình. Trong ví dụ này, mỗi lớp sẽ có Draw()chức năng riêng và mã máy khách có thể chỉ cần làm:

shape.Draw()

để có được hành vi chính xác cho bất kỳ hình dạng.

Điều này trái ngược với cách làm cũ mà mã tách biệt với dữ liệu và bạn sẽ có các chức năng như drawSquare()drawCircle().

Định hướng đối tượng, đa hình và kế thừa đều là những khái niệm liên quan chặt chẽ và chúng rất quan trọng để biết. Đã có nhiều "viên đạn bạc" trong suốt sự nghiệp dài của tôi, về cơ bản chỉ bị xì hơi nhưng mô hình OO hóa ra lại là một thứ tốt. Tìm hiểu nó, hiểu nó, yêu nó - bạn sẽ vui vì bạn đã làm :-)


(a) Ban đầu tôi đã viết nó như một trò đùa nhưng hóa ra là chính xác và do đó, không có gì buồn cười. Các monome styren tình cờ được tạo ra từ carbon và hydro , và polystyrene được tạo ra từ các nhóm đó , .C8H8(C8H8)n

Có lẽ tôi nên nói rằng một polyp có rất nhiều lần xuất hiện của bức thư pmặc dù, bây giờ tôi đã phải giải thích về trò đùa, thậm chí điều đó cũng không có vẻ buồn cười.

Đôi khi, bạn nên thoát ra trong khi bạn ở phía sau :-)


50
Tiếng Hy Lạp, không phải tiếng Latin :) ('y' và 'ph' là những quà tặng). Và trong tiếng Hy Lạp, 'morph-' chỉ là 'hình dạng', hay 'hình thức' - nghĩa tiếng Anh của ' thay đổi hình dạng' cho 'morph' là một sự phát triển sau này
AakashM

16
Đa hình không liên quan đến OOP, nhưng OOP liên quan đến đa hình vì nó vốn hỗ trợ nó (giả sử đó là ngôn ngữ OOP đàng hoàng). Nhìn vào FP cho các ví dụ khác về đa hình.
thay thế

9
Hai dòng này đã lừa tôi:Poly = many and Morph = change or form
Jo Smo

3
Polyp là viết tắt của polypo (u) s. Và pous là chân ở Hy Lạp. ;-)
Dirk

2
@Shaun, tôi nghĩ rằng bạn có thể đang sử dụng thuật ngữ "giao diện" theo nghĩa quá xa nghĩa đen / hạn chế - Tôi có nghĩa đó là một thuật ngữ tiếng Anh chứ không phải là một định nghĩa cụ thể cho một số ngôn ngữ máy tính tùy ý. Nó không có nghĩa chính xác cùng một chức năng với chính xác các tham số giống nhau, nó chỉ đơn giản là một cách ảnh hưởng đến "các đối tượng" theo cùng một cách bất kể loại bê tông cơ bản của chúng. Điều này có thể bao gồm quá tải phương thức với các loại tham số khác nhau cũng như dạng đa hình thuần túy hơn.
paxdiablo

250

Đa hình là khi bạn có thể coi một đối tượng là phiên bản chung của một cái gì đó, nhưng khi bạn truy cập vào nó, mã xác định loại chính xác đó là gì và gọi mã liên quan.

Đây là một ví dụ trong C #. Tạo bốn lớp trong một ứng dụng giao diện điều khiển:

public abstract class Vehicle
{
    public abstract int Wheels;
}

public class Bicycle : Vehicle
{
    public override int Wheels()
    {
        return 2;
    }
}

public class Car : Vehicle
{
    public override int Wheels()
    {
        return 4;
    }
}

public class Truck : Vehicle
{
    public override int Wheels()
    {
        return 18;
    }
}

Bây giờ tạo phần sau trong Main () của mô-đun cho ứng dụng bảng điều khiển:

public void Main()
{
    List<Vehicle> vehicles = new List<Vehicle>();

    vehicles.Add(new Bicycle());
    vehicles.Add(new Car());
    vehicles.Add(new Truck());

    foreach (Vehicle v in vehicles)
    {
        Console.WriteLine(
            string.Format("A {0} has {1} wheels.",
                v.GetType().Name, v.Wheels));
    }
}

Trong ví dụ này, chúng tôi tạo một danh sách Xe hạng cơ sở, không biết về mỗi lớp phụ có bao nhiêu bánh, nhưng biết rằng mỗi lớp phụ có trách nhiệm biết có bao nhiêu bánh.

Sau đó chúng tôi thêm một Xe đạp, Xe hơi và Xe tải vào danh sách.

Tiếp theo, chúng ta có thể lặp qua từng Xe trong danh sách và xử lý tất cả chúng một cách giống hệt nhau, tuy nhiên khi chúng ta truy cập vào thuộc tính của từng Bánh xe, lớp Xe sẽ ủy thác việc thực thi mã đó cho lớp phụ có liên quan.

Mã này được gọi là đa hình, vì mã chính xác được thực thi được xác định bởi lớp con được tham chiếu trong thời gian chạy.

Tôi hy vọng rằng điều này sẽ giúp bạn.


6
Tôi nghĩ rằng đây là một ví dụ rất hay để hiển thị rõ ràng giao diện cha mẹ và rằng phải đến khi đối tượng được khởi tạo thì mới cần có phiên bản cụ thể, tức là xe vs xe
dây00

1
Tôi sẽ nói đây là ví dụ rõ ràng nhất, mặc dù nếu bạn là một lập trình viên PHP, liên kết này có thể dễ dàng xem lại FIRST hơn, và sau đó vẫn xem xét điều này sau: code.tutsplus.com/tutorials/ trộm
Oliver Williams

Ngoài ra (ngoài phạm vi của OP) cần lưu ý rằng chúng tôi đang hạn chế phân tích đối với các đối tượng đã biết; chúng tôi sẽ không chuyển một đối tượng (như tệp nhập) và sau đó xác định loại đó là gì (Excel, CSV, YAML, SQL, v.v.). Để làm điều này, người ta sẽ cần một số loại lớp xuất xưởng Class_Excel, Class_CSVđược gọi hoặc có một Readerlớp được gọi. Dù bằng cách nào, một số loại lặp nếu / thì / khác sẽ phải được lưu trữ ở đâu đó.
Oliver Williams

@Antony Gibbs: đây là một ví dụ thực sự tốt (một danh sách các loại chung) có ý nghĩa với tôi .... nếu không thì vấn đề lớn của việc mỗi lớp có chức năng bánh xe riêng là gì mà không kế thừa từ lớp cơ sở? Có thêm khái niệm nào ngoài danh sách sẽ tốt cho đa hình không?
TTT

195

Từ sự hiểu biết và áp dụng đa hình trong PHP , cảm ơn Steve Guidetti.

Đa hình là một từ dài cho một khái niệm rất đơn giản.

Đa hình mô tả một mẫu trong lập trình hướng đối tượng, trong đó các lớp có chức năng khác nhau trong khi chia sẻ một giao diện chung.

Vẻ đẹp của đa hình là mã làm việc với các lớp khác nhau không cần biết nó đang sử dụng lớp nào vì tất cả chúng đều được sử dụng theo cùng một cách. Một tương tự thế giới thực cho đa hình là một nút. Mọi người đều biết cách sử dụng một nút: bạn chỉ cần áp dụng áp lực cho nó. Tuy nhiên, một nút mà thực hiện, thì, tùy thuộc vào những gì nó được kết nối và bối cảnh sử dụng - nhưng kết quả không ảnh hưởng đến cách sử dụng. Nếu sếp của bạn bảo bạn nhấn nút, bạn đã có tất cả thông tin cần thiết để thực hiện nhiệm vụ.

Trong thế giới lập trình, tính đa hình được sử dụng để làm cho các ứng dụng trở nên mô đun và mở rộng hơn. Thay vì các câu điều kiện lộn xộn mô tả các khóa hành động khác nhau, bạn tạo các đối tượng có thể hoán đổi cho nhau mà bạn chọn dựa trên nhu cầu của bạn. Đó là mục tiêu cơ bản của đa hình.


10
nút tương tự không liên quan nhiều hơn đến khái niệm trừu tượng?
thewpfguy


8
@Mantriur: Đây thực sự là ăn cắp ý tưởng, và chúng tôi có quy tắc chống lại rằng: stackoverflow.com/help/referencing Nhưng với số điểm của nó bây giờ và thực tế là các bài đăng cũ được miễn mất diện về xóa câu trả lời, tôi không chắc chắn nếu xóa nó bây giờ hoàn toàn sẽ cải thiện bất cứ điều gì. Cách thay thế tốt nhất tiếp theo sẽ là chỉ chỉnh sửa thay cho người dùng, mặc dù tôi tin tưởng mạnh mẽ rằng người dùng có trách nhiệm trích dẫn nguồn trong câu trả lời của riêng họ.
BoltClock

1
Tôi tin rằng không chính xác khi ngụ ý rằng đa hình là đặc trưng cho các lớp và / hoặc lập trình hướng đối tượng, xem cách đa hình ad hoc hoặc đa hình tham số không nhất thiết yêu cầu các lớp và / hoặc đối tượng. Tôi nghĩ những gì câu trả lời này đang nói đến là phân nhóm (còn được gọi là đa hình phụ hoặc đa hình bao gồm).
StubbornShowaGuy

64

Nếu có ai nói CẮT với những người này

  1. Bác sĩ phẫu thuật
  2. Nhà tạo mẫu tóc
  3. Diễn viên

Chuyện gì sẽ xảy ra?

  • Bác sĩ phẫu thuật sẽ bắt đầu rạch.
  • Nhà tạo mẫu tóc sẽ bắt đầu cắt tóc của ai đó.
  • Các diễn viên sẽ đột ngột ngừng hành động ra khỏi cảnh hiện tại, chờ đợi hướng dẫn của đạo diễn.

Vì vậy, đại diện trên cho thấy tính đa hình (cùng tên, hành vi khác nhau) trong OOP là gì.

Nếu bạn đang đi phỏng vấn và người phỏng vấn yêu cầu bạn kể / đưa ra một ví dụ trực tiếp cho sự đa hình trong cùng một phòng chúng ta đang ngồi, hãy nói-

Trả lời - Cửa / Windows

Tự hỏi thế nào?

Thông qua Cửa / Cửa sổ - một người có thể đến, không khí có thể đến, ánh sáng có thể đến, mưa có thể đến, v.v.

Để hiểu rõ hơn và theo cách đơn giản, tôi đã sử dụng ví dụ trên .. Nếu bạn cần tham khảo mã theo các câu trả lời ở trên.


5
Tôi không nghĩ đây là một ví dụ tuyệt vời bởi vì nó có thể khiến những người thiếu kinh nghiệm nghĩ rằng nếu hai lớp có một .foo()phương thức, thì họ nên chia sẻ một giao diện chung. Tuy nhiên, điều này không đúng và dẫn đến sự trừu tượng không chính xác. Một giao diện nên xác định một vai trò sẽ được phát, có thể có nhiều triển khai khác nhau, nhưng tất cả đều được kéo từ cùng một bộ đầu vào và trả về một cái gì đó từ cùng một bộ đầu ra. Đầu vào x.cut(...)của một bác sĩ phẫu thuật, stylist hoặc diễn viên không giống nhau, và cũng không phải là đầu ra.
Matt Klein

37

Giải thích đơn giản bằng cách tương tự

Tổng thống Hoa Kỳ sử dụng đa hình. Làm sao? Vâng, ông có nhiều cố vấn:

  1. Cố vấn quân sự
  2. Cố vấn pháp lý
  3. Các nhà vật lý hạt nhân (làm cố vấn)
  4. Cố vấn y tế
  5. Vân vân.

Mọi người chỉ nên chịu trách nhiệm cho một điều: Ví dụ:

Tổng thống không phải là một chuyên gia về mạ kẽm, hay vật lý lượng tử. Anh ta không biết nhiều thứ - nhưng anh ta chỉ biết một điều: làm thế nào để điều hành đất nước.

Nó giống với mã: mối quan tâm và trách nhiệm nên được tách ra cho các lớp / người có liên quan. Nếu không, bạn sẽ có tổng thống biết mọi thứ trên thế giới - toàn bộ Wikipedia. Hãy tưởng tượng có toàn bộ wikipedia trong một lớp mã của bạn: nó sẽ là một cơn ác mộng để duy trì.

Tại sao đó là một ý tưởng tồi cho một tổng thống để biết tất cả những điều cụ thể?

Nếu tổng thống đặc biệt nói cho mọi người biết phải làm gì, điều đó có nghĩa là tổng thống cần biết chính xác phải làm gì. Nếu tổng thống cần tự mình biết những điều cụ thể, điều đó có nghĩa là khi bạn cần thay đổi, thì bạn sẽ cần thực hiện ở hai nơi chứ không chỉ một.

Ví dụ: nếu EPA thay đổi luật ô nhiễm thì khi điều đó xảy ra: bạn sẽ phải thay đổi đối với Lớp EPA và cả lớp Tổng thống. Thay đổi mã ở hai nơi thay vì một nơi có thể nguy hiểm - vì khó duy trì hơn nhiều.

Có một cách tiếp cận tốt hơn?

Có một cách tiếp cận tốt hơn: tổng thống không cần biết chi tiết cụ thể của bất cứ điều gì - ông có thể yêu cầu lời khuyên tốt nhất, từ những người được giao nhiệm vụ đặc biệt làm những việc đó.

Ông có thể sử dụng một cách tiếp cận đa hình để điều hành đất nước.

Ví dụ - sử dụng phương pháp đa hình:

Tất cả những gì tổng thống làm là yêu cầu mọi người khuyên anh ta - và đó là những gì anh ta thực sự làm trong cuộc sống thực - và đó là những gì một tổng thống tốt nên làm. tất cả các cố vấn của ông đều trả lời khác nhau, nhưng tất cả họ đều biết ý nghĩa của tổng thống bằng cách: Advise (). Anh ta có hàng trăm người vào văn phòng của mình. Nó không thực sự quan trọng họ là ai. Tất cả các tổng thống biết là khi ông yêu cầu họ "Tư vấn", họ biết làm thế nào để trả lời cho phù hợp :

public class MisterPresident
{
    public void RunTheCountry()
    {
        // assume the Petraeus and Condi classes etc are instantiated.
        petraeus.Advise(); // # Petraeus says send 100,000 troops to Fallujah
        condolezza.Advise(); // # she says negotiate trade deal with Iran
        healthOfficials.Advise(); // # they say we need to spend $50 billion on ObamaCare
    }
}

Cách tiếp cận này cho phép tổng thống điều hành đất nước theo nghĩa đen mà không cần biết gì về quân sự, hoặc chăm sóc sức khỏe hoặc ngoại giao quốc tế: các chi tiết được để lại cho các chuyên gia. Điều duy nhất tổng thống cần biết là: "Advise ()".

Những gì bạn KHÔNG "T muốn:

public class MisterPresident
{
    public void RunTheCountry()
    {
        // people walk into the Presidents office and he tells them what to do
        // depending on who they are.

        // Fallujah Advice - Mr Prez tells his military exactly what to do.
        petraeus.IncreaseTroopNumbers();
        petraeus.ImproveSecurity();
        petraeus.PayContractors();

        // Condi diplomacy advice - Prez tells Condi how to negotiate

        condi.StallNegotiations();
        condi.LowBallFigure();
        condi.FireDemocraticallyElectedIraqiLeaderBecauseIDontLikeHim();

        // Health care

        healthOfficial.IncreasePremiums();
        healthOfficial.AddPreexistingConditions();
    }
}

KHÔNG! KHÔNG! KHÔNG! Trong kịch bản trên, tổng thống đang thực hiện tất cả các công việc: ông biết về việc tăng số lượng quân đội và các điều kiện tồn tại từ trước. Điều này có nghĩa là nếu các chính sách ở Trung Đông thay đổi, thì tổng thống sẽ phải thay đổi các mệnh lệnh của mình, cũng như lớp Petraeus. Chúng ta chỉ nên thay đổi lớp Petraeus, vì Tổng thống không nên sa lầy vào loại chi tiết đó. Anh ta không cần biết về các chi tiết. Tất cả những gì anh ta cần biết là nếu anh ta thực hiện một đơn đặt hàng, mọi thứ sẽ được chăm sóc. Tất cả các chi tiết nên để lại cho các chuyên gia.

Điều này cho phép tổng thống làm những gì ông làm tốt nhất: thiết lập chính sách chung, nhìn tốt và chơi gôn: P.

Nó được thực hiện như thế nào - thông qua một lớp cơ sở hoặc một giao diện chung

Điều đó có hiệu lực là đa hình, một cách ngắn gọn. Làm thế nào chính xác là nó được thực hiện? Thông qua "triển khai một giao diện chung" hoặc bằng cách sử dụng một lớp cơ sở (kế thừa) - xem các câu trả lời ở trên, chi tiết này rõ hơn. (Để hiểu rõ hơn về khái niệm này, bạn cần biết giao diện là gì và bạn sẽ cần hiểu kế thừa là gì. Nếu không có điều đó, bạn có thể phải vật lộn.)

Nói cách khác, Petraeus, Condi và HealthOfficials đều sẽ là các lớp "thực hiện giao diện" - hãy gọi nó là IAdvisorgiao diện chỉ chứa một phương thức : Advise(). Nhưng bây giờ chúng tôi đang đi vào chi tiết cụ thể.

Đây sẽ là lý tưởng

    public class MisterPresident
    {
            // You can pass in any advisor: Condi, HealthOfficials,
            //  Petraeus etc. The president has no idea who it will 
            // be. But he does know that he can ask them to "advise" 
            // and that's all Mr Prez cares for.

        public void RunTheCountry(IAdvisor governmentOfficer)
        {             
            governmentOfficer.Advise();              
        }
    }


    public class USA
    {
        MisterPresident president;

        public USA(MisterPresident president)
        {
            this.president = president;
        }

        public void ImplementPolicy()
        {
            IAdvisor governmentOfficer = getAdvisor(); // Returns an advisor: could be condi, or petraus etc.
            president.RunTheCountry(governmentOfficer);
        }
    }

Tóm lược

Tất cả những gì bạn thực sự cần biết là đây:

  • Tổng thống không cần biết chi tiết cụ thể - những thứ đó được để lại cho người khác.
  • Tất cả những gì tổng thống cần biết là hỏi ai đã từng bước vào cửa để tư vấn cho anh ta - và chúng tôi biết rằng họ sẽ hoàn toàn biết phải làm gì khi được yêu cầu tư vấn (vì tất cả đều là người thực tế, cố vấn (hoặc IAdvisorors :))

Tôi thực sự hy vọng nó sẽ giúp bạn. Nếu bạn không hiểu bất cứ điều gì hãy viết bình luận và tôi sẽ thử lại.


4
Ví dụ tuyệt vời! Cảm ơn.
Iman Sedighi

1
Sự tương tự rất thú vị. Cảm ơn bạn.
thanhtang

1
@TTT bởi vì (1) mỗi khi bạn có một cố vấn mới thì bạn phải thay đổi lớp chủ tịch - bạn không muốn thực hiện thay đổi x2. chỉ một. (2) thứ hai, nếu bạn phải thay đổi một cố vấn hiện có, thì bạn có thể phải quay lại và thay đổi một trong ba cuộc gọi đó trong lớp tổng thống - bạn chỉ thực sự muốn thực hiện một thay đổi, không phải hai. (3) nếu bạn có ba cuộc gọi riêng biệt thì bạn sẽ phải hỏi, trong lớp chủ tịch: if healthAdvisor? then do this:if petraus then do that etc.mô hình này sẽ cần phải được lặp lại và điều đó là không cần thiết và phức tạp. xem chỉnh sửa ở trên.
BKSpurgeon

1
@TTT vâng bạn đúng. nhưng tôi phải từ từ giới thiệu khái niệm này với độc giả nếu không họ sẽ không hiểu. tôi đã thêm những thay đổi. vui lòng thông báo nếu cần làm rõ
BKSpurgeon

1
@TTT lớp cơ sở vs giao diện là một lập trình viên quyết định thiết kế phải thực hiện khi thực hiện đa hình. xem tại đây để biết thêm chi tiết: stackoverflow.com/questions/56867/interface-vs-base-
class

24

Đa hình là khả năng đối xử với một lớp đối tượng như thể nó là lớp cha.

Chẳng hạn, giả sử có một lớp gọi là Animal và một lớp gọi là Dog thừa hưởng từ Animal. Đa hình là khả năng coi bất kỳ đối tượng Dog nào là đối tượng Động vật như vậy:

Dog* dog = new Dog;
Animal* animal = dog;

Tôi tự hỏi làm thế nào điều này có liên quan đến lời giải thích (phổ biến) mà @Ajay Patel đã đưa raclasses have different functionality while sharing a common interface
BornToCode

1
@BornToCode Lớp cha là / cung cấp giao diện chung đó.
Grokmann

1
Đa hình không yêu cầu phân nhóm.
Shaun Luttin

22

Đa hình:

Đó là khái niệm về lập trình hướng đối tượng. Khả năng đáp ứng của các đối tượng khác nhau, mỗi cách theo cách riêng của nó, đối với các thông điệp giống hệt nhau được gọi là đa hình.

Đa hình kết quả từ thực tế là mọi lớp sống trong không gian tên riêng của nó. Các tên được gán trong một định nghĩa lớp không xung đột với các tên được gán ở bất cứ đâu ngoài nó. Điều này đúng cả hai biến đối tượng trong cấu trúc dữ liệu của đối tượng và phương thức của đối tượng:

  • Giống như các trường của cấu trúc C nằm trong một không gian tên được bảo vệ, các biến đối tượng của đối tượng cũng vậy.

  • Tên phương thức cũng được bảo vệ. Không giống như tên của các hàm C, tên phương thức không phải là ký hiệu toàn cục. Tên của một phương thức trong một lớp không thể xung đột với các tên phương thức trong các lớp khác; hai lớp rất khác nhau có thể thực hiện các phương thức được đặt tên giống hệt nhau.

Tên phương thức là một phần của giao diện của đối tượng. Khi một tin nhắn được gửi yêu cầu một đối tượng làm một cái gì đó, thông điệp đặt tên cho phương thức mà đối tượng sẽ thực hiện. Bởi vì các đối tượng khác nhau có thể có các phương thức có cùng tên, ý nghĩa của một thông điệp phải được hiểu tương đối với đối tượng cụ thể nhận được thông điệp. Cùng một thông điệp được gửi đến hai đối tượng khác nhau có thể gọi hai phương thức riêng biệt.

Lợi ích chính của đa hình là nó đơn giản hóa giao diện lập trình. Nó cho phép các quy ước được thiết lập có thể được sử dụng lại trong lớp sau lớp học. Thay vì phát minh ra một tên mới cho mỗi chức năng mới mà bạn thêm vào một chương trình, các tên tương tự có thể được sử dụng lại. Giao diện lập trình có thể được mô tả như một tập hợp các hành vi trừu tượng, khá khác biệt với các lớp thực hiện chúng.

Ví dụ:

Ví dụ 1: Đây là một ví dụ đơn giản viết bằng Python 2.x .

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Dog('Lassie')]

for animal in animals:
    print animal.name + ': ' + animal.talk()

Ví dụ-2: Tính đa hình được triển khai trong Java bằng cách sử dụng nạp chồng phương thức và các khái niệm ghi đè phương thức .

Hãy để chúng tôi xem xét ví dụ xe để thảo luận về đa hình. Lấy bất kỳ thương hiệu nào như Ford, Honda, Toyota, BMW, Benz, v.v., Mọi thứ đều thuộc loại Xe.

Nhưng mỗi người có các tính năng tiên tiến của riêng mình và công nghệ tiên tiến hơn liên quan đến hành vi di chuyển của họ.

Bây giờ hãy để chúng tôi tạo ra một loại xe cơ bản

Car.java

public class Car {

    int price;
    String name;
    String color;

    public void move(){
    System.out.println("Basic Car move");
    }

}

Hãy để chúng tôi thực hiện ví dụ Ford Car.

Ford mở rộng loại Xe để kế thừa tất cả các thành viên (thuộc tính và phương pháp).

Ford.java

public class Ford extends Car{
  public void move(){
    System.out.println("Moving with V engine");
  }
}

Lớp Ford ở trên mở rộng lớp Xe hơi và cũng thực hiện phương thức move (). Mặc dù phương thức di chuyển đã có sẵn cho Ford thông qua Kế thừa, Ford vẫn thực hiện phương pháp này theo cách riêng của mình. Đây được gọi là phương thức ghi đè.

Honda.java

public class Honda extends Car{
  public void move(){
    System.out.println("Move with i-VTEC engine");
  }
}

Cũng giống như Ford, Honda cũng mở rộng loại Xe và thực hiện phương thức di chuyển theo cách riêng của mình.

Ghi đè phương thức là một tính năng quan trọng để kích hoạt Đa hình. Sử dụng ghi đè Phương thức, các loại Sub có thể thay đổi cách các phương thức hoạt động có sẵn thông qua kế thừa.

Đa hìnhExample.java

public class PolymorphismExample {
  public static void main(String[] args) {
    Car car = new Car();
    Car f = new Ford();
    Car h = new Honda();

    car.move();
    f.move();
    h.move();

  }
}

Ví dụ đa hình Kết quả:

Trong phương thức chính của lớp PolymorphismExample, tôi đã tạo ra ba đối tượng - Car, Ford và Honda. Tất cả ba đối tượng được gọi theo loại Xe.

Xin lưu ý một điểm quan trọng ở đây là Một loại siêu lớp có thể đề cập đến một loại đối tượng của lớp Sub nhưng câu đối không thể thực hiện được. Lý do là tất cả các thành viên của siêu lớp đều có sẵn cho lớp con bằng cách sử dụng tính kế thừa và trong thời gian biên dịch, trình biên dịch cố gắng đánh giá xem loại tham chiếu mà chúng ta đang sử dụng có phương thức mà anh ta đang cố truy cập hay không.

Vì vậy, đối với ô tô tham chiếu, f và h trong PolymorphismExample, phương thức di chuyển tồn tại từ loại Xe. Vì vậy, trình biên dịch vượt qua quá trình biên dịch mà không có bất kỳ vấn đề.

Nhưng khi thực hiện thời gian chạy, máy ảo sẽ gọi các phương thức trên các đối tượng là các kiểu con. Vì vậy, phương thức move () được gọi từ các triển khai tương ứng của chúng.

Vì vậy, tất cả các đối tượng thuộc loại Xe, nhưng trong thời gian chạy, việc thực thi phụ thuộc vào Đối tượng mà lệnh gọi xảy ra. Điều này được gọi là đa hình.


Khái niệm quá tải không liên quan gì đến tính kế thừa và đa hình.
srk

@srk Phương thức nạp chồng là một cách để thực hiện đa hình. Nó thường được phân loại là đa hình tĩnh hoặc ad hoc. wiki.c2.com/?C CategoryPolymorphism
Shaun Luttin

12

Thông thường, điều này đề cập đến khả năng cho một đối tượng loại A hành xử giống như một đối tượng của loại B. Trong lập trình hướng đối tượng, điều này thường đạt được bằng sự kế thừa. Một số liên kết wikipedia để đọc thêm:

EDIT: cố định liên kết bị hỏng.


10
"Khả năng cho một đối tượng loại A hành xử giống như một đối tượng của loại B" - đó không phải là định nghĩa chính xác. Tôi có thể nói nó giống như khả năng đối xử với một đối tượng loại A giống như đó là một đối tượng của loại B.
Artem Barger

Đúng. Có lẽ đó là một phrasing tốt hơn.
JesperE

Để hoàn thiện, nhiều ngôn ngữ thực hiện đa hình thông qua việc gõ vịt, ví dụ Python.
ilya n.

Tôi tự hỏi làm thế nào điều này có liên quan đến lời giải thích (phổ biến) mà @Ajay Patel đã đưa raclasses have different functionality while sharing a common interface
BornToCode

9

Đa hình là thế này:

class Cup {
   int capacity
}

class TeaCup : Cup {
   string flavour
}

class CoffeeCup : Cup {
   string brand
}

Cup c = new CoffeeCup();

public int measure(Cup c) {
    return c.capacity
}

bạn chỉ có thể vượt qua một Cup thay vì một ví dụ cụ thể. Điều này hỗ trợ chung vì bạn không phải cung cấp một thể hiện () cụ thể cho mỗi loại cốc


2
Điều này đặc biệt là đa hình phụ.
Shaun Luttin

@ vinko-vrsalovic: phát triển phần mềm như thế nào ở nông thôn Mỹ?
TTT

8

Tôi biết đây là một câu hỏi cũ hơn với rất nhiều câu trả lời hay nhưng tôi muốn bao gồm một câu trả lời một câu:

Đối xử với một loại dẫn xuất như thể nó là loại cơ sở.

Có rất nhiều ví dụ ở trên cho thấy điều này trong hành động, nhưng tôi cảm thấy đây là một câu trả lời ngắn gọn súc tích.


2
Đây là phân nhóm, chỉ là một loại đa hình.
Shaun Luttin

@ShaunLuttin bạn có thể chỉ cho tôi bất kỳ tài nguyên nào để tìm hiểu thêm về các loại đa hình khác không?
Abe Miessler

Các "đa hình ad hoc" và "đa hình parameteric" bổ sung cho "đa hình phụ".
Shaun Luttin


5

Nói chung, đó là khả năng giao diện một số loại đối tượng khác nhau bằng cách sử dụng cùng một API hoặc tương tự bề ngoài. Có nhiều hình thức khác nhau:

  • Quá tải hàm: xác định nhiều hàm có cùng tên và các loại tham số khác nhau, chẳng hạn như sqrt (float), sqrt (double) và sqrt (phức tạp). Trong hầu hết các ngôn ngữ cho phép điều này, trình biên dịch sẽ tự động chọn một ngôn ngữ chính xác cho loại đối số được truyền vào nó, do đó đây là đa hình thời gian biên dịch.

  • Các phương thức ảo trong OOP: một phương thức của một lớp có thể có các cách triển khai khác nhau phù hợp với đặc thù của các lớp con của nó; mỗi trong số này được cho là ghi đè lên việc thực hiện được đưa ra trong lớp cơ sở. Với một đối tượng có thể thuộc lớp cơ sở hoặc bất kỳ lớp con nào của nó, việc thực hiện đúng được chọn một cách nhanh chóng, do đó đây là đa hình thời gian chạy.

  • Mẫu: một tính năng của một số ngôn ngữ OO, theo đó một chức năng, lớp, v.v. có thể được tham số hóa bằng một loại. Ví dụ: bạn có thể định nghĩa một lớp mẫu "danh sách" chung, và sau đó khởi tạo nó thành "danh sách các số nguyên", "danh sách các chuỗi", thậm chí có thể là "danh sách các danh sách các chuỗi" hoặc tương tự. Nói chung, bạn viết mã một lần cho cấu trúc dữ liệu của loại phần tử tùy ý và trình biên dịch tạo các phiên bản của mã cho các loại phần tử khác nhau.


4

Thuật ngữ đa hình xuất phát từ:

nhiều = nhiều

hình thái = khả năng thay đổi

Trong lập trình, đa hình là một "kỹ thuật" cho phép bạn "nhìn" vào một vật thể là nhiều hơn một loại vật. Ví dụ:

Một đối tượng sinh viên cũng là một đối tượng người. Nếu bạn "nhìn" (tức là diễn viên) vào học sinh, có lẽ bạn có thể yêu cầu ID sinh viên. Bạn không thể luôn luôn làm điều đó với một người, phải không? (một người không nhất thiết phải là sinh viên, do đó có thể không có ID sinh viên). Tuy nhiên, một người có thể có một cái tên. Một học sinh cũng vậy.

Dòng dưới cùng, "nhìn" vào cùng một đối tượng từ các "góc" khác nhau có thể cung cấp cho bạn các "quan điểm" khác nhau (nghĩa là các thuộc tính hoặc phương pháp khác nhau)

Vì vậy, kỹ thuật này cho phép bạn xây dựng những thứ có thể được "nhìn" từ các góc độ khác nhau.

Tại sao chúng ta sử dụng đa hình? Để bắt đầu ... trừu tượng. Tại thời điểm này cần có đủ thông tin :)


3

Hãy sử dụng một sự tương tự. Đối với một kịch bản âm nhạc nhất định, mỗi nhạc sĩ chơi nó sẽ mang lại cảm giác riêng cho cô ấy trong việc diễn giải.

Nhạc sĩ có thể được trừu tượng hóa với các giao diện, thể loại mà nhạc sĩ thuộc về có thể là một lớp abstrac xác định một số quy tắc giải thích toàn cầu và mọi nhạc sĩ chơi có thể được mô hình hóa với một lớp cụ thể.

Nếu bạn là người nghe các tác phẩm âm nhạc, bạn có một tài liệu tham khảo về kịch bản, ví dụ như 'Fuga và Tocata' của Bach và mỗi nhạc sĩ thực hiện nó đều đa hình theo cách riêng của cô ấy.

Đây chỉ là một ví dụ về một thiết kế có thể (trong Java):

public interface Musician {
  public void play(Work work);
}

public interface Work {
  public String getScript();
}

public class FugaAndToccata implements Work {
  public String getScript() {
    return Bach.getFugaAndToccataScript();
  }
}

public class AnnHalloway implements Musician {
  public void play(Work work) {
    // plays in her own style, strict, disciplined
    String script = work.getScript()
  }
}

public class VictorBorga implements Musician {
  public void play(Work work) {
    // goofing while playing with superb style
    String script = work.getScript()
  }
}

public class Listener {
  public void main(String[] args) {
    Musician musician;
    if (args!=null && args.length > 0 && args[0].equals("C")) {
      musician = new AnnHalloway();
    } else {
      musician = new TerryGilliam();
    }
    musician.play(new FugaAndToccata());
}

1
AnnHallowayVictorBorgacảm thấy như chúng nên là các đối tượng hơn là các lớp - ví dụ của bạn sẽ đọc tốt hơn với ví dụ. public class Pianist implements MusicianvictorBorge = new Pianist();v.v.
Przemek D

3

Tôi đã cung cấp một tổng quan cấp cao về đa hình cho một câu hỏi khác:

Đa hình trong c ++

Hy vọng nó giúp. Trích...

... nó giúp bắt đầu từ một thử nghiệm đơn giản cho nó và định nghĩa về [đa hình]. Hãy xem xét mã:

Type1 x;
Type2 y;

f(x);
f(y);

Ở đây, f()là để thực hiện một số thao tác và được đưa ra các giá trị xylàm đầu vào. Để được đa hình, f()phải có khả năng hoạt động với các giá trị của ít nhất hai loại riêng biệt (ví dụ intdouble), tìm và thực thi mã phù hợp với loại.

(tiếp tục tại Đa hình trong c ++ )


3

Đa hình là một khả năng của đối tượng có thể được thực hiện dưới nhiều hình thức. Ví dụ trong lớp người, một người đàn ông có thể hành động dưới nhiều hình thức khi chúng ta nói về các mối quan hệ. EX: Một người đàn ông là cha của con trai anh ta và anh ta là chồng của vợ anh ta và anh ta là giáo viên cho học sinh của mình.


3

Đa hình là khả năng của một đối tượng có nhiều dạng. Việc sử dụng đa hình phổ biến nhất trong OOP xảy ra khi tham chiếu lớp cha được sử dụng để chỉ đối tượng lớp con. Trong ví dụ này được viết bằng Java, chúng ta có ba loại phương tiện. Chúng tôi tạo ra ba đối tượng khác nhau và cố gắng chạy phương thức bánh xe của họ:

public class PolymorphismExample {

    public static abstract class Vehicle
    {
        public int wheels(){
            return 0;
        }
    }

    public static class Bike extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 2;
        }
    }

    public static class Car extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 4;
        }
    }

    public static class Truck extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 18;
        }
    }

    public static void main(String[] args)
    {
        Vehicle bike = new Bike();
        Vehicle car = new Car();
        Vehicle truck = new Truck();

        System.out.println("Bike has "+bike.wheels()+" wheels");
        System.out.println("Car has "+car.wheels()+" wheels");
        System.out.println("Truck has "+truck.wheels()+" wheels");
    }

}

Kết quả là:

Kết quả

Để biết thêm thông tin, vui lòng truy cập https://github.com/m-vahidalizadeh/java_advified/blob/master/src/files/PolymorphismExample.java . Tôi hy vọng nó sẽ giúp.


Có, nhưng bạn đã không giải thích những lợi ích của đa hình. Rõ ràng có một mã ngắn hơn, nơi bạn sẽ xóa lớp Xe và nó vẫn hoạt động (tất nhiên với một khai báo đối tượng khác).
Cornelius

Tôi không giải thích, vì người hỏi câu hỏi không hỏi về lợi ích. Ông hỏi: "Đa hình là gì, nó dùng để làm gì và nó được sử dụng như thế nào?". Về mã, nếu bạn có thể làm điều đó tốt hơn, xin vui lòng gửi câu trả lời của bạn. Vì vậy, cộng đồng của chúng tôi có thể sử dụng nó. Cám ơn bạn đã góp ý.
Mohammad

Xin lỗi, không muốn nói thô lỗ, những người khác cũng không giải thích. Ít nhất bạn đã bận tâm để nhập mã. Dù sao, anh ta hỏi nó dùng để làm gì, nhưng không có ví dụ nào trên trang này giải thích nó dùng để làm gì. Tất cả các bạn chỉ trình bày một cách phức tạp để có được kết quả tương tự như sau: s28.postimg.org/jq8vl6031/Poly.jpg và không ai quan tâm giải thích lý do tại sao một người muốn sử dụng đa hình, mục đích hay mục đích của nó, những gì có thể không được thực hiện nếu nó không được sử dụng? Tất cả những gì tôi thấy trên trang này là một đề xuất để leo lên căn hộ của bạn bằng cách sử dụng cầu thang, chứ không phải thang máy ..
Cornelius

.. mà không nhận thấy rằng người ta mang một cột cờ quá lớn để phù hợp với thang máy. Tôi không biết cách đăng mã, vì vậy tôi không thể giúp được gì nhiều ...
Cornelius

2

Đa hình là khả năng lập trình viên viết các phương thức cùng tên làm những việc khác nhau cho các loại đối tượng khác nhau, tùy thuộc vào nhu cầu của các đối tượng đó. Ví dụ, nếu bạn đang phát triển một lớp được gọi Fractionvà một lớp được gọi ComplexNumber, cả hai có thể bao gồm một phương thức được gọi display(), nhưng mỗi trong số chúng sẽ thực hiện phương thức đó khác nhau. Trong PHP, ví dụ, bạn có thể thực hiện nó như thế này:

//  Class definitions

class Fraction
{
    public $numerator;
    public $denominator;

    public function __construct($n, $d)
    {
        //  In real life, you'd do some type checking, making sure $d != 0, etc.
        $this->numerator = $n;
        $this->denominator = $d;
    }

    public function display()
    {
        echo $this->numerator . '/' . $this->denominator;
    }
}

class ComplexNumber
{
    public $real;
    public $imaginary;

    public function __construct($a, $b)
    {
        $this->real = $a;
        $this->imaginary = $b;
    }

    public function display()
    {
        echo $this->real . '+' . $this->imaginary . 'i';
    }
}


//  Main program

$fraction = new Fraction(1, 2);
$complex = new ComplexNumber(1, 2);

echo 'This is a fraction: '
$fraction->display();
echo "\n";

echo 'This is a complex number: '
$complex->display();
echo "\n";

Đầu ra:

This is a fraction: 1/2
This is a complex number: 1 + 2i

Một số câu trả lời khác dường như ngụ ý rằng đa hình chỉ được sử dụng cùng với kế thừa; ví dụ, có thể FractionComplexNumbercả hai thực hiện một lớp trừu tượng được gọi là Numbercó một phương thức display(), mà Phân số và Số phức sau đó đều bắt buộc phải thực hiện. Nhưng bạn không cần thừa kế để tận dụng tính đa hình.

Ít nhất là trong các ngôn ngữ được gõ động như PHP (tôi không biết về C ++ hoặc Java), tính đa hình cho phép nhà phát triển gọi một phương thức mà không nhất thiết phải biết loại đối tượng trước thời hạn và tin tưởng rằng việc triển khai đúng phương thức sẽ được gọi là. Ví dụ: giả sử người dùng chọn loại Numberđã tạo:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

Trong trường hợp này, display()phương thức thích hợp sẽ được gọi, mặc dù nhà phát triển không thể biết trước liệu người dùng sẽ chọn một phân số hay một số phức.


2
Đó không phải là đa hình. Đó là hai lớp có các phương thức cùng tên. Chúng sẽ cần được liên kết bởi một lớp cơ sở hoặc giao diện gọi là "hiển thị" hoặc một cái gì đó tương tự, và sau đó các phương thức khác chỉ đơn giản là quan tâm rằng đối tượng thuộc loại "hiển thị" thay vì phức tạp hoặc Phân số.
Pod

Tôi luôn nghĩ rằng đa hình "hai lớp có các phương thức của cùng một nome." Trên thực tế, để trích dẫn Stephan Kochan (người mà tôi không biết xấu hổ trích xuất ví dụ Phân số / phức tạp này), "khả năng chia sẻ cùng một tên phương thức giữa các lớp khác nhau được gọi là đa hình." (từ Lập trình_In_Objective-C ) Anh ấy không đề cập đến bất kỳ nhu cầu liên kết các lớp thông qua một lớp cơ sở. Có lẽ nó khác ngôn ngữ khác nhau, tôi thực sự không biết.
Alex Basson

Ngay cả khó khăn này nói xấu được trích dẫn từ một cuốn sách xuất bản, tôi vẫn sẽ tranh luận rằng nó là không chính xác. Đặc biệt là vì nó dường như đụng độ với nhau, ngôn ngữ bất khả tri của đa hình. Và mặc dù kết quả cuối cùng giống như đã thấy với đa hình, tôi sẽ lập luận rằng đó là kiểu gõ động cho phép lập trình viên có thể thúc đẩy việc thực hiện đúng một phương thức trong số các phương thức khác, được gọi là phương thức mô phỏng.
vipirtti

2

Trong lập trình hướng đối tượng, đa hình đề cập đến ngôn ngữ lập trình khả năng để xử lý các đối tượng khác nhau tùy thuộc vào loại dữ liệu hoặc lớp của chúng . Cụ thể hơn, đó là khả năng xác định lại các phương thức cho các lớp dẫn xuất.


2

Đa hình theo nghĩa đen có nghĩa là, nhiều hình dạng. (hoặc nhiều dạng): Đối tượng từ các lớp khác nhau và cùng một phương thức tên, nhưng quy trình công việc là khác nhau. Một ví dụ đơn giản sẽ là:

Hãy xem xét một người X.

Anh ta chỉ là một người nhưng anh ta hành động như nhiều. Bạn có thể hỏi làm thế nào:

Anh là con trai của mẹ. Một người bạn cho bạn bè của mình. Một người anh cho em gái.


2

Đa hình trong OOP có nghĩa là một lớp có thể có các loại khác nhau, kế thừa là một cách để thực hiện đa hình.

ví dụ, Shape là một giao diện, nó có các kiểu con Square , Circle , Diamond . bây giờ bạn có một đối tượng Square, bạn có thể tự động hiển thị Square to Shape, bởi vì Square là một Shape. Nhưng khi bạn cố gắng hạ thấp Shape thành Square, bạn phải thực hiện chuyển kiểu rõ ràng, bởi vì bạn không thể nói Shape là Square, nó cũng có thể là Circle. Vì vậy, bạn cần truyền thủ công nó với mã như Square s = (Square)shape, nếu hình dạng là Circle, bạn sẽ nhận được java.lang.ClassCastException, bởi vì Circle không phải là Square.


2

Đa hình:

Thực hiện khác nhau theo thể hiện của lớp, không phải loại biến tham chiếu.

Một biến tham chiếu loại giao diện có thể tham chiếu đến bất kỳ trường hợp lớp nào thực hiện giao diện đó.


1

Đa hình là khả năng sử dụng một đối tượng trong một lớp nhất định, trong đó tất cả các thành phần tạo nên đối tượng được kế thừa bởi các lớp con của lớp đã cho. Điều này có nghĩa là một khi đối tượng này được khai báo bởi một lớp, tất cả các lớp con bên dưới nó (và các lớp con của nó, và cứ như vậy cho đến khi bạn đạt đến lớp con xa nhất / thấp nhất) sẽ thừa hưởng đối tượng và các thành phần của nó (trang điểm).

Hãy nhớ rằng mỗi lớp phải được lưu trong các tệp riêng biệt.

Đoạn mã sau minh họa tính đa hình:

Siêu nhân:

public class Parent {
    //Define things that all classes share
    String maidenName;
    String familyTree;

    //Give the top class a default method
    public void speak(){
         System.out.println("We are all Parents");
    }
}

Người cha, một lớp con:

public class Father extends Parent{
    //Can use maidenName and familyTree here
    String name="Joe";
    String called="dad";

    //Give the top class a default method
    public void speak(){
        System.out.println("I am "+name+", the father.");
    }
}

Đứa trẻ, một lớp con khác:

public class Child extends Father {
    //Can use maidenName, familyTree, called and name here

    //Give the top class a default method
    public void speak(){
        System.out.println("Hi "+called+". What are we going to do today?");
    }
}

Phương thức thực hiện, tham chiếu lớp Parent để bắt đầu:

public class Parenting{
    public static void main(String[] args) {
        Parent parents = new Parent();
        Parent parent = new Father();
        Parent child = new Child();

        parents.speak();
        parent.speak();
        child.speak();
    }
}

Lưu ý rằng mỗi lớp cần được khai báo trong các tệp * .java riêng biệt. Các mã nên biên dịch. Cũng lưu ý rằng bạn có thể liên tục sử dụng maidenName và FamilyTree ở xa hơn. Đó là khái niệm về đa hình. Khái niệm thừa kế cũng được khám phá ở đây, trong đó một lớp có thể được sử dụng hoặc được định nghĩa thêm bởi một lớp con.

Hy vọng điều này sẽ giúp và làm cho nó rõ ràng. Tôi sẽ đăng kết quả khi tôi tìm thấy một máy tính mà tôi có thể sử dụng để xác minh mã. Cảm ơn sự kiên nhẫn!


2
lưu ý rằng mọi đứa trẻ không phải là cha mẹ nên cấu trúc này là sai. Lớp trên cùng phải là Trẻ em (nếu bạn không chỉ bắt đầu bằng "Người"), điều này sẽ luôn đúng ngoại trừ Adam. Bạn có thể đặt cha_id của mình thành null vì không thể xác định được Tạo hóa với bất kỳ cấu trúc nào của trí tuệ con người.
Yehosef

1

Đa hình cho phép cùng một thói quen (chức năng, phương thức) hành động trên các loại khác nhau.

Vì nhiều câu trả lời hiện có là phân nhóm phụ với đa hình, nên đây là ba cách (bao gồm cả phân nhóm) để thực hiện đa hình.

  • Tính đa hình của Parameteric (chung) cho phép một thường trình chấp nhận một hoặc nhiều tham số loại, ngoài các tham số bình thường và tự chạy trên các loại đó.
  • Đa hình phụ cho phép một thói quen hành động trên bất kỳ kiểu con của các tham số của nó.
  • Đa hình ad hoc thường sử dụng quá tải thường quy để cấp hành vi đa hình, nhưng cũng có thể tham khảo các triển khai đa hình khác.

Xem thêm:

http://wiki.c2.com/?C CategoryPolymorphism

https://en.wikipedia.org/wiki/Polymorphism_(computer_science)


0

Trong các ngôn ngữ hướng đối tượng, tính đa hình cho phép xử lý và xử lý các loại dữ liệu khác nhau thông qua cùng một giao diện. Ví dụ, xem xét tính kế thừa trong C ++: Lớp B có nguồn gốc từ Lớp A. Một con trỏ loại A * (con trỏ đến lớp A) có thể được sử dụng để xử lý cả một đối tượng của lớp A VÀ một đối tượng của lớp B.


0

Đa hình trong thuật ngữ mã hóa là khi đối tượng của bạn có thể tồn tại dưới dạng nhiều kiểu thông qua thừa kế, v.v. Nếu bạn tạo một lớp có tên "Hình dạng" xác định số cạnh của đối tượng của bạn thì bạn có thể tạo một lớp mới kế thừa nó như "Hình vuông ". Sau đó, khi bạn tạo một thể hiện của "Hình vuông", sau đó bạn có thể chuyển nó qua lại từ "Hình dạng" sang "Hình vuông" theo yêu cầu.


0

Đa hình cung cấp cho bạn khả năng tạo một mô-đun gọi một mô-đun khác, nhưng vẫn có điểm phụ thuộc thời gian biên dịch đối với luồng điều khiển thay vì với luồng điều khiển.

Bằng cách sử dụng đa hình, một mô-đun cấp cao không phụ thuộc vào mô-đun cấp thấp. Cả hai đều phụ thuộc vào sự trừu tượng. Điều này giúp chúng tôi áp dụng nguyên tắc đảo ngược phụ thuộc ( https://en.wikipedia.org/wiki/Dependency_inversion_principl ).

Đây là nơi tôi tìm thấy định nghĩa trên. Khoảng 50 phút trong video người hướng dẫn giải thích ở trên. https://www.youtube.com/watch?v=TMuno5RZNeE


0

Đa hình là gì?

Đa hình là khả năng:

  • Gọi một hoạt động trên một thể hiện của một loại chuyên biệt bằng cách chỉ biết loại tổng quát của nó trong khi gọi phương thức của loại chuyên biệt và không phải là loại tổng quát: đó là đa hình động .

  • Xác định một số phương thức có tên lưu nhưng có tham số differents: đó là đa hình tĩnh .

Việc đầu tiên nếu định nghĩa lịch sử và quan trọng nhất.

Đa hình được sử dụng để làm gì?

Nó cho phép tạo ra sự thống nhất được đánh máy mạnh mẽ của hệ thống phân cấp lớp và thực hiện một số điều kỳ diệu như quản lý danh sách các đối tượng của các loại khác nhau mà không biết loại của chúng mà chỉ một trong các loại cha mẹ của chúng, cũng như các ràng buộc dữ liệu.

Gõ mạnh và yếu

Mẫu vật

Dưới đây là một số Hình dạng như Điểm, Đường, Hình chữ nhật và Vòng tròn có hoạt động Draw () không lấy gì hoặc tham số để đặt thời gian chờ để xóa nó.

public class Shape
{
 public virtual void Draw()
 {
   DoNothing();
 }
 public virtual void Draw(int timeout)
 {
   DoNothing();
 }
}

public class Point : Shape
{
 int X, Y;
 public override void Draw()
 {
   DrawThePoint();
 }
}

public class Line : Point
{
 int Xend, Yend;
 public override Draw()
 {
   DrawTheLine();
 }
}

public class Rectangle : Line
{
 public override Draw()
 {
   DrawTheRectangle();
 }
}

var shapes = new List<Shape> { new Point(0,0), new Line(0,0,10,10), new rectangle(50,50,100,100) };

foreach ( var shape in shapes )
  shape.Draw();

Ở đây, lớp Shape và các phương thức Shape.Draw () phải được đánh dấu là trừu tượng.

Họ không phải để làm cho hiểu.

Giải thích

Không có đa hình, sử dụng ghi đè trừu tượng ảo, trong khi phân tích cú pháp các hình dạng, đó chỉ là phương thức Spahe.Draw () được gọi là CLR không biết nên gọi phương thức nào. Vì vậy, nó gọi phương thức của loại mà chúng ta hành động và ở đây loại là Hình vì khai báo danh sách. Vì vậy, mã không làm gì cả.

Với tính đa hình, CLR có thể suy ra loại thực của đối tượng chúng ta hành động bằng cách sử dụng cái được gọi là bảng ảo. Vì vậy, nó gọi là tốt phương thức và ở đây gọi Shape.Draw () nếu Shape is Point gọi Point.Draw (). Vì vậy, mã vẽ các hình dạng.

Đọc thêm

C # - Đa hình (Cấp 1)

Đa hình trong Java (Cấp độ 2)

Đa hình (Hướng dẫn lập trình C #)

Bảng phương thức ảo

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.