2009-02-17 73 views
37

Tôi đang cố gắng kế thừa một lớp không tĩnh bởi một lớp tĩnh.Làm thế nào một lớp tĩnh có thể lấy được từ một đối tượng?

public class foo 
{ } 

public static class bar : foo 
{ } 

Và tôi nhận được:

lớp tĩnh không thể xuất phát từ loại. Các lớp tĩnh phải lấy từ đối tượng .

Tôi có thể lấy nó từ đối tượng bằng cách nào?

Mã này nằm trong C#.

+1

Có trường hợp sử dụng nào cho điều này không? –

Trả lời

48

Không có giá trị trong việc phát sinh các lớp tĩnh. Những lý do để sử dụng thừa kế là:

  • Polymorphism
  • Mã tái sử dụng

Bạn không thể nhận đa hình với các lớp tĩnh, rõ ràng, vì không có ví dụ để tự động cử trên (nói cách khác , nó không giống như bạn có thể vượt qua một Bar đến một chức năng mong đợi một Foo, vì bạn không một Bar).

Sử dụng lại mã có thể dễ dàng được giải quyết bằng cách sử dụng bố cục: cung cấp Bar cho trường hợp tĩnh của Foo.

+3

+1 Để cung cấp giải pháp đơn giản và phù hợp cho vấn đề của OP. – Brian

+0

Xin lỗi vì "đào bài" nhưng tôi muốn làm điều tương tự và tôi nghĩ câu trả lời của bạn là tốt nhất, tôi tự hỏi làm cách nào bạn tiếp cận trường hợp sử dụng 'foo' có một số phương thức được bảo vệ' thanh 'muốn sử dụng. – Samo

+2

Bạn đang nói rằng bạn muốn một lớp * Bar * tĩnh * kế thừa từ một * không tĩnh * 'Foo' để nó có thể đến được các thành viên được bảo vệ của nó? Có rất nhiều fishiness trong thiết kế đó (hiếm khi cho một lớp duy nhất có ý nghĩa trong cả một bối cảnh tĩnh và không tĩnh).Tuy nhiên, giả sử bạn có một lý do hợp lệ cho điều này, một giải pháp là có 'Bar' có một lớp không tĩnh riêng bên trong mà thừa hưởng từ' Foo' (gọi nó là 'FooWrapper'). Nó có các phương thức công khai chuyển tiếp đến các phương thức được bảo vệ mà nó kế thừa. 'Bar' sau đó có thể có một thể hiện của' FooHelper' và nhận được các thành viên được bảo vệ trong 'Foo' thông qua đó. – munificent

0

Không phải tất cả các lớp (bao gồm tĩnh) đã xuất phát từ đối tượng? Như trong, theo mặc định?

Ngoài ra, giống như nó nói, "Lớp tĩnh không thể lấy được từ loại", vì vậy tôi không nghĩ rằng những gì bạn đang làm là có thể. Tại sao bạn muốn một lớp tĩnh bắt nguồn từ một loại anyways?

0

Không thể. Bạn phải tạo một lớp bình thường để lấy được từ một số lớp khác.

2

Tôi không nghĩ rằng C# hỗ trợ kế thừa cho các lớp tĩnh.

Một lựa chọn sẽ được sử dụng Singleton pattern thay

public class foo 
{ } 

public class bar : foo 
{ 
    private bar instance; 
    public bar GetInstance() 
    { 
     if(instance == null) instance = new bar(); 
     return instance; 
    } 

    private bar(){} //make default constructor private to prevent instantiation 
} 
+0

Singleton không phải là điều tôi muốn giới thiệu. Hãy rất cẩn thận khi sử dụng nó. Xem: http://www.google.com/search?source=ig&hl=vi&rlz=&=&q=singleton+bad&btnG=Google+Search&aq=f –

+2

Tôi nghĩ rằng ví dụ của bạn là thiếu sót, nếu hai chủ đề thành công vượt qua nếu (Ví dụ == null) nó sẽ khởi tạo một thanh mới hai lần. – TomHastjarjanto

+0

Đoạn mã trên tạo lỗi: Các lớp tĩnh không thể có các hàm tạo ví dụ – Ali

13

Các thông báo lỗi là không có thật. Nó không nói "một" đối tượng. Nó nói về kiểu tích hợp được gọi là "đối tượng", là cơ sở của mọi thứ trong .NET.

Cần phải nói "lớp tĩnh không thể chỉ định loại cơ sở".

+4

Không, cần phải nói "Các lớp tĩnh không thể chỉ định một kiểu cơ sở. Các lớp tĩnh luôn ngầm xuất phát từ System.Object." Lưu ý rằng bạn không thể lấy được một lớp tĩnh từ một lớp tĩnh khác. –

+1

Đã sửa. Cảm ơn Jon. – GeekyMonkey

0

Tất cả các lớp bắt nguồn từ Object. Điều đó nói rằng, mặc dù các lớp tĩnh (theo định nghĩa chỉ là các thùng chứa cho các thành viên tĩnh) "lấy được" từ đối tượng, không có gì bạn có thể nhận được từ thực tế đó.

0

Thông báo lỗi gây hiểu lầm.

thanh không thể kế thừa từ foo vì foo có thể được khởi tạo và thanh không thể.

+1

Đó không phải là một lý do chính nó. Đặc tả C# có thể dễ dàng cho phép trường hợp này - nó chỉ xảy ra không. –

+3

Holy crap là Jon Skeet !! * cảm thấy may mắn hoặc một cái gì đó * ;-) – teedyay

22

Từ đặc điểm kỹ thuật C# 3.0, phần 10.1.1.3:

Một lớp tĩnh có thể không bao gồm đẳng cấp cơ sở đặc điểm kỹ thuật (§10.1.4) và không thể xác định một cách rõ ràng một lớp cơ sở hoặc danh sách các giao diện được triển khai. A lớp tĩnh hoàn toàn kế thừa từ loại object.

Nói cách khác, bạn không thể làm điều này.

7

Taken từ http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx

Các tính năng chính của một lớp tĩnh là:

Họ chỉ chứa các thành viên tĩnh.

Chúng không thể được khởi tạo.

Chúng được niêm phong.

Chúng không thể chứa Instance Constructors (Hướng dẫn lập trình C#).

Vì vậy, kế thừa từ một lớp không tĩnh vi phạm tính năng đầu tiên của các lớp tĩnh trong danh sách này bằng cách giới thiệu thành viên không tĩnh vào lớp tĩnh của bạn.

+1

Đây là câu trả lời giải quyết vấn đề gốc. – Anshul

+0

Đó là một sự xấu hổ họ không cho phép bạn kế thừa từ một lớp tĩnh thực sự, như tôi đã chỉ đi qua một kịch bản mà nó sẽ có được tiện dụng. Nếu nó được thực hiện, bạn chỉ cần cung cấp một constructor tĩnh parameterless để gọi constructor của lớp cơ sở, và tất cả các cá thể thành viên sẽ trở thành thành viên tĩnh ... –

1

Như đã nêu trước đó, thông số C# nói rằng điều này không thể thực hiện được. Bạn không thể thực hiện một giao diện với các lớp tĩnh. Đặt cược tốt nhất của bạn là thay đổi từ việc sử dụng một lớp tĩnh để sử dụng một lớp có sử dụng mẫu đơn. Bạn sẽ chỉ có một cá thể (tương tự như cách lớp tĩnh hoạt động) và bạn sẽ có thể kế thừa hành vi hoặc thực hiện các giao diện.

Bạn đọc trên Singletons here, herehere.

0

Nếu bạn đang cố ngăn mọi người tạo phiên bản của lớp, chỉ cần thêm hàm tạo mặc định riêng tư.

+0

Mục đích của tôi là ngừng tạo các thể hiện của bar nhưng vấn đề với nhà xây dựng tư nhân sẽ là tôi sẽ cần phải thay đổi các biến và chức năng trong foo cũng để tĩnh để có thể truy cập chúng. – Ali

+0

Trong trường hợp đó, bạn nên sử dụng bố cục thay vì thừa kế; thanh chứa một thể hiện chỉ đọc tĩnh của foo. –

0

lớp tĩnh không thể là lớp cơ sở cho các lớp khác và không thể mở rộng.

lớp tĩnh có thể được thừa hưởng chỉ từ lớp "đối tượng" (lớp cơ sở net).

Thông tin bổ sung: Tất cả các lớp trong .net được thừa kế từ lớp "đối tượng", thậm chí bất kỳ lớp tĩnh nào cũng có.

Sự khác biệt là mặc dù lớp tĩnh kế thừa "lớp đối tượng" nhưng nó chỉ kế thừa hai phương thức tĩnh từ lớp "đối tượng".

Các lớp không tĩnh khác kế thừa bốn phương thức khác.

0

Như đã nói trong câu trả lời khác, thông báo trình biên dịch là khó hiểu nhưng chính xác.Bạn có thể viết:

static class A : object 
{ 
} 

tất nhiên nó không phải là thực sự hữu ích để nói rõ thừa kế này nhưng thừa kế chính nó là thực sự hữu ích trong khuôn khổ như bạn ghi đè các thành viên ảo của đối tượng:

static class A : object 
    { 
     public static new string ToString() 
     { 
      return "I am object A"; 
     } 

     public static new int GetHashCode() 
     { 
      return ToString().GetHashCode(); 
     } 
    } 
0

Như Christopher đã chỉ ra, giả sử chúng ta có thể lấy được lớp tĩnh từ lớp không tĩnh.

ví dụ:

public class foo 
{ 
    public int myVar; 
} 

public static class bar : foo { } 

đây, thanh lớp có nguồn gốc từ foo, do đó lớp tĩnh Bar có không tĩnh thành viên myVar bây giờ, và Theo C# Đặc điểm kỹ thuật, tĩnh Lớp học không thể chứa thành viên không tĩnh!

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