추상 클래스와 인터페이스의 사용법을 실제 예에서 이해하도록 도와주실 수 있나요?

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

  •  06-07-2019
  •  | 
  •  

문제

추상 클래스와 상속 사용에 대해 거의 지나치게 단순화된 이해를 제공하고 개념과 구현 방법을 진정으로 이해할 수 있도록 도와주실 수 있나요?완료하려는 프로젝트가 있는데 구현 방법을 모르겠습니다.저는 교수님과 이야기를 나눴는데, 제가 그것을 알아낼 수 없다면 아마도 그 과정을 수강할 준비가 안 된 것 같다는 말을 많이 들었습니다.사전 필수 과정을 다 읽었지만 여전히 이러한 개념을 이해하는 데 어려움이 있습니다.

명확히 하자면, 제가 지금까지 수행한 프로젝트는 아래와 같습니다.아직 개/고양이 수업 등을 작성하지 않았습니다.나에게 포인터를 줄 수 있습니까?나는 누군가에게 "답변"을 주라고 요구하지 않습니다. 나는 이것과 함께 어디로 가야할지 잃어 버렸다.나는 온라인 강좌를 듣고 있는데 그의 의사소통 노력은 문제가 되었습니다.방금 다른 모든 과정을 4.0으로 마쳤으므로 노력할 의향이 있지만 이러한 개념을 이해하고 이를 실제로 적용하는 방법에 대해 잘 모르겠습니다.

이 프로젝트를 더욱 발전시키는 데 도움이 되는 의견이나 도움이 있습니까?

제가 구현하려는 내용에 대한 설명은 다음과 같습니다.

개요:

이 연습의 목적은 인터페이스, 상속, 추상 클래스 및 다형성의 사용을 보여주는 것입니다.귀하의 임무는 제공된 프로그램 쉘을 취하고 적절한 클래스와 해당 클래스 멤버/방법을 추가 하여이 프로그램을 올바르게 작동하도록하는 것입니다.제공된 코드를 변경할 수 없으며 작성하는 클래스 만 추가 할 수 있습니다.프로그램을 작동시키는 방법에는 여러 가지가 있지만 인터페이스 사용을 보여주는 기술을 사용해야합니다.
상속, 추상 클래스 및 다형성.다시 말하지만, 제공된 코드에 추가 할 수는 있지만 변경하거나 삭제할 수는 없습니다.제공되는 코드는 추가 코드가 거의 없으며 운동의 요구 사항을 충족시킵니다.

과제를 성공적으로 완료하면 프로그램이 실행될 때 다음 문을 출력해야합니다.

내 이름은 스팟, 나는 개예요

내 이름은 펠릭스이고 고양이예요

요구사항:

1) 개와 고양이 수업이 파생되는 '동물'이라는 추상적 인 기본 클래스가 있어야합니다.

2) 동물 기본 클래스는 인터페이스 'Ianimal'에서 파생되어야하며, Ianimal에서 파생되어야하는 유일한 클래스입니다.

3) 모든 동물이 이름을 가지고 있고 이름은 개나 고양이에 특정한 속성이 아니기 때문에 동물

기본 클래스는 이름이 저장되는 위치와 Whatismymame get-property가 구현되는 위치이어야합니다.

4) 동물 기반 수업에서만 파생 될 개와 고양이 수업을 만들어야합니다.

5) 개와 고양이 수업은 Whatami Get-Property를 구현하고 적절한 문자열 값을 반환해야합니다.

변경할 수 없는 코드:

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

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

지금까지 작성한 코드는 다음과 같습니다.

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);
        }
    }
}
도움이 되었습니까?

해결책

편집하다:

나는 각 클래스에 대한 코드 본문을 가져 왔습니다. 내 대답을보고 싶다면 편집 개정을 살펴보십시오 :)

먼저 우리는 정의합니다 상호 작용

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

이 인터페이스를 구현하는 클래스는 이러한 속성을 구현해야합니다. 인터페이스는 계약과 같습니다. 인터페이스를 구현하는 클래스는 인터페이스의 메소드, 속성 이벤트 또는 인덱서를 구현하는 데 동의합니다.

다음으로, 우리는 당신의 추상 동물 계급을 정의해야합니다

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

수업이라는 사실 요약 클래스는 다른 클래스의 기본 클래스 일뿐임을 나타냅니다. 우리는 인터페이스의 두 속성을 모두 구현했으며 동물 이름을 저장할 개인 분야도 있습니다. 또한, 우리는 WhatAmI Property Accessor Abstract 각 파생 클래스에서 자체 특정 속성 액세서 로직을 구현하고 문자열 인수를 받아들이고 값을 다음에 할당하는 생성자를 정의했습니다. _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 방법.

나는 누군가가 선택한 단어가 강화 될 필요가 있다고 느끼면 이것을 명확하게 설명했으면 좋겠다.

다른 팁

인터페이스와 추상 클래스의 주요 차이점은 인터페이스 에서이 인터페이스를 구현하는 객체의 공개 메소드와 속성이 무엇인지 정의한다는 것입니다. 초록 클래스는 일부 기본 구현을 제공하지만 상속자가 구현 해야하는 일부 "갭" - 초록 방법이 있습니다.

나는 당신을 위해 당신의 숙제를하지 않을 것이지만, 힌트 : 동물 계급에는 개와 고양이에 특정한 것을 포함해서는 안됩니다.

당신은 가깝지만 필요한 것보다 더 힘들게 만듭니다.

나는 당신에게 답을주고 싶지 않습니다.) 그러나 여기에는 몇 가지 포인터가 있습니다.

먼저 3 개의 클래스와 1 개의 인터페이스를 만들고 있습니다. 그러나 내가 당신이 놓치고 있다고 생각하는 한 가지는 여기에 3 가지 다른 유형의 객체가 필요하다는 것입니다 ( "최소 정의"에서 "가장 정의 된"까지).

1) 인터페이스
이것은 Ianimal이며 동물처럼 행동 할 수있는 모든 것에 의해 구현 될 수 있습니다.

2) 초록 기본 클래스 이것은 동물의 송아지입니다. 동물이 동물에서 파생되어야하는 모든 것은 직접적으로 생성 할 수 없습니다. 당신이 당신이 신을 닮은 경우, 당신은 동물을 만들지 않고, 개, 고양이, 다람쥐 또는 fuzzybunny를 만듭니다.

3) 동물의 구체적인 구현 이들은 실제 클래스 자체입니다. 이것이 당신이 만든 것입니다. 귀하의 경우 개 또는 고양이.

여기서는 구체적인 클래스 만 만들 수 있지만 Ianimal 또는 동물 (인터페이스 또는 추상 기본 클래스)을 사용하여 모든 동물 (또는 인터페이스의 경우 동물처럼 작용하는 모든 것)과 조작하고 작업 할 수 있습니다.

일반적으로 말하면:

  • 인터페이스는 객체가 응답 할 방법을 설명합니다. 그것은 대상이 만족시키기 위해 노력하는 계약입니다.

  • 초록 클래스는 기본 기능을 설명하고 특수 기능을 서브 클래스로 보냅니다.

따라서 기본적으로 해당 객체가 자연에서 다른 경우 인터페이스를 사용하고 동일한 특정 방법에 응답하십시오.

그리고 당신은 어떤 클래스의 전문화 된 버전이 필요할 때 초록 클래스를 사용합니다.

모든 종류의 객체가 고유 한 ID로 식별 될 수 있고 그들이 속한 클래스를 신경 쓰지 않는 시스템을 만들고 싶다고 가정 해 봅시다.

당신은 가질 수 있습니다 :

  • 동물

  • 수송

  • 컴퓨터 가제트.

  • 무엇이든.

관련이없는 주제이므로 구현 및 인터페이스를 선택할 수 있습니다.

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과 고양이 모두 본성이 매우 다르지만 카탈로그 시스템에 사용될 "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 방법에 응답하기 위해 노력하고 있습니다. 그렇기 때문에 자체가 해당 인터페이스를 구현하지 않을 수도 있습니다.

물론, 식별이 자동차가 가질 수있는 공통 속성에 기초 할 수 있다면, getIndifiableID는 기본 클래스에 의해 구현 될 수 있고 서브 클래스는 해당 방법을 상속받을 것이다.

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

이게 도움이 되길 바란다.

  1. 인터페이스는 계약입니다. 이곳은 구현 세부 정보없이 제공 할 기능을 설명하고자하는 곳입니다.

  2. 초록 클래스는 하위 클래스간에 구현 세부 정보를 공유하는 목적의 클래스입니다. 코드 공유/인자화 목적으로 만 여기에 있으므로 인스턴스화 할 수 없습니다.

  3. 실제 클래스는 초록 클래스에서 상속되고 필요한 경우 추상 클래스에서 공유되는 코드를 사용하면서 클래스 별 기능을 구현합니다.

솔직히 말해서, 그것은 숙제 질문인지 아닌지에 관계없이 업계의 사람들의 양을 두려워합니다. 그러므로 나는 대답 할 것이다.

초록 구현을 인터페이스하고 추상 클래스도 마찬가지입니다. 인터페이스를 구현하는 추상 클래스를 만들 수 있기 때문에 "vs"는 없습니다. 그러니 그들이 서로 전쟁 중이라고 생각하지 마십시오.

따라서 소비자가 구현에 대해 너무 많이 알기를 원하지 않을 때는 사용할 수 있습니다. 구현이 없기 때문에 인터페이스는이 작업에서 약간 더 나은 일입니다. 소비자가 다시 얻는 값을 누르고 추상 클래스가 이것보다 조금 더 진술 할 수있는 곳 (또는 훨씬 더 많은 것)을 보낼 수있는 버튼을 나타냅니다. . 따라서이 지점을 탑승하면 인터페이스 만 필요합니다. Ergo, 포인트 2 :

인터페이스의 두 가지 구현간에 공통 코드를 공유하려는 경우 추상 클래스가 사용됩니다. 이 시나리오에서는 인터페이스를 구현하는 추상 클래스에서 상속되는 두 개의 구체적인 구현입니다.

간단한 예는 Idatastore입니다. SavingtoTextFile Datastore는 Idatastore를 구현하는 클래스 일뿐입니다. 그러나 MSSQLDATASTORE 및 MYSQLDATASTORE는 공통 코드를 공유합니다. 그들은 모두 Idatastore를 구현하는 추상 클래스 Sqldatastore에서 상속 될 것입니다.

초록 수업 : 파생 된 수업에 대한 기반을 설정합니다. 그들은 모든 파생 된 클래스에 계약을 제공합니다. 상속인을 시행합니다

인터페이스 :

인터페이스는 클래스가 아니라 메소드의 정의입니다.

클래스는 여러 인터페이스를 억제 할 수 있지만 하나의 추상 클래스만을 억제 할 수 있습니다.

도움이되기를 바랍니다

기본적으로 인터페이스는 모든 구현자가 제공 해야하는 '계약'(예 : 일련의 운영/속성)을 정의합니다. 이 경우 Ianimal 인터페이스에는 Whatami 및 Whatismymame 특성이 필요합니다. 초록 클래스는 특정 기능을 제공 할 수 있지만 서브 클래스로 구현 해야하는 일부 작업을 떠날 것입니다.

예를 들어, '이름'은 모든 동물의 속성이기 때문에 동물 기반 클래스는 Whatismymame 기능을 제공 할 수 있습니다. 그러나 특정 서브 클래스만이 '유형'인지 알고 있기 때문에 'Whatami'속성을 제공 할 수 없습니다.

게시 한 샘플 코드의 문제점은 Animal Class가 서브 클래스에 대한 지식을 가지고 있다는 것입니다.

또 다른 제안 - (주제에서 약간 벗어났지만 여전히 관련이 있음)

학습 목적으로 자동 속성을 사용하지 않는 것이 좋습니다.명시적으로 구현하면 무슨 일이 일어나는지 이해하는 데 도움이 됩니다.

예를 들어, 다음을 수행하는 대신:

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

직접 구현해 보세요.

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

이 특별한 경우에 도움이 될 것이기 때문에 이것을 언급합니다.자동 속성을 사용하고 있기 때문에 컴파일러는 "빈칸을 채워줍니다". 귀하의 경우 매우 유용한 컴파일러 오류가 발생하는 것을 방지하고 있다고 생각합니다.이러한 개념이 어떻게 작동하는지 이해하려고 할 때, 직접 작업을 수행하면 일반적으로 더 어려워지는 것이 아니라 더 쉬워집니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top