Đa hình là gì, nó dùng để làm gì và nó được sử dụng như thế nào?
Đa hình là gì, nó dùng để làm gì và nó được sử dụng như thế nào?
Câu trả lời:
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.
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ư BigDecimal
hoặc Rational
hoặc Imaginary
cũ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à Shape
lớ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()
và 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ư p
mặ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 :-)
Poly = many and Morph = change or form
Đ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.
Class_Excel
, Class_CSV
được gọi hoặc có một Reader
lớ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 đó.
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.
Nếu có ai nói CẮT với những người này
Chuyện gì sẽ xảy ra?
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.
.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.
Tổng thống Hoa Kỳ sử dụng đa hình. Làm sao? Vâng, ông có nhiều cố 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.
Đ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à IAdvisor
giao 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ất cả những gì bạn thực sự cần biết là đây:
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.
if healthAdvisor? then do this:
và 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.
Đ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;
classes have different functionality while sharing a common interface
Đ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.
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.
classes have different functionality while sharing a common interface
Đ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
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.
. tốt hơn vẫn sẽ chia sẻ nó ...)
http://www.eioba.com/a/1htn/how-i-explained-rest-to-my-wife
đọc từ phần này:
..... đa hình. Đó là một cách nói táo bạo mà các danh từ khác nhau có thể có cùng một động từ được áp dụng cho chúng.
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.
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 :)
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());
}
AnnHalloway
và VictorBorga
cả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 Musician
và victorBorge = new Pianist();
v.v.
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:
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ịx
vày
là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ụint
vàdouble
), 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 ++ )
Đ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.
Đ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à:
Để 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.
Đ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 Fraction
và 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ể Fraction
và ComplexNumber
cả hai thực hiện một lớp trừu tượng được gọi là Number
có 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.
Đ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.
Đ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.
Đ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 đó.
Đ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!
Đ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.
Xem thêm:
http://wiki.c2.com/?C CategoryPolymorphism
https://en.wikipedia.org/wiki/Polymorphism_(computer_science)
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.
Đ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.
Đ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
Đ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.
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.
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.
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.