Tính đa hình trong java

Từ "đa hình" có nghĩa là "nhiều dạng".Nó xuất phát từ giờ đồng hồ Hy Lạp "poly" (có nghĩa lànhiều) với "morphos" (bao gồm nghĩa làhình thức).Ví dụ, vào chất hóa học, carbon biểu đạt tính nhiều hình vày nó hoàn toàn có thể được search thấy làm việc nhiều dạng: than chì với klặng cưng cửng.Nhưng,mỗi hiệ tượng gồm trực thuộc tính riêng biệt biệt(cùng giá cả).

Bạn đang xem: Tính đa hình trong java


Một lớp bé thiết lập tất cả các nằm trong tính với hoạt động vui chơi của rất lớp của chính nó (bởi vì một tờ con được thừa kế tất cả các thuộc tính cùng chuyển động từ bỏ siêu lớp của nó).Điều này Có nghĩa là một đối tượng người sử dụng lớp bé có thể làm bất kể điều gì cực kỳ lớp của nó hoàn toàn có thể có tác dụng.Kết quả là, bọn họ có thểcụ thếmột bộc lộ của lớp nhỏ lúc một thành viên khôn xiết lớp được mong ngóng với đều vật dụng đang chuyển động tốt.Điều này được gọi lànỗ lực thế.
*

Trong ví dụ trước của chúng tôi vềCirclevàCylinder:Cylinderlà một trong lớp bé củaCircle.Chúng ta có thể nói rằng rằngCylinder"is-a"Circle(thực tế, nó "hơn-a-a"Circle).Phân lớp khôn cùng lớp thể hiệnmọt quan lại hệđược Điện thoại tư vấn là "is-a".
Circle.java

/** The superclass Circle */public class Circle // private instance variable private double radius; /** Constructs a Circle instanve sầu with the given radius */ public Circle(double radius) this.radius = radius; /** Returns the radius */ public double getRadius() return this.radius; /** Returns the area of this circle */ public double getArea() return radius * radius * Math.PI; /** Returns a self-descriptive sầu string */ public String toString() return "Circle"; Cylinder.java/** The subclass Cylinder */public class Cylinder extends Circle // private instance variable private double height; /** Constructs a Cylinder instance with the given height và radius */ public Cylinder(double height, double radius) super(radius); this.height = height; /** Returns the height */ public double getHeight() return this.height; /** Returns the volume of this cylinder */ public double getVolumne() return super.getArea() * height; /** Overrides the inherited method khổng lồ return the surface area */
Override public double getArea() return 2.0 * Math.PI * getRadius() * height; /** Override the inherited method lớn describe itself */
Override public String toString() return "Cylinder";
Thông qua khả năngráng thế, bạn cũng có thể sản xuất một thể hiệnCylindervới gán nó mang lại mộtCircletham chiếu (khôn cùng lớp của nó), nlỗi sau:
Quý khách hàng có thể Gọi toàn bộ những thủ tục được có mang trongCirclelớp để tđắm say chiếuc1, (thực tiễn đang nắm dữ mộtCylinderđối tượng), vd
// Invoke superclass Circle"s methodsSystem.out.println(c1.getRadius());//2.2
Vấn đề này là do một biểu hiện của lớp nhỏ tải toàn bộ các nằm trong tính của khôn cùng lớp của chính nó.
Tuy nhiên, bạn KHÔNG THỂ call những cách tiến hành được tư tưởng trongCylinderlớp nhằm tmê mệt chiếuc1, vd
// CANNOT invoke method in Cylinder as c1 is a Circle referencec1.getHeight();//compilation error: cannot find symbol method getHeight()c1.getVolume();//compilation error: cannot find symbol method getVolume()
Vấn đề này là doc1tsi chiếu đếnCirclelớp, trù trừ về những cách thức được định nghĩa vào lớp conCylinder.
c1là một trong những tmê mẩn chiếu đếnCirclelớp, nhưng lại duy trì một đối tượng người dùng của lớp bé của nóCylinder.Các tài liệu tham mê khảoc1, tuy nhiên,vẫn giữ lại bạn dạng nhan sắc nội bộ của nó.Trong ví dụ của Cửa Hàng chúng tôi, lớp conCylinderghi đtrần những phương thơm thứcgetArea()vàtoString().c1.getArea()hoặcc1.toString()gọiphiên bản phiên bảnghi đèđược khẳng định vào lớp bé, cầm cố vì chưng phiên phiên bản được xác minh trong.Như vậy là dotrên thực tế đang nắm giữ mộtđối tượng người dùng trong nội cỗ.CylinderCirclec1Cylinder
Đa hình cực kỳ bạo phổi trong OOP.. đểphân bóc interface với triển khaiđể cho phép lập trình sẵn viên lậptrình interfacevào xây dựng chokhối hệ thống phức tạp.
Hãy lưu ý ví dụ sau.Giả sử rằng lịch trình của công ty chúng tôi thực hiện các loại hình dạng, chẳng hạn như hình tam giác, hình chữ nhật, v.v.Chúng ta đề nghị xây cất một hết sức lớp được Hotline làShape, xác minh các giao diện nơi công cộng (public interface) (hoặc hành vi) của toàn bộ những dạng hình.ví dụ như, công ty chúng tôi hy vọng tất cả các bản thiết kế bao gồm một thủ tục được gọigetArea(),phương thơm thứcnày trả về diện tích của ngoài mặt cụ thể kia.Các lớp hình họcShapehoàn toàn có thể được viết nlỗi sau.

Xem thêm: Phân Biệt Bring Into Là Gì, 10 Cụm 'Bring + Giới Từ'


*
SuperclassShape.java/** * Superclass Shape maintain the common properties of all shapes */public class Shape // Private member variable private String color; /** Constructs a Shape instance with the given color */ public Shape (String color) this.color = color; /** Returns a self-descriptive sầu string */
Override public String toString() return "Shape"; /** All shapes must provide a method called getArea() */ public double getArea() // We have sầu a problem here! // We need to lớn return some value lớn compile the program. System.err.println("Shape unknown! Cannot compute area!"); return 0;
Hãy chú ý rằng bọn họ bao gồm một vụ việc Khi viếtgetArea()thủ tục trong lớpShape, chính vì diện tích bắt buộc được tính trừ Lúc hình trạng thực tiễn được biết đến.Chúng tôi sẽ in một thông tin lỗi vào thời hạn này.Trong phần sau, tôi sẽ chỉ cho mình phương pháp giải quyết sự việc này.
SubclassRectangle.java/** * The Rectangle class, subclass of Shape */public class Rectangle extends Shape // Private member variables private int length, width; /** Constructs a Rectangle instance with the given color, length và width */ public Rectangle(String color, int length, int width) super(color); this.length = length; this.width = width; /** Returns a self-descriptive sầu string */
Override public String toString() return "Rectangle"; /** Override the inherited getArea() khổng lồ provide the proper implementation for rectangle */
Override public double getArea() return length*width; SubclassTriangle.java/** * The Triangle class, subclass of Shape */public class Triangle extends Shape { // Private thành viên variables private int base, height; /** Constructs a Triangle instance with the given color, base and height */ public Triangle(String color, int base, int height) super(color); this.base = base; this.height = height; /** Returns a self-descriptive sầu string */
Override public String toString() return "Triangle"; /** Override the inherited getArea() to lớn provide the proper implementation for triangle */
Các lớp bé ghi đègetArea()cách thức được thừa kế từ lớp phụ thân cùng cung cấp các xúc tiến thích hợp chogetArea().
Trong áp dụng của Shop chúng tôi, Shop chúng tôi có thể tạo thành những tmê mẩn chiếuShapevà gán cho cái đó những bộc lộ của những lớp nhỏ, như sau:
/** * A kiểm tra driver for Shape & its subclasses */public class TestShape public static void main(String<> args) Shape s1 = new Rectangle("red", 4, 5); // Upcast System.out.println(s1); // Run Rectangle"s toString() //Rectangle> System.out.println("Area is " + s1.getArea()); // Run Rectangle"s getArea() //Area is 20.0 Shape s2 = new Triangle("blue", 4, 5); // Upcast System.out.println(s2); // Run Triangle"s toString() //Triangle> System.out.println("Area is " + s2.getArea()); // Run Triangle"s getArea() //Area is 10.0
Vẻ đẹp mắt của mã này làtất cả các tmê mệt chiếu tới từ hết sức lớp(tức làlập trình sẵn làm việc Lever giao diện).Quý khách hàng hoàn toàn có thể khởi chế tạo ra biểu lộ của lớp con khác biệt cùng mã vẫn chuyển động.Quý Khách hoàn toàn có thể mở rộng công tác của chúng ta một phương pháp tiện lợi bằng cách phân phối các lớp nhỏ, chẳng hạn nhưCircle,Square, vv, một bí quyết thuận tiện.
Tuy nhiên, có mang trên của lớpShapeđặt ra một vụ việc, giả dụ ai đó khởi sinh sản một đối tượngShapevà gọigetArea()từ đối tượngShape, chương trình có khả năng sẽ bị phá tan vỡ.
public class TestShape public static void main(String<> args) // Constructing a Shape instance poses problem! Shape s3 = new Shape("green"); System.out.println(s3); //Shape System.out.println("Area is " + s3.getArea()); // Invalid output //Shape unknown! Cannot compute area! //Area is 0.0
Vấn đề này là doShapelớp Tức là hỗ trợ một hình ảnh tầm thường mang lại tất cả các lớp con của chính nó, biết tới để cung cấp việc tiến hành thực tế.Chúng tôi không thích bất cứ ai khởi tạo thành một ví dụShape.Vấn đề này hoàn toàn có thể được giải quyết bằng phương pháp thực hiện lớp trưu tượng được Hotline làabstractclass.

Xem thêm: Phần Mềm Chuyển Video Sang Mp4, 10 Phần Mềm Convert Video Miễn Phí Tốt Nhất


4.3Polymorphism EG. 2:Monstervà Subclasses của nó
*

Đa hình là một trong hình thức trẻ trung và tràn trề sức khỏe trong OOP. đểphân tách bóc bối cảnh cùng triển khaiđể được cho phép xây dựng viên lập trình sẵn trên bối cảnh vào thiết kế của một hệ thống phức hợp.lấy ví dụ như, trong ứng dụng trò đùa của công ty chúng tôi, Cửa Hàng chúng tôi có rất nhiều nhiều loại quái vật rất có thể tấn công.Chúng ta vẫn kiến tạo một rất lớp được gọiMonstervà xác định phương thơm thứcattack()vào khôn xiết lớp.Các lớp con tiếp nối đang cung ứng triển khai thực tế của họ.Trong công tác thiết yếu, chúng tôi knhì báo các biểu thị của cực kỳ lớp, được thay thế sửa chữa bởi lớp bé thực tế;cùng Hotline cách tiến hành được khái niệm trong lớp phụ vương.
SuperclassMonster.java/** * The superclass Monster defines the expected comtháng behaviors for its subclasses. */public class Monster // private instance variable private String name; /** Constructs a Monster instance with the given name */ public Monster(String name) this.name = name; /** Defines a comtháng behavior called attack() for all its subclasses */ public String attack() return "!^_&^$
+%$* I don"t know how lớn attack!"; // We have sầu a problem here! // We need to return a String; else, compilation error! SubclassFireMonster.javapublic class FireMonster extends Monster /** Constructs a FireMonster with the given name */ public FireMonster(String name) super(name); /** Subclass provides actual implementation for attack() */
Override public String attack() return "Attaông chồng with fire!"; SubclassWaterMonster.javapublic class WaterMonster extends Monster /** Constructs a WaterMonster instance with the given name */ public WaterMonster(String name) super(name); /** Subclass provides actual implementation for attack() */
Override public String attack() return "Attaông xã with water!"; SubclassStoneMonster.javapublic class StoneMonster extends Monster /** Constructs a StoneMonster instance with the given name */ public StoneMonster(String name) super(name); /** Subclass provides actual implementation for attack() */
Override public String attack() return "Attack with stones!"; A Test DriverTestMonster.javapublic class TestMonster public static void main(String<> args) // Program at the specification defined in the superclass/interface. // Declare instances of the superclass, substituted by subclasses. Monster m1 = new FireMonster("r2u2"); // upcast Monster m2 = new WaterMonster("u2r2"); // upcast Monster m3 = new StoneMonster("r2r2"); // upcast // Invoke the actual implementation System.out.println(m1.attack()); // Run FireMonster"s attack() //Attaông chồng with fire! System.out.println(mét vuông.attack()); // Run WaterMonster"s attack() //Attachồng with water! System.out.println(m3.attack()); // Run StoneMonster"s attack() //Attaông xã with stones! // m1 dies, generate a new instance and re-assign to m1. m1 = new StoneMonster("a2b2"); // upcast System.out.println(m1.attack()); // Run StoneMonster"s attack() //Attack with stones! // We have a problem here!!! Monster m4 = new Monster("u2u2"); System.out.println(m4.attack()); // garbage!!! //!^_&^$
+%$* I don"t know how to attack! 4.4Upcasting và DowncastingUpcasting Instance tham chiếu cho tới SuperclassViệc thay thế một thể hiện của lớp nhỏ đến khôn cùng lớp của nó được Hotline là "upcasting".Như vậy là vì, vào sơ vật dụng lớp UML, lớp bé thường xuyên được vẽ bên dưới lớp phụ thân của chính nó.Upcastingluôn luôn an toànvì một biểu hiện của lớp con mua tất cả các ở trong tính của vô cùng lớp của chính nó với có thể làm cho bất kể điều gì nhưng mà vô cùng lớp của chính nó có thể làm.Trình biên dịch soát sổ vấn đề upcasting phù hợp lệ với tạo nên lỗi "các một số loại không tương thích" còn nếu như không.ví dụ như,Circle c1 = new Cylinder(1.1, 2.2); // Compiler checks khổng lồ ensure that R-value is a subclass of L-value.Circle c2 = new String(); // Compilation error: incompatible typesDowncasting một tài liệu tham khảo sửa chữa đến lớp ban đầu của nó
quý khách có thể hoàn ngulặng một bộc lộ được thay thế quay trở về tđam mê chiếu lớp bé.Như vậy được call là "downcasting".ví dụ như,
Circle c1 = new Cylinder(1.1, 2.2); // upcast is safeCylinder cy1 = (Cylinder) c1; // downcast needs the casting operator
Downcasting yêu cầutoán tử đúc vẻ bên ngoài rõ rànglàm việc dạng tân oán tử tiền tố.Downcasting không hẳn thời gian nào cũng an toàn với ném nhẹm ra một thời gian chạyví như biểu đạt bị downcast không nằm trong về lớp nhỏ đúng đắn.Một đối tượng lớp bé hoàn toàn có thể được sửa chữa đến khôn xiết lớp của chính nó, nhưng lại điều ngược trở lại là sai trái.(new-type)ClassCastException
Một ví dụ khác về Upcasting cùng Downcasting
*
public class A public A() // Constructor System.out.println("Constructed an instance of A");
Override public String toString() return "This is A"; public class B extends A public B() // Constructor super(); System.out.println("Constructed an instance of B");
Override public String toString() return "This is B"; public class C extends B { public C() // Constructor super(); System.out.println("Constructed an instance of C");
public class TestCasting public static void main(String<> args) A a1 = new C(); // upcast //Constructed an instance of A //Constructed an instance of B //Constructed an instance of C System.out.println(a1); // run C"s toString() //This is C B b1 = (B)a1; // downcast okay System.out.println(b1); // run C"s toString() //This is C C c1 = (C)b1; // downcast okay System.out.println(c1); // run C"s toString() //This is C A a2 = new B(); // upcast //Constructed an instance of A //Constructed an instance of B System.out.println(a2); // run B"s toString() //This is B B b2 = (B)a2; // downcast okay C c2 = (C)a2; //compilation okay, but runtime error: //java.lang.ClassCastException: class B cannot be cast to lớn class C Casting Operator
Trình biên dịch rất có thể thiết yếu phát hiện nay lỗi vào quy trình truyền cụ thể, vấn đề đó đã chỉ được vạc hiện Khi chạy.lấy ví dụ như,
Circle c1 = new Circle(5);Point p1 = new Point(); c1 = p1; //compilation error: incompatible types (Point is not a subclass of Circle)c1 = (Circle)p1; //runtime error: java.lang.ClassCastException: Point cannot be casted khổng lồ Circle4.5Toán tử "instanceof"
Java hỗ trợ tân oán tử nhị phân được Gọi làinstanceofnó sẽ trả về giá chỉ trịtrueví như gồm một đối tượng người tiêu dùng là instance (thể hiển) của particular class. Cú pháp như sau:
anObject instanceof aClassCircle c1 = new Circle();System.out.println(c1 instanceof Circle); // true if (c1 instanceof Circle) ......
Circle c1 = new Circle(1.1);Cylinder cy1 = new Cylinder(2.2, 3.3);System.out.println(c1 instanceof Circle); //trueSystem.out.println(c1 instanceof Cylinder); //falseSystem.out.println(cy1 instanceof Cylinder); //trueSystem.out.println(cy1 instanceof Circle); //true Circle c2 = new Cylinder(4.4, 5.5);System.out.println(c2 instanceof Circle); //trueSystem.out.println(c2 instanceof Cylinder); //true4.6Tóm Tắt về Đa HìnhMột mô tả của lớp con cách xử lý tất cả những chuyển động thuộc tính của khôn cùng lớp của chính nó.lúc một thành viên khôn cùng lớp được hy vọng đợi, nó rất có thể được thay thế bởi một diễn tả của lớp nhỏ.Nói phương pháp không giống, một tđam mê chiếu cho một tấm có thể đựng một diễn đạt của lớp kia hoặc một biểu lộ của một trong các lớp con của chính nó - nó được Call là kỹ năng sửa chữa.Nếu một bộc lộ của lớp bé được gán cho 1 tsi mê chiếu khôn cùng lớp, chúng ta chỉ rất có thể hotline những cách tiến hành được khái niệm vào vô cùng lớp.quý khách hàng không thể Gọi những thủ tục được định nghĩa vào lớp con.Tuy nhiên, thành viên thay thế vẫn duy trì bản dung nhan riêng rẽ của4.7Bài Tập

Chuyên mục: Công nghệ