2013-07-18 27 views
5
interface Shape { 
    public double area(); 
} 

class Circle implements Shape { 
     private double radius; 

     public Circle(double r){radius = r;} 

     public double area(){return Math.PI*radius*radius;} 
} 

class Square implements Shape { 
     private int wid; 

     public Square(int w){wid = w;} 

     public double area(){return wid *wid;} 
} 

public class Poly{ 
    public static void main(String args[]){ 
       Shape[] s = new Shape[2]; 
       s[0] = new Circle(10); 
       s[1] = new Square(10); 

       System.out.println(s[0].getClass().getName()); 
       System.out.println(s[1].getClass().getName()); 
     } 
} 

Trong một nỗ lực để hiểu khái niệm về đa hình, tôi thấy bài sau (https://stackoverflow.com/a/4605772/112500) nhưng tôi nhận thấy rằng Charlie đã tạo ra lớp Shape với một phương pháp chưa thực hiện.Hiểu đa hình với nhiều lớp học và một hình thức giao diện của instantiation

Như người ta có thể nhìn thấy từ mã của tôi, tôi chuyển đổi lớp đó thành một giao diện và sau đó sử dụng nó để khởi tạo một lớp ẩn danh mà sau đó được gọi là phương thức thích hợp.

Ai đó có thể cho tôi biết nếu giải pháp của tôi có âm thanh không? Bạn có viết mã theo cách khác không? Tại sao việc sử dụng giao diện trên cả hai mặt của hàm dấu bằng như vậy?

Cảm ơn.

Caitlin

+2

Bạn đã tạo lớp ẩn danh trong mã được đăng ở đâu? – NINCOMPOOP

+3

Bạn có nghĩa là dòng 'Shape [] s = new Shape [2]'? Bạn không tạo bất kỳ cá thể nào của 'Hình dạng' ở đó, chỉ một mảng có thể chứa 2' Hình dạng '. –

+0

@Heuster Suy luận hay! – NINCOMPOOP

Trả lời

4

Đó có vẻ tốt đẹp đối với tôi - mặc dù bạn không sử dụng các lớp học vô danh bất cứ nơi nào, nó hiển thị như thế nào cơ bản các công trình đa hình.

Nói chung, trong mã như

Shape s1 = new Circle(2); 
Shape s2 = new Square(2); 

cả các dòng ở trên làm việc vì CircleSquare thực hiện Shape, mà thực sự là nói 'Circle là một Shape' và 'Square là một Shape'. Bằng cách tuyên bố 's1' là loại Shape bạn đang nói rằng nó có thể tham chiếu đến bất cứ điều gì đó là một Shape, tức là. bất cứ điều gì thực hiện Shape. Lưu ý rằng bạn chỉ có thể các phương thức gọi được xác định trong giao diện Shape qua s1s2. Nói rằng các mối đã có một phương pháp diameter thì:

Shape s1 = new Circle(2); 
s1.diameter(); 

sẽ thất bại, bởi vì diameter không tồn tại trên giao diện Shape: Loại một biến được khai báo là xác định những phương pháp có thể được nhìn thấy, không lớp thực tế của biến thể hiện biến. Nhưng việc thực hiện được gọi là được xác định bởi lớp thực tế của cá thể được đề cập - đây là cốt lõi của đa hình.

4

Cách tiếp cận của bạn tốt - luôn đề xuất lập trình cho giao diện (hình dạng) thay vì triển khai cụ thể (vòng tròn). Đa hình có nghĩa là mọi việc thực hiện cụ thể hình dạng có thể diễn ra dưới dạng hình dạng.

ví dụ: (Giống như giả java)

Circle c = new Circle(10); // not polymorph, as c = new Square(10) will throw an error 

nhưng

Shape s = new Circle(10); 
... some other code 
s = new Square(10) // totaly fine 

Bạn có thể cải thiện bạn mã bằng cách sử dụng factorys để tạo hình dạng của bạn, ví dụ

public class ShapeFactory { 
    public Shape createCircle(int param) { 
return new Circle(param); 
} 

public Shape createRectangle(int param, int param2) { 
return new Rectangle(param, param2) }; 

and so on 

Xem http://en.wikipedia.org/wiki/Factory_method_pattern

Tóm lại: bạn đang ở trên một cách đúng đắn!

+0

Cảm ơn @ verbose-mode. Vì vậy, tôi có thể sử dụng một giao diện ở phía bên trái chỉ khi lớp bên phải thực hiện giao diện? Có thể một giao diện tồn tại trên cả hai mặt của "="? – CaitlinG

+0

Không! Không thể có một thể hiện (XYZ mới) của giao diện. Một giao diện mô tả các phương thức công khai của một lớp. Vì vậy, nếu bạn muốn làm một cái gì đó như thế này InterfaceA a = new ClassA(); ClassA() cần triển khai giao diện đó. Xem giao diện dưới dạng bản tóm tắt các phương thức "được chia sẻ" trên tất cả các trình triển khai của giao diện đó. – Mirco

+0

Danke schön @ verbose-mode. Một giao diện tương tự như một "hợp đồng" giữa hai bên và đại diện cho một mối quan hệ "là-a", theo đó chỉ những phương thức được định nghĩa trong giao diện và được triển khai trong các lớp thực hiện các giao diện nói trên mới có khả năng được gọi. Điều này có đúng không? – CaitlinG

5

Một lớp ẩn danh trong Java là một lớp không được đặt tên và vừa được khai báo vừa được trình bày trong một câu lệnh. Bạn nên cân nhắc sử dụng một lớp ẩn danh bất cứ khi nào bạn cần tạo một lớp sẽ được khởi tạo chỉ một lần.

Lớp ẩn danh phải luôn triển khai giao diện hoặc mở rộng lớp trừu tượng. Tuy nhiên, bạn không sử dụng kéo dài hoặc triển khai từ khóa để tạo lớp ẩn danh. Thay vào đó, bạn sử dụng cú pháp sau để khai báo và khởi tạo một lớp vô danh:

new interface-or-class-name() { class-body } 

Một ví dụ sẽ là:

Shape s = new Shape() // no square brackets here 
{ 
    public double area() 
    { 
     return 10.0; 
    } 
}; 

Không nơi trong mã đăng tải của bạn, bạn đang tạo ra bất kỳ lớp nặc danh.

Đọc số Oracle tutorialthis để biết thêm.


Khi bạn làm điều này:

Shape[] s = new Shape[2] // notice the square brackets : "[2]" 

Bạn đang thực sự tạo ra một mảng có thể có tham chiếu đến đối tượng của Shape và phân nhóm của nó.Vì vậy, mảng này có thể chứa các tham chiếu đến đối tượng của bất kỳ lớp mà thực hiện Shape:

s[0] = new Circle(); 
s[1] = new Square(); 
+0

http://stackoverflow.com/questions/9157784/java-interface-with-new-keyword-how-is-that-possible Câu trả lời thứ hai là những gì tôi đọc. – CaitlinG

+0

@CaitlinG Câu hỏi khác ở đó và thậm chí cả mã mẫu. – NINCOMPOOP

+0

Ahh, tôi hiểu rồi! Khái niệm đa hình bắt đầu trở nên ít mơ hồ hơn. Nếu không có mảng trong "trình điều khiển", tôi có thể đã gọi các phương thức với một s.method đơn giản? – CaitlinG

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