상속의 유용성을 어떻게 설명 할 수 있습니까? [닫은]


16

OOP의 상속 개념을 설명하려고 할 때 일반적인 예는 종종 포유류 예입니다. IMHO, 이것은 초보자 가이 개념을 잘못된 방식으로 사용하게하기 때문에 실제로 나쁜 예입니다. 또한 일상적인 디자인 작업에서 직면하게되는 것은 일반적인 디자인이 아닙니다.

그렇다면 상속을 사용하여 해결되는 훌륭하고 간단하며 구체적인 문제는 무엇입니까?


1
"일반적인 예는 종종 포유류"입니까? 무슨 소리 야? 이에 대한 링크, 참조 또는 인용을 제공 할 수 있습니까?
S.Lott


3
상속 = 빌 게이츠의 어린이 신탁 기금의 유용성을 설명하는 가장 좋은 예는 무엇입니까?
Martin Beckett

1
@ 크리스 :이 질문은 어떻게 건설적이지 않습니까? 하나의 질문자와 14 명의 응답자가 모두의 시간을 낭비하고 있다고 선언하고 있습니까?
Dan Dascalescu

@DanDascalescu-2 년 전 "건설적이지 않은 것으로 폐쇄를 고려하십시오 : 답변에 대한 답변으로 판단하면 일반적인 목록 / 여론 조사 질문처럼 보입니다"라는 플래그에 대한 응답으로 폐쇄되었습니다. 이것이 잘못되었다고 생각되면 수정하지 않았 음을 분명히하고 커뮤니티가 다시 열기 검토 대기열을 통해 결정하도록하십시오.
ChrisF

답변:


15

포유류와 같은 순수하게 학문적 인 예에는 아무런 문제가 없습니다. 사각형 / 사각형 예제도 좋아합니다. 왜냐하면 실제 분류법이 항상 원하는 상속 관계로 직접 변환되지 않는지를 지적하기 때문입니다.

내 의견으로는, 가장 일상적인 예는 GUI 툴킷입니다. 모든 사람이 사용한 것이지만 초보자가 후드에서 어떻게 작동하는지 추론하지 않았을 수도 있습니다. 주어진 구현에 대한 자세한 지식 없이도 모든 컨테이너, 모든 위젯, 이벤트 등에 공통적 인 동작에 대해 이야기 할 수 있습니다.


5
GUI 툴킷의 경우 +1 ... 그리고 최소한의 draw ()를 가진 하나의 Shape와 사용자 정의 draw ()를 가진 자손 모양을 가진 shape 예제도 좋아합니다.
yati sagade

14

실제 사례는 간단한 HR 응용 프로그램의 도메인 모델입니다. 물론 Employee 라는 기본 클래스를 만들 수 있다고 말하지만 물론 관리자도 직원입니다.

public class Employee
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Code { get; set; }

    public string GetInsuranceHistory()
    {
        // Retrieving insurance history based on employee code.
    }
}

그런 다음 개발자직원 , 테스터직원 , 프로젝트 관리자직원이라고 설명 합니다. 따라서 직원 클래스에서 모두 상속받을 수 있습니다 .


2
상속 이점을 보여주기 위해 개발자와 직원의 차이점을 보여주는 것도 흥미로울 수 있습니다. 차이가 없다면 Developer 클래스를 전혀 만들 필요가 없습니다.
David

3
같은 생각 보인다 Employee이 될 수 abstract도 클래스입니다.
StuperUser

+1 이것은 대부분의 선생님이 사용한 예제이며 정말 마음에 들었습니다. 그것은 완전하게 이해되었고 상속을 사용하는 방법에 대한 실제적인 예를 주었다.
David Peterman

18
항상 a Developer와 a 둘 다 여야하는 사람이 최소한 한 명 있기 때문에 실제로는 작동하지 않습니다 Tester. 또 다른 유사한 상황이 당신이 가지고있는 연락처 데이터베이스입니다 CustomerSupplier하지만 당신을 말할 것이다 이러한 시스템을 만든 사람 같이이 경우 항상 거기 Company둘 다가. 그렇기 때문에 이러한 예의 대부분이 잘못된 방향으로 안내합니다.
Scott Whitlock

11

다양한 것을 캡슐화합니다 ... 템플릿 메소드 패턴 을 보여줍니다. 기본 클래스에 공통적 인 동작을 넣고 서브 클래스에서 다양한 동작을 캡슐화하여 상속의 유용성을 보여줍니다.

UI controls그리고 Streams또한 상속의 유용성에 대한 아주 좋은 예이다.


나는 공장이 더 좋은 예라고 생각합니다.
Let_Me_Be

1
@Let_Me_Be : 팩토리와 상속의 관계는 본질적으로 너무 간접적이라고 생각합니다. 물론 구체적인 유형을 생성하고 추상 / 기본 유형을 반환하지만 인터페이스 유형 만 반환 할 수도 있습니다! 그것은 전형적인 동물의 예보다 낫지 않은 Imho.
팔콘

@Let_Me_Be : 또한 추상 팩토리는 서로 다른 상속 계층 구조 (항목 하나, 팩토리 하나)를 포함하는 매우 복잡한 예입니다. 상속을 잘 사용하지만 좋은 예는 아니라고 생각합니다.
팔콘

3

생각해 내다

객체의 모든 인스턴스는 상속의 유용성에 대한 구체적인 예입니다!

특별히 계급 상속 을 의미한다면 , 지금 당신은 분류법의 세계에 있으며, 그것들을 사용하는 시스템의 목표에 따라 크게 달라질 것입니다. 동물 / 포유류 예제는 생물학에서 일반적이고 잘 알려진 친숙한 분류법을 사용하지만, 언급 한 것처럼 대다수의 프로그래밍 문제에는 거의 쓸모가 없습니다.

따라서 프로그램 개념이라는 보편적 인 것을 시도하십시오. 모든 프로그램이 시작, 실행 및 종료됩니다. 모든 프로그램에는 이름과 선택적 명령 줄 매개 변수가 있습니다. 따라서 기본 Program 클래스는 실행을 시작하고 명령 줄 인수를 가져와 처리하고 기본 논리를 실행하며 정상적으로 종료하는 데 매우 유용합니다.

그렇기 때문에 많은 객체 지향 프로그래밍 언어가 Program 클래스 또는 Program 클래스와 똑같이 동작하는 것을 제공하는 이유입니다.


그래서 당신은 많은 프로그램을 가진 프로그램을 프로그램합니까? :) 내 경험에 따르면 Programm Objects는 거의 항상 상속이없는 싱글 톤이므로 가장 좋은 예는 아닙니다.
keppla

@keppla : Java 또는 .NET을 사용해 본 적이 있습니까? .NET에는 명시 적 Program 클래스가 있으며 Java는 암시 적입니다. 그들은 싱글 톤이 아닙니다
Steven A. Lowe

1.4.2 버전의 Java를 사용했습니다. 당시에는 정적 무효 메인 만 있었으므로 조금 변경 된 것 같습니다. Programm 클래스의 인스턴스가 둘 이상있는 일반적인 이유는 무엇입니까?
keppla

@keppla : java의 static void main은 암시 적으로 항목 클래스가 프로그램을 나타내도록합니다. 프로그램을 실행하는 모든 사용자는 새로운 인스턴스를 만듭니다. 현재 Chrome 인스턴스 3 개, Word 문서 4 개, 메모장 3 개, Windows 탐색기 2 개가 실행 중입니다. 그들이 모두 싱글 톤이라면 결코 그렇게 할 수 없었습니다.
Steven A. Lowe

1
나는 당신이 정의를 약간 스트레칭 생각합니다. class Programm { public static void main(String[] args) { system.out.println('hello world'); }}최소한의 Java 프로그램입니다. 전화하면 Program 인스턴스가 없습니다. 프로그램은 아무것도 상속받지 않습니다. 3 개의 프로세스를 시작하면 (crhome을 사용하는 것처럼) 3 개의 프로그램이있을 수 있지만 개별 메모리 영역에는 여전히 하나의 프로그램 만 있습니다. Imho, singleton은 머신이 아닌 '프로세스 당 하나의 인스턴스 만'을 의미합니다. 그렇다면 싱글 톤을 만들 수 없으며 코드를 두 번 실행하는 것을 막을 수있는 것은 없습니다.
keppla

3

직장에서 카메라로 작업하고 있습니다. 서로 다른 모델에 연결되는 장치가 있으므로 추상 "카메라 클래스"가 있으며 모든 모델은이 클래스에서 상속되어 해당 카메라의 특정 기능을 지원합니다. 실제 사례이며 이해하기 어렵지 않습니다.


2
당신이 가지고있는 경우에 예를 들면 모두의 모델, 분해 수 CameraPhone(우리 모두가 지금 우리 주머니에서처럼). 어떤 기본 클래스를 상속해야합니까? 아니면 그냥 인터페이스 ICameraIPhone인터페이스를 모두 구현해서는 안 됩니까? (ha ha)
Scott Whitlock

2
@Scott : iPhone 인터페이스를 구현할 수 없거나 Apple에 의해 고소 당할 것입니다.
메이슨 휠러

3

화학 원소 예

이것은 내 두뇌에서 튀어 나온 또 다른 예입니다.

Element_ 클래스
{
    이중 원자량; // 원자의 원자량
    이중 원자 번호; // 원소의 원자 수
    문자열 속성; // 요소의 속성
    // 다른 경우
}


동위 원소는 Element_를 확장한다 // 원소의 동위 원소가 존재할 수있다
{
    이중 반감기;
   // 다른 경우

}

2
비록 atomicNumber가 (정수?) 정수일 수 있지만 ...
Andrew

나는 상속을 사용하지 않을 것입니다. isotope의 특별한 경우가 아닙니다 Elemenet. 차라리에 Element속성이 있습니다 Isotope.
코드 InChaos

2

이 항상 모두를있는 뭔가의 가능성 어디 그들은 예를 제공하기 때문에 실제 사례는 거의 항상 잘못을 얻을 TypeA하고 TypeB있지만, 많은 언어의 단일 상속 계층 구조가 허용되지 않습니다.

프로그래밍을 많이할수록 상속에서 멀어집니다.

"상속"이라는 단어조차도 여기에 잘못 사용되었습니다. 예를 들어, 아버지 특성의 약 50 %와 어머니 특성의 50 %를 물려받습니다. 실제로 당신의 DNA는 당신의 아버지의 DNA의 절반과 어머니의 DNA의 절반의 구성입니다. 생물학은 실제로 상속보다 구성을 선호 하기 때문 입니다.

단순히 인터페이스를 구현하거나 "덕 타이핑"과 종속성 주입을 구현하는 것이 객체 지향 프로그래밍에 익숙하지 않은 사람들을 가르치는 데 훨씬 좋습니다.


1

나는 단지 실제 사례를 보여줄 것입니다. 예를 들어, 대부분의 UI 프레임 워크에서는 "Dialog"또는 "Window"또는 "Control"클래스에서 파생되어 사용자가 직접 만들 수 있습니다.


1

좋은 예는 정렬에서 비교 함수입니다.

template<class T>
class CompareInterface {
public:
   virtual bool Compare(T t1, T t2) const=0;
};
class FloatCompare : public CompareInterface<float> { };
class CompareImplementation : public FloatCompare {
public:
   bool Compare(float t1, float t2) const { return t1<t2; }
};
template<class T>
void Sort(T*array, int size, CompareInterface<T> &compare);

유일한 문제는 초보자가 너무 자주 성능이 좋은 코드보다 중요하다고 생각한다는 것입니다 ...


0

내 실제 예는 차량입니다.

public class Vehicle
{
    public Vehicle(int doors, int wheels)
    {
        // I describe things that should be
        // established and "unchangeable" 
        // when the class is first "made"
        NumberOfDoors = doors;
        NumberOfWheels = wheels;
    }

    public void RollWindowsUp()
    {
        WindowsUp = true;
    }

    // I cover modifiers on properties to show
    // how to protect certain things from being
    // overridden
    public int NumberOfDoors { get; private set; }
    public int NumberOfWheels { get; private set; }

    public string Color { get; set; }
    public bool WindowsUp { get; set; }
    public int Speed { get; set; }
}

public class Car : Vehicle
{
    public Car : base(4, 4)
    {

    }
}

public class SemiTruck : Vehicle
{
    public SemiTruck : base(2, 18)
    {

    }
}

이 예제는 원하는대로 자세하게 얻을 수 있으며, 가르치고 자하는 모디파이어의 사용법을 설명하기 위해 차량에 부착 된 모든 종류의 속성이 있습니다.


2
코드를 개선하기 위해 상속을 어떻게 사용할 수 있는지 이해하는 데 새로운 프로그래머를 얻지 못하기 때문에 항상 예제로 차량을 사용하는 것을 싫어 했습니다. 차량은 프로그래머가 아닌 사람의 마음에 많은 비 추상적 인 아이디어를 떠올리게하는 엄청나게 복잡한 기계입니다. 이것을 코드로 설명하려고 시도하면 평균 초보자는 예제에서 많은 세부 사항이 남았다 고 생각하고 작동하기 위해 더 가깝지 않다는 느낌을줍니다. 나는 누군가가 나에게 그것을 설명하기 위해 차량을 사용하려고 시도했을 때 느꼈던 것과 똑같이 경험에서 이것을 말합니다 .
riwalk

@ Stargazer712 : 차량은 주로 복잡하거나 간단 할 수 있기 때문에 주로 사용합니다. 나는 그의 학생의 수준을 결정하기 위해 강사의 판단에 맡깁니다. 나는 일반적인 기본 사항을 설명하는 차량의 간단한 속성을 사용하여 아내에게 프로그래밍 경험이없는 기본 OOP를 설명했습니다. 모든 차량에는 문이 있고, 모든 차량에는 바퀴 등이 있습니다. 수업의 예가 잘못되었다고 개체 예제를 비난 할 수 없습니다.
Joel Etherton

아내가 코드를 쓰려고하지 않았습니다. 나는 비히클 예제가 상속을 이해하는 데 도움이되지 않았다고 매우 안전하게 말할 수 있습니다 . 상속을 설명하는 데 사용하는 것이 무엇이든 완전 하고 실용적 이어야합니다 . 프로그래머가 아닌 사람이 이해할 수있는 방식으로 설명하지 않는 것이 목표입니다. 초보자 프로그래머가 사용할 수있는 방식으로 기술하는 것이 목표이며 , 그렇게하는 유일한 방법은 전문가 프로그래머가 사용하는 방법의 초보자 예를 보여주는 것입니다.
riwalk

@ Stargazer712 : 저의 수업 계획에 대한 상속을 처음 이해할 수 없었습니다. 나는 또한 함께 일하는 후배들에게 상속을 설명하기 위해 차량을 사용했으며,이 개념에 대해 아무런 문제가 없었습니다. 제 생각에, 수업 계획이 철저하고 적절하게 구성되면 차량 목표는 완전하고 실용적입니다. 인터넷에있는 1 명의 임의의 사람은 내가 OOP를 가르친 30 명 정도의 인턴과 주니어 개발자의 얼굴을 바꾸지 않을 것입니다. 차량이 마음에 들지 않으면 투표를하고 계속 진행하십시오.
Joel Etherton

당신이 원하는대로 ....
riwalk

0

이 비 포유류, 비 조류, 비 물고기 예는 다음과 같은 도움이 될 수 있습니다.

public abstract class Person {

    /* this contains thing all persons have, like name, gender, home addr, etc. */

    public Object getHomeAddr() { ... }

    public Person getName() { ... }

}

public class Employee extends Person{

    /* It adds things like date of contract, salary, position, etc */

    public Object getAccount() { ... }

}

public abstract class Patient extends Person {
    /* It adds things like medical history, etc */
}

그때

public static void main(String[] args) {

    /* you can send Xmas cards to patients and employees home addresses */

    List<Person> employeesAndPatients = Factory.getListOfEmployeesAndPatients();

    for (Person p: employeesAndPatients){
        sendXmasCard(p.getName(),p.getHomeAddr());
    }

    /* or you can proccess payment to employees */

    List<Employee> employees = Factory.getListOfEmployees();

    for (Employee e: employees){
        proccessPayment(e.getName(),e.getAccount());
    }       

}

참고 : 비밀을 말하지 마십시오 : 사람은 포유 동물을 확장합니다.


1
직원 중 한 명이 환자가 될 때까지 작동합니다.
Scott Whitlock

이 경우, Patient와 Employee를 추상 클래스 대신 인터페이스로 선언하는 것이 더 합리적이라고 생각합니다. 따라서 Person이 여러 인터페이스를 구현할 수있는 유연성이 제공됩니다.
Jin Kim

@ JinKim-전적으로 동의합니다. 그것이 더 나은 방법입니다.
Scott Whitlock

@JinKim 그들은 독점적이지 않습니다. 주어진 시간에 직원을 환자 또는 환자로 취급하지만 동시에는 아닙니다. 두 개의 인터페이스는 문제가 없지만 EmployeePatient? 당신은 얼마나 많은 조합을 가지고 있습니까?
Tulains Córdova

당신은 당신이 원하는대로 구체적인 클래스를 호출 할 수 있습니다. 코드가 직원 만 처리 할 것으로 예상되면 참조를 직원으로 선언합니다. (예 : Employee employee = new Person ();) 코드가 환자 만 다룰 것으로 예상되는 경우 참조를 환자로 선언합니다. 드물게 구체적인 클래스로 참조를 선언하고 싶습니까?
Jin Kim

0

대수 표현의 계층 구조는 어떻습니까? 상속과 구성을 모두 포함하기 때문에 좋습니다.

+--------------------+------------------------+
| Expression         |<------------------+    |
+--------------------+----------+        |    |
| + evaluate(): int  |<---+     |        |    |
+--------------------+    |     |        |    |
          ^               |     |        |    |
          |               |     |        |    |
   +--------------+  +---------------+  +-------------+  ...
   | Constant     |  | Negation      |  | Addition    |
   +--------------+  +---------------+  +-------------+
   | -value: int  |  |               |  |             |
   +--------------+  +---------------+  +-------------+
   | +evaluate()  |  | +evaluate()   |  | +evaluate() |
   | +toString()  |  | +toString()   |  | +toString() |
   +--------------+  +---------------+  +-------------+

   Addition(Constant(5), Negation(Addition(Constant(3),Constant(2))))
   (5 + -(3 + 2)) = 0

루트 표현식 Constant를 제외하고 다른 모든 표현식은 모두 표현식이며 하나 이상의 표현식을 포함합니다.


-1

새를 예로 사용하겠습니다

닭고기, 오리, 독수리처럼

나는 발톱, pecks 및 날개가 모두 있지만 설명은 다르지만 그 특성은 다릅니다.

닭은 날 수없고, 수영 할 수없고, 벌레를 먹을 수 있고, 곡물을 먹을 수 있습니다

오리는 날 수없고, 수영하고, 곡물을 먹을 수 있고, 벌레를 먹을 수 없습니다

독수리는 날 수 있고, 수영 할 수없고, 벌레를 먹을 수 있고, 곡물을 먹을 수 없습니다


4
나는 구성과 인터페이스가 아마도 이런 종류의 개념, 즉 날기, 수영 등을 전달하는 가장 좋은 방법이라는 것을 읽었습니다.
dreza

오리는 날 수 없습니까?!
Adam Cameron

-3

일반적인 레일스 클론은 많은 실제적인 예를 제공합니다 . 모든 데이터 조작을 캡슐화하는 (추상적 인) 기본 모델 클래스가 있고 모든 HTTP 통신을 캡슐화하는 기본 컨트롤러 클래스가 있습니다.


이 답변이 왜 나쁜지 자세히 설명 하시겠습니까?
keppla
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.