você pode me ajudar a entender em um exemplo prático o uso classes abstratas contra as interfaces?

StackOverflow https://stackoverflow.com/questions/627199

  •  06-07-2019
  •  | 
  •  

Pergunta

Você pode me dar uma compreensão quase demasiado simplista da classe abstrata vs utilização herança e ajuda-me para que eu possa realmente entender o conceito e como implementar? Eu tenho um projeto que estou tentando completa, e estou perdido sobre como implementar. Estive conversando com meu professor e foi dito off praticamente, dizendo que se eu não posso descobrir isso, eu provavelmente não estou pronto para o curso. Tenho OVERCOVERED os cursos prerequestite, e ainda tem dificuldade para entender esses conceitos.

Para esclarecer, o projeto como eu tenho feito até agora é abaixo. Eu não tenho as classes cão / gato etc preenchido ainda. Você pode me dar um ponteiro. Eu não estou pedindo para ninguém para me dar as "respostas". Eu só estou perdido sobre onde ir com isso. I fazer cursos on-line e seus esforços de comunicação com me foram incomodando. Acabei de terminar com 4.0 com todos os meus outros cursos, por isso estou disposto a colocar o esforço, mas eu estou perdido na compreensão destes conceitos e como PRATICAMENTE aplicá-las.

Quaisquer comentários ou ajuda que vai me deixar progredir neste projeto?

A descrição do que estou a implementar é a seguinte:

Visão geral:

O objetivo deste exercício é demonstrar a utilização de interfaces, Herança, classes abstratas, e Polimorfismo. Sua tarefa é tomar a casca e programa fornecido SOME o classes apropriadas e correspondendo membros da classe / métodos para obter este programa para funcionar corretamente. Você pode não fazer alterações em qualquer do código fornecido, você só pode adicionar as classes você escreve. Apesar de haver inúmeras maneiras de obter o programa de trabalho, é necessário utilizar técnicas que demonstrar o uso de Interfaces,
Herança, classes abstratas, e Polimorfismo. Mais uma vez, para deixar claro, você pode adicionar o código fornecido, mas você não pode alterar ou excluir qualquer isto. O código que é a vontade fornecido trabalho com muito pouco código adicional e a satisfazer os requisitos de o exercício.

Se você concluir com êxito o atribuição, seu programa deve saída as seguintes declarações quando executado:

Meu nome é ponto, eu sou um cão

Meu nome é Felix, eu sou um gato

Requisitos:

1) Você deve ter uma base abstrata classe chamada 'Animal' a partir do qual o aulas de cão e gato derivar.

2) A classe base animal deve derivar a partir da interface 'IAnimal', é a única classe que deve derivar IAnimal.

3) Uma vez que todos os animais têm um nome e um nome não é um atributo que é específico para um cão ou um gato, o animal

classe base deve ser onde o nome é armazenado e onde o WhatIsMyName get-propriedade é implementada.

4) Você vai precisar para criar um cão e uma classe Cat que irá derivar apenas de a classe de base animal.

5) As classes de cão e gato deve implementar o WhatAmI get-propriedade e devolver o valor da seqüência apropriada.

código que você não pode mudar:

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);
        }
    }
}

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

código que eu escrevi até agora:

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);
        }
    }
}
Foi útil?

Solução

EDIT:

Tomei o corpo do código para cada classe para fora - Se você quiser ver a minha resposta, ter um olhar para as revisões de edição:)

Primeiro definimos a interface de

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

Qualquer classe que implementa essa interface deve implementar essas propriedades. Uma interface é como um contrato; uma classe que implementa uma interface concorda em fornecer uma implementação de métodos, propriedades eventos ou indexadores da interface.

Em seguida, precisamos definir o seu resumo classe Animal

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

O fato de que a classe é abstrato indica que a classe destina-se apenas a ser uma classe base para outras classes. Temos implementado ambas as propriedades da interface e também tem um campo privado para armazenar o nome animal. Além disso, temos feito a propriedade WhatAmI acessor tão abstrato que podemos implementar nossa própria lógica propriedade específica acessor em cada classe derivada e também definido um construtor que aceita um argumento de cadeia e atribui o valor para o campo privado _name.

Agora, vamos definir nossas aulas Cat e 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
}

As duas classes herdam Animal e cada um tem um construtor que define um argumento de cadeia e passa esse argumento como um parâmetro para o construtor base. Além disso, cada classe implementa o seu próprio assessor propriedade para WhatAmI, retornando uma seqüência de seu tipo, respectivamente.

Para o resto do código

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();
    }
}

o método DescribeAnimal estática aceita um IAnimal como um argumento e grava os valores devolvidos pelas WhatIsMyName e propriedade WhatAmI acessores para o passado em IAnimal.

Desde implementos Animal IAnimal e ambos Dog e Cat Herdar do Animal, qualquer objeto Cat ou Dog pode ser passado como um parâmetro para o método DescribeAnimal.

Espero que expliquei isso claramente, Se alguém se sente a minha escolha de palavras necessidades reforço, por favor comentário e eu vou ser feliz para editar a minha resposta.

Outras dicas

A principal diferença entre uma interface e uma classe abstrata é que na interface só definir o que devem ser os métodos públicos e propriedades do objeto que implementa essa interface. Uma classe abstrata fornece alguns implementação base, mas tem algumas "lacunas" -. Métodos abstratos que as necessidades herdeiro para implementar

Eu não vou fazer sua lição de casa para você, mas uma dica:. A classe animal não deve conter específica nada para cães e gatos

Você está perto, mas fazer isso mais difícil do que precisa ser.

Eu não quero dar-lhe a resposta;) mas aqui ficam algumas sugestões

.

Em primeiro lugar, você está criando 3 classes e 1 interface. No entanto, a única coisa que eu acredito que você pode estar faltando é que você precisa de 3 tipos diferentes de objetos aqui (de "menos definido" para "mais definido"):

1) Interface de
Esta é IAnimal - e pode ser implementado por qualquer coisa que possa agir como um animal

2) Resumo Base de Classe Este é o animal calss - Tudo o que é um animal deve derivar de animal, mas estes não são creatable diretamente. Se você fingir que você é Deus, você não faz um animal, você faz um cão, gato, esquilo, ou FuzzyBunny

3) implementação concreta do animal Estas são as próprias classes reais. Isto é o que você cria. Cão ou gato no seu caso.

O truque aqui é que você só pode criar classes concretas, mas você pode usar IAnimal ou animal (interfaces ou classes base abstratas) para manipular e trabalhar com qualquer animal (ou, no caso de interfaces, qualquer coisa que age como um animal)

De um modo geral:

  • Um interfaces de descrever os métodos de um objeto vai responder. É um contrato o objeto se compromete a satisfazer.

  • As classes abstratas descreve a funcionalidade básica e deixar especializada funcionalidade para uma subclasse.

Então, basicamente você usa uma interface quando você quer que os objetos de natureza diferente, respondem ao mesmo método específico.

E você usar uma classe abstrata quando você precisa se especializaram versões de alguma classe.

Vamos dizer que você quer criar um sistema onde qualquer tipo de objeto pode ser identificado por um ID único, e você não se importa a classe a que pertencem.

Você pode ter:

  • Animais

  • Transporte

  • Gadgets Computador.

  • Seja qual for.

Uma vez que são temas não relacionados, você pode optar por implementar e interface, vamos dizer:

public interface IIdentifiable 
{ 

      public long GetUniqueId();
}

E todas as classes que querem satisfazer este contrato irá implementar essa interface.

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

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

Ambos, e IPod e um gato, têm naturezas muito diferentes, mas ambos podem responder ao método "GetUniqueId ()", que será usado no sistema de catálogo.

Em seguida, ele pode ser usado como este:

    ...

    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.
    }

Por outro lado, você pode ter uma classe abstrata que define todo o comportamento comum o objeto possa ter, e deixar que os subclasse definir versões especializadas.

  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....
        }
   }

Aqui, dois tipos de carros, implementa o método "movimento" de maneiras diferentes, ainda que eles compartilham coisas comuns na classe base.

Para tornar as coisas mais interessantes, estes dois carros podem implementar também de interface de IIdentifiable, mas ao fazê-lo, eles estão apenas cometendo para responder ao método GetUniqueId, e não pela natureza do ser carros. É por isso que o carro auto pode não implementar essa interface.

Claro que, se a identificação pode basear-se no comum atribui os carros podem ter, a GetIdentifiableId pode ser implementado pela classe base e as subclasses vai herdar esse método.

// case 1 ... cada subclasse implementa a interface

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

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

Caso 2, os implementos classe base a interface eo benefício subclasse dela.

   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()
       {
         .....
       }
  }

Espero que isso ajude.

  1. Uma interface é um contrato. Este é o lugar onde você quer para descrever as funcionalidades que você vai fornecer, sem quaisquer detalhes de implementação

  2. Uma classe abstrata é uma classe cujo propósito é detalhes de implementação de acções entre suas sub-classes. Uma vez que é aqui apenas para fins de partilha / fatoração de código, não pode ser instanciado

  3. sua classe real irá herdar de sua classe abstrata, e implementar as suas funcionalidades específicas de classe ao usar o código compartilhado na classe abstrata, se necessário.

Para ser honesto, me assusta a quantidade de pessoas na indústria que não sabem isso, independentemente de se tratar de uma pergunta lição de casa ou não. Por isso eu vou responder.

Interfaces implementação abstrata e assim fazer classes abstratas. Não existe "vs" porque você pode criar uma classe abstrata que implementa uma interface também. Portanto, não acho que eles estão em guerra uns com os outros.

Portanto, qualquer um pode ser usado quando você não quer que o consumidor saber muito sobre a implementação. Uma interface é um pouco melhor neste trabalho, porque não tem nenhuma implementação, ele apenas afirma que botões o consumidor pode pressionar os valores que recebem de volta e enviar onde uma classe abstrata pode indicar um pouco mais do que isso (ou mesmo muito mais!) . Então, se você tomar apenas este ponto a bordo você só precisa realmente interfaces. Ergo, ponto dois:

Como classe abstrata é usado quando você quer compartilhar código comum entre duas implementações diferentes de um interface. Neste cenário duas implementações concretas tanto herdar da classe abstrata que implementa a interface.

Um exemplo simples é IDataStore. SavingToATextFile armazenamento de dados é apenas uma classe que implementa IDataStore. No entanto MsSqlDataStore e MySqlDataStore irá compartilhar código comum. Ambos irão herdar do SqlDataStore classe abstrata que implementa IDataStore.

Classes Resumo: Estabelecer uma base para classes derivadas que eles fornecem um contrato para todas as classes derivadas. Obriga heirarchies

Interfaces:

Uma interface não é uma classe, sua definição de métodos.

A classe pode inheirt múltiplas interfaces mas apenas uma classe abstrata.

Espero que ajude

Basicamente, uma interface define um 'contrato' (isto é, um conjunto de operações / propriedades) que todos os implementadores deve proporcionar. Neste caso, a interface IAnimal requer as propriedades WhatAmI e WhatIsMyName. As classes abstratas podem fornecer certas funcionalidades, mas também vai deixar algumas operações que devem ser implementadas por suas subclasses.

No caso do seu exemplo, a classe base animal é capaz de fornecer a funcionalidade WhatIsMyName desde 'Nome' é uma propriedade de todos os animais. No entanto, ele não pode fornecer a propriedade 'WhatAmI', uma vez que apenas subclasses específicas sabe o que 'tipo' eles são.

O problema com o código de exemplo que você postou, é que thet classe Animal tem conhecimento dele de subclasses, que ele não deve ter

Outra sugestão - (ligeiramente fora de tópico, mas ainda relacionado)

Eu recomendo, para fins de aprendizagem, para evitar propriedades automáticas. Ele vai ajudar você a entender o que está acontecendo se você implementá-los explicitamente.

Por exemplo, em vez de fazer:

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

Tente implementar este se:

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

Digo isto porque ele vai te ajudar neste caso específico. Desde que você está usando propriedades automáticas, o compilador é "enchimento os espaços em branco" para você, e no seu caso, eu acho que está impedindo você de obter alguns erros do compilador muito úteis. Ao tentar entender como esses conceitos trabalhar, fazer o trabalho sozinho geralmente torna mais fácil, não mais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top