Базовая ссылка на объект и использовать вопрос с помощью C # - PullRequest
2 голосов
/ 24 декабря 2010

Я новый в области объектной ориентации и программирования.Есть некоторые вещи, которые я до сих пор пытаюсь понять.

Например, у меня есть следующий код:

 public abstract class ParentA
    {
        public virtual void MethodA()
        {
            Console.WriteLine("Doing somethin...");
        }
    }
    public class DerivedClassA : ParentA
    {
        public override void MethodA()
        {
            Console.WriteLine("Doing something from derived...");
        }
    }

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

ParentA p = new DerivedClassA();
            p.MethodA();

Почему бы просто не указать класс, который вы хотите использовать, и использовать его члены?

 DerivedClassA d = new DerivedClassA();
            d.MethodA();

Я вижу, что здесь также используется много интерфейсов, где написано так:

public interface Animal
    {
        void Bark();
    }
    public class Dog : Animal
    {
        public void Bark()
        {
            Console.WriteLine("bark");
        }
    }

и затем используется следующим образом:

Animal a = new Dog();
            a.Bark();

Почему бы просто не сделать это ??:

Dog d = new Dog();
            d.Bark();

Когда это имеет значение?

Спасибо за помощь

:)

Ответы [ 5 ]

12 голосов
/ 24 декабря 2010

Ты прав;это выглядит странно, не правда ли?

Код:

Animal animal = new Dog();

достаточно редко;обычно, если бы вы знали, что создаете Dog, вы вводите переменную как Dog.Что более распространено:

Animal animal = petStore.ObtainInexpensivePet();

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

5 голосов
/ 24 декабря 2010

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

Если этот конкретный производный класс имеет дополнительные методы (например, List<T>), и вы хотите убедиться, чтоваш код будет работать с другими реализациями, у которых нет этих дополнительных методов, объявление переменной в качестве базового типа гарантирует, что вы не вызовете методы.

1 голос
/ 24 декабря 2010

Цель вызова a.Bark против d.Bark заключается в том, что вам не нужно знать фактический тип объекта.Обычно это можно увидеть, когда вы работаете со списком животных или пишете метод, который принимает животное в качестве параметра или возвращает его, но вы не хотите делать метод специфичным для объектов типа Dog.

Найдите информацию о полиморфизме, которая поможет вам лучше понять.

0 голосов
/ 24 декабря 2010

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

Идея состоит в том, что если вы правильно спроектируете иерархию классов, вы можете использовать свои классы более безопасным образом во всем коде (благодаря тому, чтоC # строго типизирован).И, конечно, повторно используйте код, который можно использовать для целого семейства объектов, а не переписывайте его для каждого класса.

Давайте проанализируем силу приведенного вами примера.

Поскольку у вас есть известный интерфейс Animal, вам не нужно знать все типы животных, существующие в программе (классы, реализующие интерфейс).

Это позволяет вамкод, подобный следующему:

public interface Animal
    {
        void Play();
        void WagTale();
        void Eat(Food food);
    }
}


void PlayWithAnimal(Animal animal) {
   animal.WagTale();
   this.ThrowBall();
   animal.Play();
   animal.WaTale();
}

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

Таким образом, вы можете вызвать метод следующим образом:

Dog dog = new Dog();
Lion lion = new Lion();
Flee flee = new Flee();
PlayWithAnimal(dog);
PlayWithAnimal(lion);
PlayWithAnimal(flee);

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

Более ориентированный на C # пример:Image - абстрактный класс, вы даже не можете создать экземпляр такого объекта.Но есть много других классов, которые являются производными от Image, поэтому, хотя ни один объект не может быть реальным Image, вы в основном увидите Image в коде, который использует Images.(Опять же, в основном изображение на самом деле Bitmap или какой-то другой класс)

0 голосов
/ 24 декабря 2010

Эта концепция называется 'Программирование для интерфейса, а не для реализации ', здесь интерфейс не означает фактический интерфейс C #, это может быть базовый класс, абстрактный класс, и это очень популярная концепция в ООМир, который является основой для других понятий, таких как «Инъекция зависимостей», «МОК (инверсия контроля)»

Как Эрик уже сказал, что

, если вы заранее знаете, что на самом деле собираетесьСоздание объекта Dog по сравнению с использованием основанной на интерфейсе техники оказывает меньшее влияние, НО его действительная сила проявляется, когда вы используете метод Factory, который возвращает Animal, и вы фактически до Runtime не знаете конкретный тип.

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