Tương đương với trận chung kết của Java trong C # là gì?


560

Tương đương với Java finaltrong C # là gì?


131
Một nhận xét trên đầu lớp nói rằng "Nếu bạn ghi đè lên lớp này, bạn sẽ bị sa thải!" (tất nhiên đó là một trò đùa :)
Hemant

Câu trả lời:


861

Các finaltừ khóa có một số tập quán trong Java. Nó tương ứng với cả từ khóa sealedreadonlytừ khóa trong C #, tùy thuộc vào ngữ cảnh mà nó được sử dụng.

Các lớp học

Để ngăn phân lớp (kế thừa từ lớp được xác định):

Java

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

Phương pháp

Ngăn chặn ghi đè một virtualphương thức.

Java

public class MyClass
{
    public final void myFinalMethod() {...}
}

C #

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

Như Joachim Sauer chỉ ra, một sự khác biệt đáng chú ý giữa hai ngôn ngữ ở đây là Java theo mặc định đánh dấu tất cả các phương thức không tĩnh là virtual, trong khi C # đánh dấu chúng là sealed. Do đó, bạn chỉ cần sử dụng sealedtừ khóa trong C # nếu bạn muốn dừng ghi đè thêm một phương thức đã được đánh dấu rõ ràng virtualtrong lớp cơ sở.

Biến

Để chỉ cho phép một biến được gán một lần:

Java

public final double pi = 3.14; // essentially a constant

C #

public readonly double pi = 3.14; // essentially a constant

Là một lưu ý phụ, tác dụng của readonlytừ khóa khác với từ constkhóa ở chỗ readonlybiểu thức được đánh giá trong thời gian chạy thay vì thời gian biên dịch , do đó cho phép các biểu thức tùy ý.


15
Tôi muốn thêm rằng tất cả các phương thức không tĩnh trong Java là ảo theo mặc định. Vì vậy, trong khi ở C #, bạn chỉ cần bỏ ảo trong định nghĩa ban đầu, bạn sẽ cần sử dụng "cuối cùng" để tránh các lớp con ghi đè lên nó trong Java
Joachim Sauer

167
câu trả lời hay - mặc dù có thêm một cách sử dụng "cuối cùng" trong java - trên một biến cục bộ hoặc tham số phương thức để ngăn chặn việc gán lại nó. Không có c # tương đương trực tiếp với điều này.
serg10

17
readonlycác biến thành viên có thể được sửa đổi trong các hàm tạo: pastebin.com/AzqzYGiA
đệ quy

8
Cũng lưu ý: Nếu bạn khai báo một biến thành viên là cuối cùng trong Java, trình biên dịch sẽ phàn nàn, nếu không phải mọi nhà xây dựng đều gán một giá trị trong mỗi đường dẫn mã, trong khi C # chỉ đưa ra cảnh báo trong kịch bản đó với các biến thành viên chỉ đọc
Mene

1
@NickolayKondratyev: Đúng, ví dụ của tôi đã ngầm hiểu rằng bạn cần phải phân lớp từ một lớp khác. Bạn không cần giao diện thực sự; đó là thừa, nhưng nếu không thì có vẻ đúng.
Noldorin

180

Nó phụ thuộc vào ngữ cảnh.


1
Trên thực tế không có yêu cầu rằng một biến cuối cùng được gán khi nó được khai báo. 'Final' có nghĩa là biến phải được chỉ định bởi một số đường dẫn mã trước khi nó được tham chiếu và không có đường dẫn mã nào cho phép biến được gán nhiều lần. Điều này áp dụng cho các biến thể hiện, có nghĩa là các nhà xây dựng phải gán biến rõ ràng.
Jay

31
+ cho For a final local variable or method parameter, there's no direct C# equivalentmột sự khác biệt rất lớn.
Daniel B. Chapman

1
Nếu bạn đang khởi tạo , const cho một biến cục bộ có thể được sử dụng. Nó không tương đương vì tất nhiên cuối cùng cho phép bạn khai báo và khởi tạo riêng (và do đó có các giá trị khác nhau), nhưng chỉ trong trường hợp bạn không biết ...
Griknok

3
constchỉ có thể được sử dụng trên các loại giá trị. Theo như tôi biết thì không có cách nào tạo ra hằng số hiệu quả cho kiểu tham chiếu cục bộ.
vui vẻ

2
@jocull Với chuỗi là ngoại lệ duy nhất.
Raimund Krämer

46

Điều mọi người ở đây đang thiếu là sự đảm bảo của Java về việc gán xác định cho các biến thành viên cuối cùng.

Đối với một lớp C có biến thành viên cuối cùng V, mọi đường dẫn thực thi có thể thông qua mọi hàm tạo của C phải gán V chính xác một lần - không gán V hoặc gán V hai lần trở lên sẽ dẫn đến lỗi.

Từ khóa chỉ đọc của C # không có bảo đảm như vậy - trình biên dịch sẽ rất vui khi không để các thành viên chỉ đọc không được chỉ định hoặc cho phép bạn gán chúng nhiều lần trong một hàm tạo.

Vì vậy, cuối cùng và chỉ đọc (ít nhất là đối với các biến thành viên) chắc chắn không tương đương - cuối cùng thì nghiêm ngặt hơn nhiều.


7

Như đã đề cập, sealedtương đương với các finalphương thức và các lớp.

Đối với phần còn lại, nó là phức tạp.

  • Đối với static finalcác lĩnh vực, static readonlylà điều gần nhất có thể. Nó cho phép bạn khởi tạo trường tĩnh trong một hàm tạo tĩnh, tương đối giống với trình khởi tạo tĩnh trong Java. Điều này áp dụng cho cả hằng số (nguyên thủy và đối tượng bất biến) và tham chiếu không đổi đến các đối tượng có thể thay đổi.

    Công cụ constsửa đổi khá giống nhau cho các hằng số, nhưng bạn không thể đặt chúng trong một hàm tạo tĩnh.

  • Trên một trường không nên được chỉ định lại khi nó rời khỏi hàm tạo, readonlycó thể được sử dụng. Mặc dù vậy, nó không bằng nhau - finalyêu cầu chính xác một phép gán ngay cả trong hàm tạo hoặc trình khởi tạo.
  • Không có C # tương đương với một finalbiến cục bộ mà tôi biết. Nếu bạn đang tự hỏi tại sao mọi người sẽ cần nó: Bạn có thể khai báo một biến trước một if-if, switch-case hoặc như vậy. Bằng cách tuyên bố nó là cuối cùng, bạn thực thi rằng nó được gán nhiều nhất một lần.

    Các biến cục bộ Java nói chung được yêu cầu phải được chỉ định ít nhất một lần trước khi chúng được đọc. Trừ khi nhánh nhảy ra trước khi đọc giá trị, một biến cuối cùng được gán chính xác một lần. Tất cả điều này được kiểm tra thời gian biên dịch. Điều này đòi hỏi mã hoạt động tốt với ít lề cho một lỗi.

Tóm lại, C # không có tương đương trực tiếp final. Mặc dù Java thiếu một số tính năng hay của C #, nhưng đối với tôi, phần lớn là một lập trình viên Java để xem C # không cung cấp tương đương ở đâu.


6

Lớp cuối cùng của lớp Java và phương thức cuối cùng -> được niêm phong. Biến thành viên Java cuối cùng -> chỉ đọc cho hằng số thời gian chạy, const cho hằng số thời gian biên dịch.

Không tương đương với Chung kết biến đối số và phương thức cuối cùng



0

niêm phong


8
Đó chỉ là một phần của câu trả lời vì nó phụ thuộc vào ngữ cảnh và thêm một lời giải thích và / hoặc ví dụ sẽ giúp nó dễ tiêu hóa hơn rất nhiều cho những người cần giúp đỡ
Rune FS
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.