2009-03-09 4 views
5

Можете ли вы дать мне почти чрезмерно упрощенное понимание абстрактного класса и использования наследования и помочь мне, чтобы я мог действительно понять концепцию и как ее реализовать? У меня есть проект, который я пытаюсь выполнить, и я потерял его, как реализовать. Я беседовал с моим профессором, и мне сказали, что если я не смогу это понять, я, вероятно, не готов к курсу. У меня НАПРАВЛЕНЫ предварительные курсы, и до сих пор сложно понять эти понятия.Можете ли вы помочь мне в практическом примере понять использование абстрактных классов и интерфейсов?

Чтобы уточнить, проект, как я сделал до сих пор, приведен ниже. У меня еще нет классов для собак/кошек и т. Д. Можете ли вы дать мне указатель. Я не прошу кого-нибудь дать мне «ответы». Я просто теряюсь на том, куда идти с этим. Я беру онлайн-курсы, и его усилия по связям со мной были тревожными. Я только что закончил с 4.0 со всеми моими другими курсами, поэтому я готов приложить усилия, но я потерял понимание этих концепций и как ПРАКТИЧЕСКИ применить их.

Любые комментарии или помощь, которые позволят мне продвинуться дальше в этом проекте?

Описание того, что я реализовать следующим образом:

Обзор:

Цель этого упражнения состоит в продемонстрировать использование интерфейсов, наследование, абстрактные классы, и Полиморфизм. Ваша задача - взять прилагаемую оболочку программы и добавить соответствующие классы и соответствующие классы/методы класса , чтобы эта программа функционировала правильно. Вы можете не вносить изменения в код , вы можете добавлять только классы , которые вы пишете. Хотя есть множество способов получить программу , вы должны использовать методы, которые демонстрируют использование интерфейсов,
Наследование, абстрактные классы и Полиморфизм. Опять же, чтобы сделать ясно, вы можете добавить к прилагаемому коду, но вы не можете изменить или удалить любой из . Код, который поставляется, будет работать с очень небольшим дополнительным кодом и будет удовлетворять требованиям упражнения.

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

Меня зовут Пятно, я собака

Меня зовут Феликс, я Cat

Требования:

1) Вы должны иметь абстрактный базовый класс под названием «Animal», из которого Пес и кот с лайсы.

2) базового класса Animal должны получить из интерфейса «IAnimal», это единственный класс, который должен вывести из IAnimal.

3) Поскольку все животные имеют имя и имя не является атрибутом, который является специфическими для собаки или кошки, животное

базовый класс должен быть где имя хранится и где WhatIsMyName реализована функция get-property.

4) Вам необходимо будет создать собаку и класс Cat, который будет получен только от базового класса животных.

5) Классы собак и кошек должны реализовать свойство getAmI, а - вернуть соответствующее строковое значение.

код вы не можете изменить:

using System; 

namespace IT274_U2 
{ 
    public interface IAnimal 
    { 
     string WhatAmI { get; } 
     string WhatIsMyName { get; } 
    } 

    public class TesterClass 
    { 
     public static void DescribeAnimal(IAnimal animal) 
     { 
      Console.WriteLine("My name is {0}, I am a {1}", animal.WhatIsMyName, animal.WhatAmI); 
     } 

     static void Main(string[] args) 
     { 
      Dog mydog = new Dog("Spot"); 
      Cat mycat = new Cat("Felix"); 
      DescribeAnimal(mydog); 
      DescribeAnimal(mycat); 
     } 
    } 
} 

///////////////////////

Code I» ве написано до сих пор:

using System; 


namespace IT274_U2 
{ 
    public interface IAnimal 
    { 
     string WhatAmI { get; } 
     string WhatIsMyName { get; } 
    } 


    public class Dog 
    { 
     public abstract string WhatAmI 
     { 
      get; 
      set; 
     } 
    }//end public class Dog 

    public class Cat 
    { 
    public abstract string WhatIsMyName 
    { 
     get; 
     set; 
    } 
    }//end public class Cat 

    public abstract class Animal : IAnimal 
    { 
    // fields 
    protected string Dog; 
    protected string Cat; 

        // implement WhatIsMyName 

    //properties 
    public abstract String Dog 
    { 
     get; 
     set; 
    } 
    public abstract String Cat 
    { 
     get; 
     set; 
    } 
    public abstract string WhatIsMyName(); 

    } //end public abstract class Animal 


    public class TesterClass 
    { 
     public static void DescribeAnimal(IAnimal animal) 
     { 
      Console.WriteLine("My name is {0}, I am a {1}", animal.WhatIsMyName, animal.WhatAmI); 
     } 

     static void Main(string[] args) 
     { 

      Dog mydog = new Dog("Spot"); 
      Cat mycat = new Cat("Felix"); 
      DescribeAnimal(mydog); 
      DescribeAnimal(mycat); 
     } 
    } 
} 
+0

Является ли образец кода в вашем сообщении кодом, который вам не разрешено изменять? –

+0

@Mike - только то, что я собирался спросить :) –

+0

обновил вопрос выше с кодом, данным профессором, и кодом, который я написал. Спасибо за это, я даже не подумал. Он сказал мне, что у меня общий план, но снова он очень быстро отталкивал меня от сеанса, так что только ненадолго взглянул на него. – SheldonH

ответ

6

EDIT:

Я взял тело кода для каждого класса из - Если вы хотите увидеть мой ответ, есть взгляд на редактирование пересмотров :)

Во-первых, определим interface

public interface IAnimal 
{ 
    string WhatAmI { get; } 
    string WhatIsMyName { get; } 
} 

Любой класс, реализующий этот интерфейс, должен реализовать эти свойства. Интерфейс подобен контракту; класс, реализующий интерфейс, соглашается предоставить реализацию методов интерфейса, событий свойств или индексаторов.

Далее нам нужно определить свой абстрактный класс Animal

public abstract class Animal : IAnimal 
{ 
    //Removed for Training, See Edit for the code 
} 

Тот факт, что класс abstract указывает на то, что класс предназначен только быть базовым классом для других классов. Мы реализовали оба свойства интерфейса, а также создали личное поле для хранения имени животного. Кроме того, мы сделали абстракцию доступа к объекту WhatAmI, чтобы мы могли реализовать свою собственную специфическую логику доступа к свойствам в каждом производном классе и также определили конструктор, который принимает строковый аргумент и присваивает значение частному полю _name.

Теперь давайте определим наши Cat и Dog классы

public class Dog : Animal 
{ 
    //Removed for Training, See Edit for the code 
} 

public class Cat : Animal 
{ 
    //Removed for Training, See Edit for the code 
} 

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

Для остальной части кода

public class Program 
{ 
    public static void DescribeAnimal(IAnimal animal) 
    { 
     Console.WriteLine("My name is {0}, I am a {1}", animal.WhatIsMyName, animal.WhatAmI); 
    } 

    static void Main(string[] args) 
    { 
     Dog mydog = new Dog("Spot"); 
     Cat mycat = new Cat("Felix"); 
     DescribeAnimal(mydog); 
     DescribeAnimal(mycat); 
     Console.ReadKey(); 
    } 
} 

статического метод DescribeAnimal принимает IAnimal в качестве аргумента и записывает значения, возвращаемых аксессоры собственности WhatIsMyName и WhatAmI для переданного в IAnimal.

С Animal реализует IAnimal и оба Dog и Cat наследоваться от Animal, любой Cat или Dog объект может быть передан в качестве параметра методу DescribeAnimal.

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

+0

Честно говоря, я избегал читать весь ваш комментарий полностью, так как мне не нравится «читать» ответ на мой проект, но fyi ссылка, которую вы дали MSDN, дала «образец» кода, который помог мне переместить мой проект спасибо за помощь! – SheldonH

+1

good stuff :) Дайте мне знать, если вы хотите, чтобы я удалил свой ответ или оставил его, чтобы вернуться, как только у вас есть ваше решение. –

+0

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

6

Основное различие между интерфейсом и абстрактным классом является то, что в интерфейсе вы только определить, какими должны быть общие методы и свойства объекта, который реализует этот интерфейс. Абстрактный класс предоставляет некоторую базовую реализацию, но имеет некоторые «пробелы» - абстрактные методы, которые необходимо реализовать наследнику.

Я не собираюсь делать домашнее задание для вас, а подсказка: класс животных НЕ должен содержать ничего конкретного для собак и кошек.

0

Аннотация Классы: Создание базы для производных классов, которые они предоставляют для всех производных классов. Он навязывает heirarchies

Интерфейсы:

интерфейс не является классом, его определение методов.

Класс может inheirt несколько интерфейсов, но только один абстрактный класс.

Я надеюсь, что помогает

+0

«Интерфейс - это не класс, его определение методов». .. я думал, что это тип класса? вы говорите, что это не так? Это очень помогает! – SheldonH

+0

«Интерфейс - это особый тип класса C#, который поддерживает полиморфный stustituion и latebinding без наследования». Современный дизайн программного обеспечения - RIchard Weiner Это, предположительно, противоречит утверждению, что интерфейс не является классом, никаким комментарием? – SheldonH

+0

@ Шелдон. Я согласен с моим замечанием, что интерфейс не является классом, это договор – CodeMonkey

3

Вы близки, но сделать это сложнее, чем это должно быть.

Я не хочу давать вам ответ;) но вот несколько указателей.

Во-первых, вы создаете 3 класса и 1 интерфейс. Тем не менее, одна вещь, которую я считаю, вам может отсутствовать, что вам нужно 3 различных типов объектов здесь (от «наименее определено» в «наиболее определенный»):

1) Интерфейс
Это IAnimal - и может быть реализуется любым чем-либо, что может действовать как животное

2) Абстрактный базовый класс Это животные - все, что животное должно происходить от Животного, но они не могут быть созданы напрямую.Если вы притворяетесь, что являетесь Богом, вы не делаете животного, вы делаете собаку, кошку, белку или FuzzyBunny

3) Бетонирование бетона животных Это сами классы. Это то, что вы создаете. Собака или Кот в вашем случае.

Фокус в том, что вы можете создавать только конкретные классы, но вы можете использовать IAnimal или Animal (интерфейсы или абстрактные базовые классы) для управления и работы с любым животным (или, в случае интерфейсов, чем-либо, что действует как животное)

+0

, спасибо за тщательный ответ. Мне нужны указатели, а не ответы. Я просто смущен, поэтому такая помощь значительно ускорит меня, вместо того, чтобы сдаться! Обед в ближайшее время, и я буду читать все ответы и работать над моим проектом, чтобы закончить сегодня. ДЕЙСТВИТЕЛЬНО оцените помощь – SheldonH

+0

Перечитайте, что я опубликовал, и взгляните на свои классы для собак и кошек. Любое использование «абстрактных» в одном свойстве делает класс абстрактным классом, поэтому вы вынуждаете собак и кошек быть моей категорией 2. Взгляните на ключевое слово «переопределить» на C# - это может помочь вам немного дальше. –

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

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

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

0

В принципе, интерфейс определяет «контракт» (т. Е. Набор операций/свойств), который должны предоставить все разработчики. В этом случае интерфейс IAnimal требует свойств WhatAmI и WhatIsMyName. Абстрактные классы могут обеспечить определенную функциональность, но также оставят некоторые операции, которые должны быть реализованы по их подклассам.

В случае вашего примера базовый класс Animal может предоставить функцию WhatIsMyName, так как «Имя» является свойством всех животных. Однако он не может предоставить свойство «WhatAmI», поскольку только определенные подклассы знают, что такое «тип».

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

+0

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

+0

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

0

Еще одно предложение - (немного не по теме, но до сих пор связаны)

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

Например, вместо того, чтобы делать:

class SomeClass 
{ 
    public string MyProperty 
    { 
     get; 
     set; 
    } 
} 

Try реализации этого себя:

class SomeClass 
{ 
    public string MyProperty 
    { 
     get 
     { 
      return "MyValue"; // Probably a private field 
     } 
     set 
     { 
      // myField = value; or something like that 
     } 
} 

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

1

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

Интерфейсы абстрактной реализации, а также абстрактные классы. Нет «vs», потому что вы можете создать абстрактный класс, который также реализует интерфейс. Поэтому не думайте, что они воюют друг с другом.

Таким образом, ЭТО можно использовать, когда вы не хотите, чтобы потребитель слишком много знал о реализации.Интерфейс немного лучше в этом задании, потому что он не имеет реализации, он просто указывает, какие кнопки потребитель может нажать на значения, которые они возвращают, и отправить туда, где абстрактный класс может указать немного больше этого (или даже намного больше!). , Поэтому, если вы просто берете эту точку на борту, вам действительно нужны интерфейсы. Ergo, пункт 2:

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

Простым примером является IDataStore. SavingToATextFile datastore - это просто класс, который реализует IDataStore. Однако MsSqlDataStore и MySqlDataStore будут совместно использовать общий код. Они оба наследуют от абстрактного класса SqlDataStore, который реализует IDataStore.

2

Вообще говоря:

  • An интерфейсы описывают методы объекта будет реагировать. Это контракт, который объект обязуется удовлетворить.

  • Абстрактные классы описывают основные функции и позволяют специализированные функциональные возможности подкласса.

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

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

Предположим, вы хотите создать систему, в которой любой тип объекта может быть идентифицирован уникальным идентификатором, и вам не нужен класс, к которому они принадлежат.

Вы можете иметь:

  • Животные

  • Транспорт

  • Компьютерные гаджеты.

  • Неважно.

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

public interface IIdentifiable 
{ 

     public long GetUniqueId(); 
} 

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

public class IPod: IIdentifiable 
{ 
     public long GetUniqueId() 
     { 
      return this.serialNum + this.otherId; 
     } 
} 

public class Cat: IIdentifiable 
{ 
     public long GetUniqueId() 
     { 
      return this..... 
     } 
} 

Оба, и IPod и Cat, имеют очень разные характеры, но оба они могут отвечать на «GetUniqueId()» метод, который будет использоваться в системе каталога.

Тогда он может быть использован, как это:

... 

    IIdentifiable ipod = new IPod(); 
    IIdentifiable gardfield = new Cat(); 

    store(ipod); 
    store(gardfield); 


    .... 
    public void store(IIdentifiable object) 
    { 

     long uniqueId = object.GetUniqueId(); 
     // save it to db or whatever. 
    } 

С другой стороны, вы можете иметь абстрактный класс, определяющий все общее поведение объекта может иметь, и пусть подкласс определяют специализированные версии.

public abstract class Car 
    { 
     // Common attributes between different cars 
     private Tires[] tires; // 4 tires for most of them 
     private Wheel wheel; // 1 wheel for most of them. 

     // this may be different depending on the car implementation. 
     public abstract void move(); 
    } 


    class ElectricCar: Car 
    { 
     public void move() 
     { 
     startElectricEngine(); 
     connectBattery(); 
     deploySolarShields(); 
     trasnformEnertyToMovemetInWheels(); 
     } 
    } 

    class SteamCar: Car 
    {  
     public void move() 
     { 
      fillWithWather(); 
      boilWater(); 
      waitForCorrectTemperature(); 
      keepWaiting(); 
      releasePreasure.... 
     } 
    } 

Здесь два вида машин, реализует «перемещение» метод по-разному, тем не менее они имеют общие вещи в базовом классе.

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

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

// Случай 1 ... каждый подкласс реализует интерфейс

public class ElectricCar: Car, IIdentifiable 
    { 
     public void move() 
     { 
     ..... 
     } 
     public long GetUniqueId() 
     { 
     .... 
     } 
    } 

    public class SteamCar: Car, IIdentifiable 
    { 
     public void move() 
     { 
     ..... 
     } 
     public long GetUniqueId() 
     { 
     .... 
     } 
    } 

случае 2, базовый класс реализует интерфейс и подкласс выгоды от него.

public abstract class Car: IIdentifiable 
    { 
     // common attributes here 
     ... 
     ... 
     ... 



     public abstract void move(); 
     public long GetUniqueId() 
     { 
      // compute the tires, wheel, and any other attribute 
      // and generate an unique id here. 
     } 
    } 

    public class ElectricCar: Car 
    { 
     public void move() 
     { 
     ..... 
     } 
    } 

    public class SteamCar: Car 
    { 
     public void move() 
     { 
     ..... 
     } 
    } 

Надеюсь, это поможет.