Могут ли поля дочернего класса использоваться в родительском классе? - PullRequest
0 голосов
/ 30 августа 2018

Есть ли способ использовать поля или свойства дочерних классов внутри конструктора или методов родительского класса?

public class Parent
{
    public Parent()
    {

    }
}
public class Child : Parent
{
    public int y;
    public Child()
    {

    }
}
class Program
{
    static void Main(string[] args)
    {
        Parent obj = new Child();
        obj.y = 10;
    }
}

В приведенном выше коде я не могу получить доступ к полю 'y'

Ответы [ 5 ]

0 голосов
/ 30 августа 2018

Нет. Объекты, которые наследуются от Parent, не обязательно имеют свойство y типа int. Фактически это было бы нарушением принципа подстановки Лискова (L в SOLID). Этот принцип означает, что я должен иметь возможность назначать любой объект типа, который происходит от Parent, к этой переменной, и логика должна работать. Ясно, что если бы я создал класс Child2, который унаследован от Parent, но не имел свойства ay, или объявил y как некоторый другой тип (например, DateTime), то ваш код сам по себе, очевидно, не смог бы присвоить значение 10 этому экземпляру объекта.

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

0 голосов
/ 30 августа 2018

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

Parent parent = new Child();
Child child = (Child)parent;
child.y = 10;

Но вы должны иметь в виду, что Child child = (Child)parent; может выдать исключение времени выполнения, если parent содержит объект другого типа, например, если вы написали Parent parent = new AnotherChild(); выше

Вы можете избежать исключения во время выполнения, используя is operator

if (parent is Child) 
{
    Child child = (Child)parent;
    child.y = 10;
}

Или лучше, используя as оператор

Child child = parent as Child;
if (child != null)
{
    child.y = 10;
}

Оператор as никогда не сгенерирует исключение. Вместо этого, если объект не может быть приведен, результат будет нулевым.

0 голосов
/ 30 августа 2018

Когда вы обращаетесь к своему экземпляру obj через родительский класс, , который не имеет никаких знаний о y, вы, безусловно, не сможете получить доступ к этому члену, так как он определен только в детский класс.

Другими словами: каждый Child является Parent и имеет y -свойство. Но не каждый Parent также является Child.

Таким образом, ваша ссылка obj должна иметь тип времени компиляции Child, а не Parent:

Child obj = new Child();
obj.y = 10;
0 голосов
/ 30 августа 2018

Это невозможно, потому что вы используете переменную типа Parent, а parent не предоставляет свойство y.

0 голосов
/ 30 августа 2018

Нет, вы не можете сделать. Это связано с тем, что любой экземпляр ClassB также является экземпляром ClassA, но, наоборот, неверен.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...