Tại sao Nhiều Kế thừa không được phép trong Java hoặc C #?


115

Tôi biết rằng đa kế thừa không được phép trong Java và C #. Nhiều sách chỉ nói, không được phép thừa kế đa di sản. Nhưng nó có thể được thực hiện bằng cách sử dụng các giao diện. Không có gì được thảo luận về lý do tại sao nó không được phép. Ai đó có thể cho tôi biết chính xác lý do tại sao nó không được phép không?


1
Cũng giống như chỉ ra rằng có những khung công tác cho phép hành vi giống MI trong các lớp C #. Và tất nhiên bạn có tùy chọn có các mixin không trạng thái (sử dụng các phương thức mở rộng) - mặc dù không trạng thái, chúng không hữu ích lắm.
Dmitri Nesteruk

1
Việc các giao diện có liên quan gì đến tính kế thừa là một ảo tưởng được tạo ra bởi cú pháp ngôn ngữ. Tài sản thừa kế được cho là giúp bạn giàu có hơn. Không có gì giống như vậy đối với một giao diện, bạn không kế thừa squat và nó làm cho bạn nghèo đi đáng kể. Bạn thừa kế món nợ cờ bạc của chú Harry, bạn có nhiều việc phải làm để triển khai giao diện.
Hans Passant

Câu trả lời:


143

Câu trả lời ngắn gọn là: bởi vì các nhà thiết kế ngôn ngữ quyết định không làm vậy.

Về cơ bản, có vẻ như cả nhà thiết kế .NET và Java đều không cho phép đa kế thừa vì họ lý luận rằng việc thêm MI làm tăng quá nhiều độ phức tạp cho các ngôn ngữ trong khi mang lại quá ít lợi ích .

Để đọc sâu hơn và thú vị hơn, có một số bài báo có sẵn trên web với các cuộc phỏng vấn của một số nhà thiết kế ngôn ngữ. Ví dụ, đối với .NET, Chris Brumme (người đã làm việc tại MS trên CLR) đã giải thích lý do tại sao họ quyết định không:

  1. Các ngôn ngữ khác nhau thực sự có những kỳ vọng khác nhau về cách MI hoạt động. Ví dụ: xung đột được giải quyết như thế nào và liệu các cơ sở trùng lặp được hợp nhất hay dư thừa. Trước khi có thể triển khai MI trong CLR, chúng ta phải khảo sát tất cả các ngôn ngữ, tìm ra các khái niệm chung và quyết định cách diễn đạt chúng theo cách trung lập về ngôn ngữ. Chúng tôi cũng sẽ phải quyết định xem MI có thuộc CLS hay không và điều này có nghĩa là gì đối với các ngôn ngữ không muốn khái niệm này (có lẽ là VB.NET chẳng hạn). Tất nhiên, đó là công việc mà chúng ta đang kinh doanh như một ngôn ngữ chung thời gian chạy, nhưng chúng ta vẫn chưa làm được điều đó cho MI.

  2. Số nơi thực sự thích hợp MI thực sự là khá ít. Trong nhiều trường hợp, kế thừa nhiều giao diện có thể hoàn thành công việc. Trong các trường hợp khác, bạn có thể sử dụng tính năng đóng gói và ủy quyền. Nếu chúng ta thêm một cấu trúc hơi khác một chút, như mixin, thì nó có thực sự mạnh hơn không?

  3. Sự kế thừa đa thực thi đưa rất nhiều phức tạp vào việc thực hiện. Sự phức tạp này ảnh hưởng đến quá trình đúc, bố cục, điều phối, truy cập trường, tuần tự hóa, so sánh danh tính, khả năng xác minh, phản ánh, thông tin chung và có lẽ rất nhiều nơi khác.

Bạn có thể đọc toàn bộ bài viết ở đây.

Đối với Java, bạn có thể đọc bài viết này :

Lý do bỏ qua đa kế thừa từ ngôn ngữ Java chủ yếu xuất phát từ mục tiêu "đơn giản, hướng đối tượng và quen thuộc". Là một ngôn ngữ đơn giản, những người tạo ra Java muốn một ngôn ngữ mà hầu hết các nhà phát triển có thể nắm bắt được mà không cần đào tạo chuyên sâu. Để đạt được mục tiêu đó, họ đã làm việc để làm cho ngôn ngữ này giống với C ++ nhất có thể (quen thuộc) mà không mang theo sự phức tạp không cần thiết của C ++ (đơn giản).

Theo ý kiến ​​của các nhà thiết kế, đa kế thừa gây ra nhiều vấn đề và nhầm lẫn hơn là nó có thể giải quyết được. Vì vậy, họ cắt đa kế thừa khỏi ngôn ngữ (cũng giống như họ cắt giảm tải toán tử). Kinh nghiệm C ++ sâu rộng của các nhà thiết kế đã dạy họ rằng đa kế thừa không đáng phải đau đầu.


10
So sánh đẹp. Tôi nghĩ khá rõ ràng về các quy trình suy nghĩ làm nền tảng cho cả hai nền tảng.
CurtainDog

97

Việc thực hiện nhiều kế thừa là điều không được phép.

Vấn đề là trình biên dịch / thời gian chạy không thể tìm ra việc phải làm nếu bạn có lớp Cowboy và lớp Artist, cả hai đều có triển khai cho phương thức draw () và sau đó bạn cố gắng tạo một kiểu CowboyArtist mới. Điều gì xảy ra khi bạn gọi phương thức draw ()? Có ai đó nằm chết trên đường phố, hay bạn có một màu nước đáng yêu?

Tôi tin rằng nó được gọi là vấn đề thừa kế kim cương kép.


80
Bạn nhận được một màu nước đáng yêu của một người nào đó đã chết trên đường phố :-)
Dan F

Đây có phải là vấn đề duy nhất? Tôi nghĩ, tôi không chắc rằng C ++ giải quyết vấn đề này bằng từ khóa ảo, điều này có đúng không? Tôi không giỏi C ++
Abdulsattar Mohammed

2
Trong C ++, bạn có thể chỉ định hàm nào của lớp cơ sở để gọi trong dẫn xuất hoặc tự thực hiện lại nó.
Dmitry Risenberg

1
Thiết kế hiện đại có xu hướng ưu tiên bố cục hơn là kế thừa trong tất cả các trường hợp, trừ những trường hợp đơn giản nhất. Đa thừa kế sẽ không bao giờ được coi là một trường hợp đơn giản. Với thành phần, bạn có thể kiểm soát chính xác hơn những gì lớp học của bạn làm khi có những vấn đề kim cương như thế này ...
Bill Michell

Bạn chỉ cần một danh sách ưu tiên. Điều này được sử dụng trong hệ thống đối tượng của Common Lisp, CLOS. Tất cả các lớp tạo thành một hệ thống đẳng cấp và phương thức được gọi được xác định từ đó. Hơn nữa, CLOS cho phép bạn xác định các quy tắc khác nhau để CowboyArtist.draw () trước tiên có thể vẽ một Cao bồi và sau đó là một Nghệ sĩ. Hoặc những gì bạn đã từng trang điểm.
Sebastian Krog

19

Lý do: Java rất phổ biến và dễ viết mã, vì tính đơn giản của nó.

Vì vậy, điều mà các nhà phát triển java cảm thấy khó hiểu và phức tạp đối với các lập trình viên, họ đã cố gắng tránh nó. Một trong những loại tài sản như vậy là đa thừa kế.

  1. Họ đã tránh các con trỏ
  2. Họ đã tránh được đa thừa kế.

Bài toán đa kế thừa: Bài toán kim cương.

Ví dụ :

  1. Giả sử rằng lớp A có một phương thức fun (). lớp B và lớp C bắt nguồn từ lớp A.
  2. Và cả hai lớp B và C, đều ghi đè phương thức fun ().
  3. Bây giờ, giả sử rằng lớp D kế thừa cả lớp B và C. (chỉ là Giả định)
  4. Tạo đối tượng cho lớp D.
  5. D d = new D ();
  6. và cố gắng truy cập d.fun (); => nó sẽ gọi là niềm vui của lớp B () hay niềm vui của lớp C ()?

Đây là sự mơ hồ tồn tại trong vấn đề kim cương.

Nó không phải là không thể giải quyết vấn đề này, nhưng nó tạo ra nhiều sự nhầm lẫn và phức tạp hơn cho lập trình viên khi đọc nó. Nó gây ra nhiều vấn đề hơn là nó cố gắng giải quyết.

Lưu ý : Nhưng bất kỳ cách nào bạn luôn có thể thực hiện đa kế thừa gián tiếp bằng cách sử dụng các giao diện.


1
"Nhưng bất kỳ cách nào bạn luôn có thể thực hiện đa kế thừa gián tiếp bằng cách sử dụng các giao diện." - yêu cầu người lập trình chỉ định lại phần thân của các phương thức mỗi lần, nhiều lần.
Kari

13

Bởi vì Java có một triết lý thiết kế khác rất nhiều so với C ++. (Tôi sẽ không thảo luận về C # ở đây.)

Khi thiết kế C ++, Stroustrup muốn bao gồm các tính năng hữu ích, bất kể chúng có thể bị lạm dụng như thế nào. Có thể tăng thời gian với đa kế thừa, nạp chồng toán tử, mẫu và nhiều tính năng khác, nhưng cũng có thể thực hiện một số điều rất tốt với chúng.

Triết lý thiết kế Java là nhấn mạnh tính an toàn trong cấu trúc ngôn ngữ. Kết quả là có những thứ khó thực hiện hơn rất nhiều, nhưng bạn có thể tự tin hơn rất nhiều rằng mã bạn đang xem có nghĩa là những gì bạn nghĩ.

Hơn nữa, Java ở một mức độ lớn là phản ứng từ C ++ và Smalltalk, những ngôn ngữ OO được biết đến nhiều nhất. Có rất nhiều ngôn ngữ OO khác (Common Lisp thực sự là ngôn ngữ đầu tiên được chuẩn hóa), với các hệ thống OO khác nhau xử lý MI tốt hơn.

Chưa kể rằng bạn hoàn toàn có thể thực hiện MI trong Java, sử dụng giao diện, thành phần và ủy quyền. Nó rõ ràng hơn trong C ++, và do đó khó sử dụng hơn nhưng sẽ giúp bạn hiểu rõ hơn về cái nhìn đầu tiên.

Không có câu trả lời đúng ở đây. Có nhiều câu trả lời khác nhau và câu trả lời nào tốt hơn cho một tình huống nhất định phụ thuộc vào ứng dụng và sở thích cá nhân.


12

Lý do chính (mặc dù không phải là duy nhất) khiến mọi người tránh xa MI là cái gọi là "vấn đề kim cương" dẫn đến sự mơ hồ trong việc triển khai của bạn. Bài viết wikipedia này thảo luận về nó và giải thích tốt hơn tôi có thể. MI cũng có thể dẫn đến mã phức tạp hơn và rất nhiều nhà thiết kế OO tuyên bố rằng bạn không cần MI, và nếu bạn sử dụng nó, mô hình của bạn có thể sai. Tôi không chắc mình đồng ý với điểm cuối cùng này, nhưng giữ mọi thứ đơn giản luôn là một kế hoạch tốt.


8

Trong C ++, đa kế thừa là một vấn đề đau đầu khi sử dụng không đúng cách. Để tránh những vấn đề thiết kế phổ biến đó, nhiều giao diện "kế thừa" được buộc phải thay thế bằng các ngôn ngữ hiện đại (java, C #).


8

Thừa kế Nhiều là

  • khó hiểu
  • khó gỡ lỗi (ví dụ: nếu bạn kết hợp các lớp từ nhiều khung công tác có các phương thức được đặt tên giống hệt nhau, có thể xảy ra sự hợp lực khá bất ngờ)
  • dễ sử dụng
  • không hẳn là vậy hữu ích
  • khó thực hiện, đặc biệt nếu bạn muốn nó được thực hiện một cách chính xác hiệu quả

Do đó, có thể coi là một lựa chọn khôn ngoan khi không đưa Multiple Inheritance vào ngôn ngữ Java.


3
Tôi không đồng ý với tất cả những điều trên, đã làm việc với Hệ thống đối tượng Lisp chung.
David Thornley

2
Các ngôn ngữ động không được tính ;-) Trong bất kỳ hệ thống giống Lisp nào, bạn có REPL giúp việc gỡ lỗi khá dễ dàng. Ngoài ra, CLOS (theo tôi hiểu, tôi chưa bao giờ thực sự sử dụng nó, chỉ đọc về nó) là một hệ thống siêu đối tượng, với rất nhiều tính linh hoạt và thái độ của riêng bạn. Nhưng hãy xem xét một ngôn ngữ được biên dịch tĩnh như C ++, trong đó trình biên dịch tạo ra một số tra cứu phương thức phức tạp kinh khủng bằng cách sử dụng nhiều bảng (có thể chồng chéo): trong một triển khai như vậy, việc tìm ra cách triển khai của một phương thức có thể là một nhiệm vụ không hề nhỏ.
mfx

5

Một lý do khác là do đơn kế thừa làm cho việc ép kiểu trở nên tầm thường, không đưa ra các lệnh của trình hợp dịch (ngoại trừ việc kiểm tra tính tương thích của các kiểu khi được yêu cầu). Nếu bạn có đa kế thừa, bạn cần phải tìm ra vị trí trong lớp con mà một phụ huynh nhất định bắt đầu. Vì vậy, hiệu suất chắc chắn là một đặc quyền (mặc dù không phải là duy nhất).


4

Quay trở lại ngày xưa (những năm 70) khi Khoa học Máy tính mang tính Khoa học hơn và ít sản xuất hàng loạt hơn, các lập trình viên có thời gian suy nghĩ về thiết kế tốt và triển khai tốt và kết quả là các sản phẩm (chương trình) có chất lượng cao (ví dụ: thiết kế TCP / IP Và thực hiện ). Ngày nay, khi mọi người đang lập trình và các nhà quản lý đang thay đổi các thông số kỹ thuật trước thời hạn, các vấn đề tế nhị như vấn đề được mô tả trong liên kết wikipedia từ bài đăng của Steve Haigh rất khó theo dõi; do đó, "đa kế thừa" bị giới hạn bởi thiết kế trình biên dịch. Nếu bạn thích nó, bạn vẫn có thể sử dụng C ++ .... và có mọi quyền tự do bạn muốn :)


4
... trong đó có quyền tự do để bắn mình trong bàn chân, nhiều lần;)
Mario Ortegón

4

Tôi đưa ra tuyên bố rằng "Nhiều kế thừa không được phép trong Java" với một chút muối.

Kế thừa nhiều được định nghĩa khi một "Loại" kế thừa từ nhiều hơn một "Loại". Và các giao diện cũng được phân loại thành các loại khi chúng có hành vi. Vì vậy, Java có đa kế thừa. Chỉ là nó an toàn hơn.


6
Nhưng bạn không kế thừa từ một giao diện, bạn thực hiện nó. Các giao diện không phải là các lớp.
Blorgbeard ra mắt vào

2
Có, nhưng thừa kế chưa bao giờ được định nghĩa hẹp như vậy, ngoại trừ trong một số cuốn sách tiền kỳ. Và tôi nghĩ chúng ta nên nhìn xa hơn ngữ pháp của nó. Cả hai đều làm những điều tương tự, và các giao diện được "phát minh" chỉ vì lý do đó.
Rig Veda

Lấy giao diện Có thể đóng được: một phương thức, đóng (). Giả sử bạn muốn mở rộng điều đó, thành Openable: nó có một phương thức open () đặt trường boolean isOpen thành true. Cố gắng mở một Có thể mở đã mở sẽ ném ra một Ngoại lệ, cũng như cố gắng đóng một Có thể mở chưa mở ... Hàng trăm bảng phả hệ thú vị khác của các lớp có thể muốn áp dụng chức năng như vậy ... mà không cần phải chọn mở rộng từng lớp thời gian từ lớp Có thể mở được. Nếu Openable chỉ đơn giản là một giao diện, nó không thể cung cấp chức năng này. QED: giao diện không cung cấp tính kế thừa!
loài gặm nhấm mike

4

Việc tải động các lớp làm cho việc thực hiện đa kế thừa trở nên khó khăn.

Trong java thực sự họ đã tránh được sự phức tạp của đa kế thừa thay vào đó bằng cách sử dụng một giao diện và kế thừa. Tính phức tạp của đa kế thừa là rất cao trong một tình huống như giải thích dưới đây

vấn đề kim cương của đa thừa kế. Chúng ta có hai lớp B và C kế thừa từ A. Giả sử rằng B và C đang ghi đè một phương thức kế thừa và chúng cung cấp cách triển khai của riêng chúng. Bây giờ D kế thừa từ cả B và C thực hiện đa kế thừa. D nên kế thừa phương thức ghi đè đó, jvm không thể quyết định phương thức ghi đè nào sẽ được sử dụng?

Trong c ++, các hàm ảo được sử dụng để xử lý và chúng ta phải thực hiện một cách rõ ràng.

Điều này có thể tránh được bằng cách sử dụng các giao diện, không có cơ quan phương thức. Không thể khởi tạo các giao diện — chúng chỉ có thể được thực thi bởi các lớp hoặc được mở rộng bởi các giao diện khác.


3

Trên thực tế, đa kế thừa sẽ nảy sinh sự phức tạp nếu các lớp kế thừa có cùng chức năng. tức là trình biên dịch sẽ có một sự nhầm lẫn mà một trong những phải chọn (vấn đề kim cương). Vì vậy, trong Java, sự phức tạp đó đã được loại bỏ và cung cấp giao diện để có được chức năng như đa kế thừa đã cung cấp. Chúng ta có thể sử dụng giao diện


2

Java có khái niệm, tức là tính đa hình. Có 2 loại đa hình trong java. Có ghi đè phương thức và ghi đè phương thức. Trong số đó, ghi đè phương thức xảy ra với mối quan hệ lớp con và lớp con. Nếu chúng ta đang tạo một đối tượng của một lớp con và gọi phương thức của lớp cha và nếu lớp con mở rộng nhiều hơn một lớp, thì phương thức siêu lớp nào sẽ được gọi?

Hoặc, trong khi gọi hàm tạo siêu lớp bằng super(), phương thức khởi tạo siêu lớp nào sẽ được gọi?

Quyết định này là không thể bởi các tính năng API java hiện tại. vì vậy đa kế thừa không được phép trong java.


Về cơ bản, hệ thống kiểu của Java giả định rằng mọi cá thể đối tượng đều có một kiểu, việc truyền một đối tượng tới một kiểu siêu sẽ luôn hoạt động và được bảo toàn tham chiếu và việc truyền một tham chiếu đến một kiểu con sẽ là bảo toàn tham chiếu nếu cá thể thuộc kiểu con đó hoặc loại phụ của chúng. Những giả định như vậy rất hữu ích và tôi không nghĩ rằng có thể cho phép đa kế thừa tổng quát theo cách phù hợp với chúng.
supercat,

1

Kế thừa nhiều không được phép trực tiếp trong Java, nhưng thông qua các giao diện thì được phép.

Lý do:

Kế thừa nhiều: Giới thiệu sự phức tạp và mơ hồ hơn.

Giao diện: Giao diện là các lớp hoàn toàn trừu tượng trong Java cung cấp cho bạn một cách thống nhất để phân định chính xác cấu trúc hoặc hoạt động bên trong của chương trình của bạn từ giao diện có sẵn công khai của nó, với kết quả là lượng mã linh hoạt hơn và có thể sử dụng lại cũng như kiểm soát nhiều hơn về cách bạn tạo và tương tác với các lớp khác.

Chính xác hơn, chúng là một cấu trúc đặc biệt trong Java với đặc tính bổ sung cho phép bạn thực hiện kiểu đa kế thừa, tức là các lớp có thể được upcast lên nhiều hơn một lớp.

Hãy lấy ví dụ đơn giản.

  1. Giả sử có 2 lớp cha A và B có tên phương thức giống nhau nhưng chức năng khác nhau. Thông qua mã sau với (mở rộng) từ khóa đa kế thừa là không thể.

       public class A                               
         {
           void display()
             {
               System.out.println("Hello 'A' ");
             }
         }
    
       public class B                               
          {
            void display()
              {
                System.out.println("Hello 'B' ");
              }
          }
    
      public class C extends A, B    // which is not possible in java
        {
          public static void main(String args[])
            {
              C object = new C();
              object.display();  // Here there is confusion,which display() to call, method from A class or B class
            }
        }
  2. Nhưng thông qua các giao diện, có thể thực hiện đa kế thừa với từ khóa (thực hiện).

    interface A
        {
           // display()
        }
    
    
     interface B
        {
          //display()
        }
    
     class C implements A,B
        {
           //main()
           C object = new C();
           (A)object.display();     // call A's display
    
           (B)object.display(); //call B's display
        }
    }

0

Ai đó có thể cho tôi biết chính xác lý do tại sao nó không được phép không?

Bạn có thể tìm thấy câu trả lời từ liên kết tài liệu này

Một lý do tại sao ngôn ngữ lập trình Java không cho phép bạn mở rộng nhiều hơn một lớp là để tránh các vấn đề về trạng thái đa kế thừa, đó là khả năng kế thừa các trường từ nhiều lớp.

Nếu cho phép đa kế thừa và khi bạn tạo một đối tượng bằng cách khởi tạo lớp đó, thì đối tượng đó sẽ kế thừa các trường từ tất cả các siêu lớp của lớp đó. Nó sẽ gây ra hai vấn đề.

  1. Điều gì sẽ xảy ra nếu các phương thức hoặc hàm tạo từ các siêu lớp khác nhau khởi tạo cùng một trường?

  2. Phương thức hoặc hàm tạo nào sẽ được ưu tiên hơn?

Mặc dù trạng thái đa kế thừa hiện được cho phép, bạn vẫn có thể triển khai

Đa kế thừa kiểu : Khả năng của một lớp để triển khai nhiều hơn một giao diện.

Nhiều kế thừa của việc triển khai (thông qua các phương thức mặc định trong giao diện): Khả năng kế thừa các định nghĩa phương thức từ nhiều lớp

Tham khảo câu hỏi SE liên quan này để biết thêm thông tin:

Nhiều mơ hồ kế thừa với giao diện


0

Trong C ++, một lớp có thể kế thừa (trực tiếp hoặc gián tiếp) từ nhiều hơn một lớp, được gọi là đa kế thừa .

Tuy nhiên, C # và Java giới hạn các lớp ở mức kế thừa đơn lẻ, mỗi lớp kế thừa từ một lớp cha duy nhất.

Đa kế thừa là một cách hữu ích để tạo các lớp kết hợp các khía cạnh của hai phân cấp lớp khác nhau, điều thường xảy ra khi sử dụng các khung lớp khác nhau trong một ứng dụng.

Ví dụ: nếu hai khung công tác xác định các lớp cơ sở của riêng chúng cho các ngoại lệ, bạn có thể sử dụng đa kế thừa để tạo các lớp ngoại lệ có thể được sử dụng với một trong hai khung.

Vấn đề với đa kế thừa là nó có thể dẫn đến sự mơ hồ. Ví dụ cổ điển là khi một lớp kế thừa từ hai lớp khác, mỗi lớp kế thừa từ cùng một lớp:

class A {
    protected:
    bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
    public:
    void setFlag( bool nflag ){
        flag = nflag; // ambiguous
    }
};

Trong ví dụ này, flagthành viên dữ liệu được xác định bởi class A. Nhưng class Dgiảm dần từ class Bclass C, cả hai đều bắt nguồn từ A, vì vậy về bản chất, hai bản sao của flagcó sẵn vì hai thể hiện của Anằm trong Dhệ thống phân cấp lớp của. Bạn muốn đặt cái nào? Trình biên dịch sẽ phàn nàn rằng tham chiếu đến flagin Dkhông rõ ràng . Một cách khắc phục là phân biệt rõ ràng tham chiếu:

B::flag = nflag;

Một cách khắc phục khác là khai báo B và C là virtual base classes, có nghĩa là chỉ có một bản sao của A có thể tồn tại trong hệ thống phân cấp, loại bỏ mọi sự mơ hồ.

Sự phức tạp khác tồn tại với đa kế thừa, chẳng hạn như thứ tự mà các lớp cơ sở được khởi tạo khi một đối tượng dẫn xuất được xây dựng, hoặc cách các thành viên có thể vô tình bị ẩn khỏi các lớp dẫn xuất. Để tránh những phức tạp này, một số ngôn ngữ tự giới hạn mô hình kế thừa đơn giản hơn.

Mặc dù điều này làm đơn giản hóa việc kế thừa đáng kể, nhưng nó cũng hạn chế tính hữu dụng của nó vì chỉ các lớp có tổ tiên chung mới có thể chia sẻ các hành vi. Các giao diện giảm thiểu phần nào hạn chế này bằng cách cho phép các lớp trong các cấu trúc phân cấp khác nhau hiển thị các giao diện chung ngay cả khi chúng không được triển khai bằng cách chia sẻ mã.


-1

Hãy tưởng tượng ví dụ này: Tôi có một lớp học Shape1

Nó có CalcualteAreaphương pháp:

Class Shape1
{

 public void CalculateArea()

     {
       //
     }
}

Có một lớp khác Shape2cũng có cùng một phương thức

Class Shape2
{

 public void CalculateArea()

     {

     }
}

Bây giờ tôi có một lớp con Circle, nó bắt nguồn từ cả Shape1 và Shape2;

public class Circle: Shape1, Shape2
{
}

Bây giờ khi tôi tạo đối tượng cho Circle và gọi phương thức, hệ thống không biết phương thức tính diện tích nào sẽ được gọi. Cả hai đều có chữ ký giống nhau. Vì vậy, trình biên dịch sẽ bị nhầm lẫn. Đó là lý do tại sao nhiều thừa kế không được phép.

Nhưng có thể có nhiều giao diện vì các giao diện không có định nghĩa phương thức. Thậm chí cả hai giao diện đều có cùng một phương thức, cả hai đều không có bất kỳ thực thi nào và phương thức luôn trong lớp con sẽ được thực thi.


trình thiết kế ngôn ngữ có thể gọi phương thức rõ ràng giống như họ làm trong Giao diện. Không có điểm nào như vậy! Một lý do khác là làm thế nào về lớp trừu tượng với các phương thức trừu tượng bây giờ làm thế nào bạn xem xét điều đó?
Nomi Ali
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.