Множественное наследование в C#

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

207
задан JK. 12 May 2012 в 17:09
поделиться

7 ответов

Поскольку множественное наследование - это плохо (это усложняет исходный код), C # не предоставляет такой шаблон напрямую. Но иногда было бы полезно иметь эту возможность.

C # и .net CLR не реализовали MI, потому что они еще не пришли к выводу, как это будет взаимодействовать между C #, VB.net и другими языками, а не потому, что " это сделало бы исходный код более сложным »

MI - полезная концепция, неотвеченные вопросы такие как: -« Что вы делаете, когда у вас есть несколько общих базовых классов в разных суперклассах?

Perl - единственный язык, с которым я когда-либо работал, где MI работает и работает хорошо. .Net вполне может представить его в один прекрасный день, но пока нет, CLR уже поддерживает MI, но, как я уже сказал, для него еще нет языковых конструкций.

120
ответ дан 23 November 2019 в 04:44
поделиться

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

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

я не вижу оснований, почему это не могло быть реализовано в компиляторе C# - но это - другой бит сложности языка...

14
ответ дан Vegard Larsen 29 July 2019 в 05:53
поделиться

Множественное наследование является одной из тех вещей, которая обычно вызывает больше проблем, чем это решает. В C++ это соответствует шаблону предоставления Вам достаточно веревки для зависания себя, но Java и C# приняли решение пойти более безопасным путем не предоставления Вам опция. Самая большая проблема состоит в том, что сделать, если Вы наследовали несколько классов, которые имеют метод с той же подписью, которую не реализует inheritee. Какой метод класса это должно выбрать? Или это не должно компилировать? Обычно существует другой способ реализовать большинство вещей, который не полагается на множественное наследование.

0
ответ дан tloach 23 November 2019 в 04:44
поделиться

Если можно жить с ограничением, что методы IFirst и ISecond должны только взаимодействовать с контрактом IFirst и ISecond (как в примере)..., можно сделать то, что Вы спрашиваете с дополнительными методами. На практике это редко имеет место.

public interface IFirst {}
public interface ISecond {}

public class FirstAndSecond : IFirst, ISecond
{
}

public static MultipleInheritenceExtensions
{
  public static void First(this IFirst theFirst)
  {
    Console.WriteLine("First");
  }

  public static void Second(this ISecond theSecond)
  {
    Console.WriteLine("Second");
  }
}

///

public void Test()
{
  FirstAndSecond fas = new FirstAndSecond();
  fas.First();
  fas.Second();
}

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

1
ответ дан Amy B 23 November 2019 в 04:44
поделиться

MI не плох, все, которые (серьезно) использовали его, ЛЮБИТ его и это, doesNOT усложняют код! По крайней мере, не больше, чем другие конструкции может усложнить код. Плохой код является плохим кодом независимо от того, является ли MI в изображении.

Так или иначе, у меня есть миленькое решение для Множественного наследования, которое я хотел совместно использовать, это в; http://ra-ajax.org/lsp-liskov-substitution-principle-to-be-or-not-to-be.blog или можно перейти по ссылке в моем сигнале...:)

2
ответ дан Thomas Hansen 23 November 2019 в 04:44
поделиться

У Вас мог быть один абстрактный базовый класс, который реализует и IFirst и ISecond, и затем наследуйтесь просто той основе.

5
ответ дан Joel Coehoorn 23 November 2019 в 04:44
поделиться

Рассмотрите просто использование состав вместо того, чтобы пытаться моделировать Множественное наследование. Можно использовать Интерфейсы для определения, какие классы составляют состав, например: ISteerable подразумевает, что свойство типа SteeringWheel, IBrakable подразумевает свойство типа BrakePedal, и т.д.

, Как только Вы сделали это, Вы могли использовать опция Extension Methods , добавленная к C# 3.0 для дальнейшего упрощения вызывающих методов для тех подразумеваемых свойств, например:

public interface ISteerable { SteeringWheel wheel { get; set; } }

public interface IBrakable { BrakePedal brake { get; set; } }

public class Vehicle : ISteerable, IBrakable
{
    public SteeringWheel wheel { get; set; }

    public BrakePedal brake { get; set; }

    public Vehicle() { wheel = new SteeringWheel(); brake = new BrakePedal(); }
}

public static class SteeringExtensions
{
    public static void SteerLeft(this ISteerable vehicle)
    {
        vehicle.wheel.SteerLeft();
    }
}

public static class BrakeExtensions
{
    public static void Stop(this IBrakable vehicle)
    {
        vehicle.brake.ApplyUntilStop();
    }
}


public class Main
{
    Vehicle myCar = new Vehicle();

    public void main()
    {
        myCar.SteerLeft();
        myCar.Stop();
    }
}
205
ответ дан Chris Wenham 23 November 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: