Tôi có thể ghi đè một thuộc tính trong c # không? Làm sao?


77

Tôi có lớp Cơ bản này:

abstract class Base
{
  public int x
  {
    get { throw new NotImplementedException(); }
  }
}

Và hậu duệ sau:

class Derived : Base
{
  public int x
  {
    get { //Actual Implementaion }
  }
}

Khi tôi biên dịch, tôi nhận được cảnh báo này nói rằng định nghĩa của lớp Derived xlà sẽ ẩn phiên bản Base của nó. Có thể ghi đè các thuộc tính trong các phương thức giống như c # không?

Câu trả lời:


96

Bạn cần sử dụng virtual từ khóa

abstract class Base
{
  // use virtual keyword
  public virtual int x
  {
    get { throw new NotImplementedException(); }
  }
}

hoặc xác định một thuộc tính trừu tượng:

abstract class Base
{
  // use abstract keyword
  public abstract int x { get; }
}

Và sử dụng override từ khóa khi ở trong trẻ:

abstract class Derived : Base
{
  // use override keyword
  public override int x { get { ... } }
}

Nếu bạn KHÔNG ghi đè, bạn có thể sử dụng newtừ khóa trên phương thức để ẩn định nghĩa gốc.

abstract class Derived : Base
{
  // use new keyword
  public new int x { get { ... } }
}

12

Làm cho thuộc tính cơ sở trở nên trừu tượng và ghi đè hoặc sử dụng từ khóa mới trong lớp dẫn xuất.

abstract class Base
{
  public abstract int x { get; }
}

class Derived : Base
{
  public override int x
  {
    get { //Actual Implementaion }
  }
}

Hoặc là

abstract class Base
{
  public int x { get; }
}

class Derived : Base
{
  public new int x
  {
    get { //Actual Implementaion }
  }
}

4
Hoặc bạn có thể sử dụng ảo trên lớp cơ sở, như Jeffrey Zhao đã đề cập.
jrummell

5

Thay đổi chữ ký thuộc tính như hình dưới đây:

Lớp cơ sở

public virtual int x 
{ get { /* throw here*/ } }

Lớp có nguồn gốc

public override int x 
{ get { /*overriden logic*/ } }

Nếu bạn không cần triển khai trong lớp Cơ sở, chỉ cần sử dụng thuộc tính trừu tượng.

Căn cứ:

public abstract int x { get; }

Nguồn gốc:

public override int x { ... }

Tôi sẽ đề xuất bạn sử dụng thuộc abstracttính thay vì trhowing ngoại lệ NotImplemented trong getter, abstactmodifier sẽ buộc tất cả các lớp dẫn xuất thực hiện thuộc tính này, vì vậy bạn sẽ kết thúc với giải pháp an toàn trong thời gian biên dịch.


3
abstract class Base 
{ 
  // use abstract keyword 
  public virtual int x 
  { 
    get { throw new NotImplementedException(); } 
  } 
} 

3
abstract class Base
{

  public virtual int x
  {
    get { throw new NotImplementedException(); }
  }
}

hoặc là

abstract class Base
{
  // use abstract keyword
  public abstract int x
  {
    get;
  }
}

Trong cả hai trường hợp, bạn phải viết trong lớp dẫn xuất

public override int x
  {
    get { your code here... }
  }

sự khác biệt giữa hai điều này là với trừu tượng, bạn buộc lớp dẫn xuất thực hiện một cái gì đó và với Virtaul, bạn có thể cung cấp một hành vi mặc định mà lớp dẫn xuất có thể sử dụng như hiện tại hoặc thay đổi.

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.