2016-08-08 40 views

Trả lời

10

Các tài liệu sẽ giúp ở đây:

Interfaces Extending Classes

Khi một kiểu giao diện mở rộng một kiểu lớp nó được thừa hưởng các thành viên của lớp nhưng không triển khai của họ. Nó giống như giao diện có tuyên bố tất cả các thành viên của lớp mà không cung cấp triển khai . Giao diện kế thừa ngay cả các thành viên riêng tư và được bảo vệ của một lớp cơ sở. Điều này có nghĩa là khi bạn tạo một giao diện mở rộng một lớp với các thành viên riêng tư hoặc được bảo vệ, giao diện chỉ có thể được thực hiện bởi lớp đó hoặc một lớp con của lớp đó.

Điều này rất hữu ích khi bạn có một hệ thống phân cấp thừa kế lớn, nhưng muốn để chỉ định rằng mã của bạn chỉ hoạt động với các lớp con có số thuộc tính nhất định. Các lớp con không phải liên quan bên cạnh việc kế thừa từ lớp cơ sở. Ví dụ:

class Control { 
    private state: any; 
} 

interface SelectableControl extends Control { 
    select(): void; 
} 

class Button extends Control { 
    select() { } 
} 

class TextBox extends Control { 
    select() { } 
} 

class Image extends Control { 
} 

class Location { 
    select() { } 
} 

Vì vậy, trong khi

  • extends nghĩa - nó được tất cả từ mẹ
  • implements trong trường hợp này là gần giống như thực hiện một giao diện. Đối tượng con có thể giả vờ rằng nó là cha mẹ .. nhưng nó không nhận được bất kỳ triển khai nào
+0

khi bạn nói "' extends'-it get all from parent ", nó có áp dụng cho thành viên riêng tư không? Ví dụ 'class Person {private name: string} class man mở rộng Person {gender: string;}' does 'man' có tên thuộc tính? – davejoem

+0

Riêng tư cũng ở đó. Chỉ cần TS không thể tiếp cận. Làm cho chúng được bảo vệ và bạn có thể sử dụng chúng. Trong trường hợp "thực hiện" chỉ là một phần công cộng có ý nghĩa. Hy vọng nó sẽ giúp một chút –

19

Trong bản in (và một số ngôn ngữ OO khác) bạn có các lớp và giao diện.

Giao diện không có triển khai, nó chỉ là "hợp đồng" của thành viên/phương thức mà loại này có.
Ví dụ:

interface Point { 
    x: number; 
    y: number; 
    distance(other: Point): number; 
} 

Instances người thực hiện giao diện Point này phải có hai thành viên của số loại: xy, và một phương pháp distance mà nhận khác Point dụ và trả về một number.
Giao diện không triển khai bất kỳ giao diện nào trong số đó.

Lớp học đang triển khai:

class PointImplementation implements Point { 
    public x: number; 
    public y: number; 

    constructor(x: number, y: number) { 
     this.x = x; 
     this.y = y; 
    } 

    public distance(other: Point): number { 
     return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2)); 
    } 
} 

(code in playground)

Trong ví dụ của bạn, bạn đối xử với lớp Person của bạn một lần như là một lớp khi bạn mở rộng nó và một lần như một giao diện khi bạn thực hiện nó.
Mã của bạn:

class Person { 
    name: string; 
    age: number; 
} 
class Child extends Person {} 

class Man implements Person {} 

Có một lỗi biên dịch nói:

Class 'Man' không đúng cách thực hiện giao diện 'Người'.
Thuộc tính 'tên' bị thiếu trong loại 'Man'.

Và đó là do giao diện thiếu triển khai.
Vì vậy, nếu bạn implement một lớp sau đó bạn chỉ có "hợp đồng" của mình mà không thực hiện, vì vậy bạn sẽ cần phải làm điều này:

class NoErrorMan implements Person { 
    name: string; 
    age: number; 
} 

(code in playground)

Điểm mấu chốt là trong nhiều trường hợp bạn muốn extend một lớp khác chứ không phải là implement nó.

1

Câu trả lời hay từ @ nitzan-tomer! Đã giúp tôi rất nhiều ... Tôi đã mở rộng bản trình diễn của anh ấy một chút với:

IPoint interface; 
Point implements IPoint; 
Point3D extends Point; 

Và cách chúng hoạt động trong các chức năng mong đợi loại IPoint.

Vì vậy, những gì tôi đã học cho đến nay và được sử dụng như một quy tắc ngón tay cái: nếu bạn đang sử dụng các lớp và phương thức mong đợi các loại chung, hãy sử dụng giao diện như các loại mong đợi. Và đảm bảo cha mẹ hoặc lớp cơ sở sử dụng giao diện đó. Bằng cách đó, bạn có thể sử dụng tất cả các lớp con trong các trường con khi chúng thực hiện giao diện.

Hier the extended demo

+0

Điều này không cung cấp câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ tác giả, hãy để lại nhận xét bên dưới bài đăng của họ. - [Từ đánh giá] (/ review/low-quality-posts/18734440) – aronisstav

+0

@aronisstav Tôi chỉ đăng bản demo mở rộng về những gì tôi đã tìm thấy câu trả lời hay đã giúp tôi. Nhưng có lẽ một người khác sẽ tìm thấy công việc tôi đã mở rộng bản demo hữu ích. Đó là tất cả. Bình luận không thực sự có nghĩa là để đặt một khối mã, vì vậy đó là lý do tại sao tôi tìm thấy nó dễ hiểu hơn trong một bài viết trả lời. Vậy vấn đề với nó là gì? – andzep

+0

Câu trả lời của bạn được (tự động?) Bị gắn cờ do độ dài và nội dung, xuất hiện trong hàng đợi đánh giá của tôi và tôi đã khen ngợi những lý do được trình bày trong cờ. Đóng góp chính của nó (giải thích rằng bạn đã mở rộng bản trình diễn) sẽ tốt hơn như một nhận xét. Với đoạn thêm có lẽ nó thực sự hữu ích hơn. – aronisstav

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