зачем создавать тип родительского класса для хранения объекта дочернего класса? - PullRequest
0 голосов
/ 01 октября 2018

Меня немного смущает полиморфизм, наследование в C #.Узнав о полиморфизме, я обнаружил что-то вроде этого ParentClass P = new ChildClass ();что немного сбивает с толку.Зачем кому-то создавать тип родительского класса для хранения объекта дочернего класса?Однако это действительно в c #. Я просто хочу понять 3 вещи: 1. Какова цель сделать это?2. Каковы преимущества этого?3. Когда мы должны создать такой объект?Ниже приведен мой код для справки:

using System;

class ParentClass
{
    public void Display()
    {
        Console.WriteLine("Display method in Parent class");
    }
}

class ChildClass : ParentClass
{
    public void Display()
    {
        Console.WriteLine("Display method in Child class");
    }
}

public class Program
{
    public static void Main()
    {
        ParentClass P = new ChildClass();
        P.Display();
    }
}

Вывод кода такой: Показать метод в родительском классе.

Теперь, если кто-то должен вызвать метод в родительском классе, почему бы просто не создать ParentClassP = новый ParentClass ();Или, если кто-то должен вызвать метод в классе Child, почему бы просто не создать ChildClass C = new ChildClass ();

Перебрал много форумов, так и не нашел ответа, который хочу.Пожалуйста, если кто-то может объяснить подробно с примером, будет большая помощь.Спасибо.

Ответы [ 4 ]

0 голосов
/ 01 октября 2018

1. Цель, а) вам придется вызывать конструктор дочернего класса, а затем членов родительского класса,

2.Преимущества, а) для вызова конструктора дочернего класса.

3. КогдаЧтобы использовать, а) Когда вам нужно сначала получить доступ к конструктору дочернего класса, а затем к членам родительского класса.

Код

class ParentClass
{
    public void Display()
    {
        Console.WriteLine("Display method in Parent class");//second get executed
    }
}

class ChildClass : ParentClass
{
    public ChildClass(string x)//first get executed
    {
        Console.WriteLine(x);
    }
    public void Display1()
    {
        Console.WriteLine("Display method in Child class");
    }
}

public class Program
{
    public static void Main()
    {
        ParentClass P = new ChildClass("First get Executed");
        P.Display();
        Console.ReadKey();
    }
}
0 голосов
/ 01 октября 2018

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

Cat c = new Cat();
Dog d = new Dog();

List<Animal> myPets = new List<Animal>();
myPets.Add(c);
myPets.Add(d); //no casting needed

Так что у базы Animal есть свойство, которое содержитage:

public int Age { get; set; }

Поскольку мы неявно сказали, что my Cat c и Dog d относятся к типу Animal, мы можем вызывать этот тип без выполнения приведения, что полезно.

Foreach(Animal a in myPets)
   Console.WriteLine(a.Age);

Это полезно для, возможно, коллекций элементов управления, где у нас есть asp:Panel в Asp.Net или Panel в winforms, которые содержат дочерние элементы (которые могут быть коллекцией label, textbox и т. д.) вместо того, чтобы содержать List каждого из этих элементов, мы можем преобразовать их в базу, которую они все разделяют, которая является классом Control, позволяющим нам иметь коллекцию дочерних элементов или узлов, хранящихся в виде коллекцииControls и когда мы хотим выполнить какую-либо операцию, мы можем уменьшить ее до более производного типа (используя as / is)

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

Это ковариация и контравариантность

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

Дополнительная литература

0 голосов
/ 01 октября 2018

Я могу привести простой пример, который открыл мне глаза, когда я был в вашем положении.Допустим, мы хотим вычислить Площадь некоторых 2D-фигур:

class Program
{
    static void Main(string[] args)
    {
        List<Shape> shapes = new List<Shape>()
        {
            new Rectangle(5, 5),
            new Circle(2)
        };

        foreach (Shape shape in shapes) //even though we just have a "Shape" here the respective methods of "Rectangle" and "Circle" are executed
        {
            Console.WriteLine(shape.CalculateArea());
        }

        Console.ReadKey(true);
    }
}

public abstract class Shape
{
    public abstract double CalculateArea();
}

public class Rectangle : Shape
{
    private double a;
    private double b;

    public Rectangle(double a, double b)
    {
        this.a = a;
        this.b = b;
    }

    public override double CalculateArea()
    {
        return a * b;
    }
}

public class Circle : Shape
{
    private double r;

    public Circle(double r)
    {
        this.r = r;
    }

    public override double CalculateArea()
    {
        return 2 * Math.PI * r;
    }
}

Как вы можете видеть, у нас есть родительский класс Shape и производные от него Rectangle и Circle.Потому что мы говорим C # с public abstract double ClaculateArea(), что все подклассы должны реализовывать такую ​​функцию.Этот расчет, скорее всего, будет разным для каждого подкласса, который мы создаем.Выигрыш в этом, как это, заключается в том, что мы можем сохранять все виды различных фигур, которые получаются из Shape внутри списка.Но если мы вызовем CalculateArea() из этих элементов, которые типы подклассов неизвестны в этот момент , то будут выполнены соответствующие функции вычисления.

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

0 голосов
/ 01 октября 2018

Вся идея полиморфизма заключается в возможности создания объектов из производного типа класса, но рассматривая их как тип базового класса.

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

Чтобы работать с этими объектами без проверки их типа, вы можете просто относиться к ним как к базовому классу животных, а не к их созданному типу.class.

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

Хотя все они были созданы для другого типа объектавсе они являются производными от класса Animal, поэтому они имеют некоторые методы и свойства.

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