2016-02-26 2 views
0

Можно ли создать подкласс базового класса, например, создать представление таблицы в SQL, в C#?Как создать подкласс с ограничениями?

Пример желаемого поведения:

public class EmployeeSpecificUsage : Employee 
{ 
    public string firstName; 
    public string field1; 
    public int age; 

    public string Name; //Error! Not implemented in main class 
} 

public abstract class Employee 
{ 
    public string firstName; 
    public string lastname; 
    public int age; 
    public string workTitle; 
    public string field1; 
    public string field2; 
    public string field3; 
} 

Цель:

  • Сокращение числа членов полевых видимых.
  • Запрет добавления новых полей в соответствии с оригинальной моделью.
+1

Я предполагаю, вы имеете в виду «интерфейс», а не подкласс. – Haukinger

+4

Взгляды и подклассы - совершенно разные вещи. Представление - это подготовленный и сохраненный запрос, который выполняется в базе данных. Подкласс - это просто объект с разным/расширенным поведением по отношению к его базовому классу. Сначала вам следует рассмотреть некоторые основы ООП. Чего вы на самом деле хотите достичь? Скрыть некоторые поля вашего базового класса и добавить некоторые новые? – HimBromBeere

+1

Наличие члена класса 'Name' в субасе EmployeeSpecificUsage' полностью. Как уже упоминалось @HimBromBeere, я также предлагаю сначала прочитать книги ... Плюс рекомендую удалить этот вопрос. – Alex

ответ

1

интерфейс предоставляет доступ к аспекту класса (в отличие от производного класса, который фактически расширяет базовый класс).

Посмотрите на это:

public class Employee : IEmployeeSpecificUsage 
{ 
    public string firstName { get; } 
    public string lastname { get; } 
    public int age { get; } 
    public string workTitle { get; } 
    public string field1 { get; } 
    public string field2 { get; } 
    public string field3 { get; } 
} 

public interface IEmployeeSpecificUsage 
{ 
    public string firstName { get; } 
    public string field1 { get; } 
    public int age { get; } 
} 

Если вы ссылаетесь на Employee например, с помощью интерфейса IEmployeeSpecificUsage, вы будете только «видеть», что в интерфейсе.

Вы не можете добавлять новые интерфейсы, не изменяя при этом «базовый класс», поскольку он должен объявить, что он реализует эти интерфейсы.

+0

IEmployeeSpecificUsage e = new Employee() Очень просто, извините, все. Я был почти там. Также я хотел уметь переопределять/расширять методы, но сейчас я буду использовать методы расширений. У вас есть лучшее решение? – Gugas

0

Если вы хотите предоставить доступ только для чтения к внутреннему полю класса проверить общественное свойства с геттером. Обеспечьте защиту членов поля. Таким образом, у вас будет возможность реализовать пользовательскую логику для . Имя свойство, составляющее его из поля firstname и lastname.

public class EmployeeSpecificUsage : Employee 
{ 
    public string FirstName { get { return firstName; }}; 
    public string FullName { get { return string.Format("{0} {1}", firstName, lastName); }}; 
} 

public class Employee 
{ 
    protected string firstName; 
    protected string lastname; 
    protected int age; 
    protected string workTitle; 
    protected string field1; 
    protected string field2; 
    protected string field3; 
} 

Возможна установка свойств в базовом классе с защищенными сеттерами и общедоступными геттерами.

1

Интерфейсы могут использоваться как виды.

public interface IView 
{ 
    string FirstName { get; } 
    int Age { get; } 
    string Name { get; } 
} 

public class Employee: IView 
{ 
    // make fields private if possible   
    private string firstName; 
    private string lastname; 
    private int age; 
    private string workTitle; 
    private string field1; 
    private string field2; 
    private string field3; 

    // implements IView.FirstName as an auto property 
    public string FirstName { get; set; } 

    // implements IView.Age: returns the private age field 
    public int Age { get { return age;} } 

    // explicit implementation of IView.Name: visible only as IView 
    string IView.Name { get { return lastName + ", " + firstName; } } 
} 

И потом:

Employee employee1 = new Employee(); // FirstName and Age are visible on employee1 
IView employee2 = new Employee(); // Name is visible, too 
2

Ваше понимание подкласса неверно. Подклассификация - это путь , распространяющийся базовый класс, а не отвод от него. Каким бы ни был базовый класс, все подклассы также имели бы его.

Это отличается от представлений в SQL, что позволяет как отбирать столбцы, так и добавлять вычисленные столбцы.

Хотя наследование не позволяет сократить количество видимых элементов, вы можете сделать это с композицией. Заверните Employee в RestrictedEmployee и подвергать только те элементы, которые вы хотите, чтобы другие видели:

public class EmployeeSpecificUsage { 
    private readonly Employee wrapped; 
    public EmployeeSpecificUsage(Employee e) { 
     wrapped = e; 
    } 
    public string firstName => wrapped.firstName; 
    public string field1 => wrapped.field1; 
    // Two fields above use C# 6 syntax. If it is not available, 
    // use syntax below: 
    public int age { 
     get { 
      return wrapped.age; 
     } 
    } 
} 

Что касается запрета на добавление новых полей идет, вы не можете сделать это с помощью либо наследования или композиции: если вы имеете для подкласса вообще (т. е. базовый класс не является sealed), вы сможете добавлять новых участников.Композиция намного слабее, чем наследование, поэтому вы можете добавлять новые поля даже к классам sealed, обертывая их.

+0

Подкласс подразумевает Наследование не расширение. Также в названии было «получено», кто-то отредактировал его, его также можно было назвать подмножеством ... – Gugas

+0

В любом случае вы ответили на мой вопрос, хотя ответ от @Haukinger выглядит чище. – Gugas

+0

@ Gugas различия между двумя ответами заключаются в том, что другой требует способности модифицировать класс и легко обойти его. – dasblinkenlight

Смежные вопросы