Наследование + вложенные классы в C # - PullRequest
9 голосов
/ 25 сентября 2011

Мы можем иметь вложенные классы в C #.Эти вложенные классы также могут наследовать OuterClass.Например:

public class OuterClass
{
  // code here
  public class NestedClass : OuterClass
  {
    // code here
  }
}

полностью приемлемо.

Мы также можем достичь этого, не делая NestedClass как вложенный класс для OuterClass, как показано ниже:

public class OuterClass
{
  // code here
}

public class NestedClass : OuterClass
{
  // code here
}

Мне интересноВ чем разница между двумя сценариями?Что достижимо в сценарии I, чего нельзя достичь в сценарии II?Есть ли что-то, что мы можем получить, сделав NestedClass «вложенным» в OuterClasss?

Ответы [ 4 ]

15 голосов
/ 25 сентября 2011

второй приведенный вами пример: не вложенный класс, а обычный класс, производный от OuterClass.

  • вложенные типы по умолчанию имеют private видимость, но могут быть объявлены с более широкой видимостью
  • вложенные типы могут обращаться к свойствам, полям и методам содержащего типа (даже объявленным private и наследуемым от базовых типов)

также посмотрите на этот вопрос здесь о том, когда и зачем использовать вложенные классы.
Ссылка MSDN: Вложенные типы (Руководство по программированию в C #)

EDIT
Чтобы ответить на комментарий @ Henk о разнице в характере обоих отношений (наследование против вложенных типов): В обоих случаях у вас есть отношения между двумя классами, но они имеют различную природу. При наследовании от базового класса производный класс наследует все (кроме private) методы, свойства и поля базового класса. Это не верно для вложенного класса. Вложенные классы ничего не наследуют, но имеют доступ ко всему в содержащем классе - даже к private полям, свойствам и методам.

5 голосов
/ 25 сентября 2011

Наследование от родительского класса не позволяет вложенному классу видеть приватные члены и методы его родителя, только защищенные (и публичные). Вложение его в родительский класс позволяет ему видеть все закрытые члены и вызывать его закрытые методы, независимо от того, наследует ли вложенный класс родительский класс или нет.

4 голосов
/ 08 августа 2012

Возможно, уже слишком поздно, но позвольте мне добавить мои 2 цента. Пожалуйста, , Если я правильно понял ваш вопрос, вы имеете в виду:

В чем преимущество вложенного класса, который также унаследован от его внешнего класса?

Ключевой момент в строительстве

Первый код:

    public class OuterClass
{
    public OuterClass{console.writeln("OuterClaass Called");}

  public class NestedClass : OuterClass //It does Inherit
  {
    public NestedClass{console.writeln("NestedClass Called");}
  }
}

static void Main()
{
  outerClass.NestedClass nestedobject = new outerClass.NestedClass();
}

Выход:

Outerclass Called

NestedClass Called

Второй код:

public class OuterClass
{
    public OuterClass{console.writeln("OuterClaass Called");}

  public class NestedClass //it dosent Inherit
  {
    public NestedClass{console.writeln("NestedClass Called");}
  }
}

static void Main()
{

  OuterClass.NestedClass nestedobject = new OuterClass.NestedClass();
}

Выход:

NestedClass называется


В первом коде при создании объекта NestedClass конструктор OutrClass также будет вызываться, и, на мой взгляд, это означает Соотношение композиции между NestedClass и OuterClass, но в Второй код Объектная конструкция NestedClass и Outerclass не ограничена и выполняется независимо.

надеюсь, это будет полезно.

0 голосов
/ 17 ноября 2016

Вложенные классы отличаются от подклассов тем, как они могут получить доступ к свойствам и закрытым полям класса контейнера при наследовании от него.

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

Например, используя практический класс для подключения к базе данных и вставки данных:

public class WebDemoContext
{
    private SqlConnection Conn;
    private string connStr = ConfigurationManager.ConnectionStrings["WebAppDemoConnString"].ConnectionString;

    protected void connect()
    {
        Conn = new SqlConnection(connStr);
    }

    public class WebAppDemo_ORM : WebDemoContext
    {
        public int UserID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public string UserName { get; set; }
        public string UserPassword { get; set; }

        public int result = 0;

        public void RegisterUser()
        {
            connect();
            SqlCommand cmd = new SqlCommand("dbo.RegisterUser", Conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("FirstName", FirstName);
            cmd.Parameters.AddWithValue("LastName", LastName);
            cmd.Parameters.AddWithValue("Phone", Phone);
            cmd.Parameters.AddWithValue("Email", Email);
            cmd.Parameters.AddWithValue("UserName", UserName);
            cmd.Parameters.AddWithValue("UserPassword", UserPassword);

            try
            {
                Conn.Open();
                result = cmd.ExecuteNonQuery();
            }
            catch (SqlException se)
            {
                DBErrorLog.DbServLog(se, se.ToString());
            }
            finally
            {
                Conn.Close();
            }
        }
    }
}

Класс WebAppDemo_ORM является вложенным классом внутри WebDemoContext и в то же время наследуется от WebDemoContext, таким образом, вложенный класс может получить доступ ко всем членам класса контейнера, включая закрытые, что может быть эффективным для сокращения DRY и достижение SOC .

...