Что такое Затенение?

Вы можете использовать pd.concat() и apply() после переименования некоторых столбцов:

def reformat(x):

    return pd.concat([x[['WELL','X1','Y1','TD2']], x[['WELL','X2','Y2','TD2']].rename(columns={'X2': 'X1', 'Y2': 'Y1'})], axis=0).sort_values('WELL')

out = df.groupby(['TYPE','RESV']).apply(reformat).reset_index().drop('level_2', axis=1)

Выход:

   TYPE RESV WELL    X1   Y1   TD2
0   INJ    B   W2   120  255   695
1   INJ    B   W2   700   -7   695
2   INJ    B   W6   200  275  1495
3   INJ    B   W6  1500  -15  1495
4   INJ    B   W8   240  285  1895
5   INJ    B   W8  1900  -19  1895
6   OBS    A   W5   180  270  1295
7   OBS    A   W5  1300  -13  1295
8   OBS    A   W7   220  280  1695
9   OBS    A   W7  1700  -17  1695
10  OBS    B   W3   140  260   895
11  OBS    B   W3   900   -9   895
12   OP    A   W1   100  250   495
13   OP    A   W1   500   -5   495
14   OP    A   W9   260  290  2095
15   OP    A   W9  2100  -21  2095
16   OP    B   W4   160  265  1095
17   OP    B   W4  1100  -11  1095
34
задан Machavity 7 August 2017 в 12:18
поделиться

7 ответов

Затенение скрывает метод в базовом классе. Используя пример в вопросе Вы связались:

class A 
{
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A
{
   public new int Foo() { return 1;}
   public override int Bar() {return 1;}
}

Класс B переопределяет виртуальный метод Bar. Это скрывает (тени) невиртуальный метод Foo. Переопределение использует ключевое слово переопределения. Затенение сделано с новым ключевым словом.

В коде выше, если Вы не использовали новое ключевое слово при определении Foo метод в классе B, Вы получили бы это предупреждение компилятора:

'test.B.Foo()' hides inherited member 'test.A.Foo()'. Use the new keyword if hiding was intended.
45
ответ дан Jim Mischel 27 November 2019 в 16:02
поделиться
  • Переопределение: переопределение существующего метода на базовом классе
  • Затенение: создание совершенно нового метода с той же подписью как один в базовом классе
32
ответ дан Tim Cooper 27 November 2019 в 16:02
поделиться

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

public class A
{
    public virtual void M() { Console.WriteLine("In A.M()."); }
}

У меня также есть производный класс, который также определяет метод M:

public class B : A
{
    // could be either "new" or "override", "new" is default
    public void M() { Console.WriteLine("In B.M()."); }
}

Теперь, предположите, что я пишу программу как это:

A alpha = new B(); // it's really a B but I cast it to an A
alpha.M();

У меня есть два различных варианта для того, как я хочу, чтобы это было реализовано. Поведение по умолчанию состоит в том, чтобы назвать версию A M. (Это идентично поведению, если Вы подали заявку"new"ключевое слово к B.M().)

Это называют "затенением", когда у нас есть метод с тем же именем, но другое поведение при вызове от базового класса.

Поочередно, мы, возможно, указали"override"на B.M(). В этом случае, alpha.M() назвал бы версию B M.

21
ответ дан mqp 27 November 2019 в 16:02
поделиться

Затенение состоит при сокрытии метода базового класса с новым определением в дочернем классе.

Различие между сокрытием и переопределением имеет отношение к способу, которым вызываются методы.

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

С другой стороны, когда метод скрыт, новый адрес добавляется к таблице вызова метода дочернего класса.

Когда вызов выполняется к рассматриваемому методу:

  1. Тип класса таблицы вызова метода получен, если мы вызываем со ссылкой на базовый класс затем, таблица метода базового класса получена, если у нас есть ссылка на дочерний класс, затем таблица метода дочернего класса получена.
  2. Метод ищется в таблице, если найдено затем, что вызов происходит, иначе таблица метода базового класса ищется.

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

Если мы вызываем метод со ссылкой на базовый класс затем изменения поведения. При переопределении, поскольку адрес метода перезаписывает запись базового класса, мы назовем дочерний метод, держа ссылку на базовый класс. С затенением таблица метода базового класса (который является единственным, видимым, поскольку мы держим ссылку на базовый класс) содержит виртуальный адрес метода, и поэтому, метод базового класса назовут.

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

10
ответ дан Jorge Córdoba 27 November 2019 в 16:02
поделиться

Подробно останавливаясь на корректном ответе Кента

При устранении неоднозначности, когда, какой метод назовут, мне понравится думать о затенении по сравнению с переопределением со следующим

  • Затенение: названный метод зависит от типа ссылки в точке, вызов выполняется
  • Переопределение: названный метод зависит от типа объекта в точке, вызов выполняется.
8
ответ дан JaredPar 27 November 2019 в 16:02
поделиться

Вот статья MSDN о Затенении. Примеры языка находятся в Visual Basic (к сожалению, нет никакой эквивалентной страницы C# на MSDN), но он обычно имеет дело с понятиями и надо надеяться должен помочь Вам понять так или иначе.

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

3
ответ дан Noldorin 27 November 2019 в 16:02
поделиться

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

-3
ответ дан Jeremy 27 November 2019 в 16:02
поделиться
Другие вопросы по тегам:

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