oopoop 시작하기


비고

객체 지향 프로그래밍 (OOP)은 "객체"개념을 기반으로하는 프로그래밍 패러다임으로, 필드 형태로 데이터를 포함 할 수 있습니다. 및 코드를 절차의 형태로, 종종 방법이라고합니다.

소개

OOP - 객체 지향 프로그래밍은 요즘 널리 사용되는 프로그래밍 패러다임입니다. OOP에서 객체와 동작을 사용하여 실제 문제를 모델링합니다. 프로그래밍을 통해 문제를 해결합니다.

네 가지 주요 OOP 개념이 있습니다.

  1. 계승
  2. 다형성
  3. 추출
  4. 캡슐화

이 네 가지 개념은 함께 OOP에서 프로그램을 개발하는 데 사용됩니다.

객체 지향 프로그래밍을 지원하는 다양한 언어가 있습니다. 가장 인기있는 언어는

  • C ++
  • 자바
  • 기음#
  • 파이썬 (파이썬은 완전히 객체 지향적이지는 않지만 대부분의 OOP 기능을 가지고 있습니다)

OOP 소개

침입

객체 지향 프로그래밍 (OOP라고도 함)은 문제를 해결하기위한 프로그래밍 패러다임입니다.
OO (객체 지향) 프로그램의 아름다움은 프로그램을 특정 주문에 따라 순차적 스크립트 대신 서로 통신하는 수많은 객체로 생각한다는 것입니다.

OOP를 지원하는 프로그래밍 언어가 많이 있습니다. 인기있는 언어는 다음과 같습니다.

  • 자바
  • C ++
  • 기음#

파이썬은 또한 OOP를 지원하는 것으로 알려져 있지만 몇 가지 속성이 부족합니다.


OOP 용어

OOP의 가장 기본적인 용어는 클래스 입니다.
클래스는 기본적으로 하나의 객체 를 가지며, 하나의 객체 는 상태를 가지며 객체 는 상태에 따라 작동합니다.

또 다른 중요한 용어는 인스턴스 입니다.
클래스를 자체 인스턴스를 만드는 데 사용되는 템플릿으로 생각하십시오. 클래스는 템플릿이며 인스턴스는 구체적인 객체입니다.

A 클래스에서 생성 된 인스턴스는 일반적으로 'type A'에서 참조됩니다. 5 의 유형이 int 이고 "abcd" 유형이 문자열 입니다.

유형 (class) 인 insance1 이라는 인스턴스를 생성하는 예제 ClassA :

자바

ClassA instance1 = new ClassA();
 

C ++

ClassA instance1;
 

또는

ClassA *instance1 = new ClassA(); # On the heap
 

파이썬

instance1 = ClassA()
 

위의 예제에서 볼 수 있듯이 모든 경우에 클래스 이름이 언급되고 그 뒤에는 빈 괄호가 있습니다 (C ++을 제외하고는 괄호를 제거 할 수 있습니다). 이 괄호 안에는 클래스의 생성자arguments 를 전달할 수 있습니다.

생성자는 인스턴스가 생성 될 때마다 호출되는 클래스의 메서드입니다. 인수를 취할 수도 있고 그렇지 않을 수도 있습니다. 프로그래머가 작성한 클래스에 대해 생성자를 지정하지 않으면 빈 생성자가 생성됩니다 (아무것도 수행하지 않는 생성자).
대부분의 언어에서 생성자는 반환 형식을 정의하지 않고 클래스의 동일한 이름을 가진 메서드로 정의됩니다 (몇 섹션의 예제).

유형 (class) ClassB의 b1 이라는 인스턴스를 작성하는 예제. ClassB 의 생성자는 int 형식의 인수 하나를 취합니다.

자바

ClassA instance1 = new ClassA(5);
 

또는

int i = 5;
ClassA instance1 = new ClassA(i);
 

C ++

ClassA instance1(5);
 

파이썬

instance1 = ClassA(5)
 

보시다시피, 인스턴스를 만드는 프로세스는 함수를 호출하는 프로세스와 매우 비슷합니다.


함수와 메소드

함수와 메소드 모두 매우 비슷하지만 Object Oriented Design (OOD)에서는 각각 고유 한 의미를 지닙니다.
메서드는 클래스의 인스턴스에서 수행되는 작업입니다. 메소드 자체는 대개 인스턴스의 상태를 사용하여 작동합니다.
한편, 함수는 특정 인스턴스가 아닌 클래스에 속합니다. 이는 클래스의 상태 나 인스턴스에 저장된 데이터를 사용하지 않음을 의미합니다.

이제부터는 OOP가이 언어로 매우 명확하기 때문에 Java 로만 예제를 보여줄 것입니다. 그러나 다른 OOP 언어에서도 같은 원리가 작동합니다.

Java에서 함수의 정의에는 정적 이라는 단어가 있습니다.

// File's name is ClassA
public static int add(int a, int b) {
    return a + b;
}
 

즉, 스크립트의 어느 위치에서든 호출 할 수 있습니다.

// From the same file
System.out.println(add(3, 5));

// From another file in the same package (or after imported)
System.out.println(ClassA.add(3, 5));
 

우리가 다른 파일에서 함수를 호출 할 때 클래스의 이름을 사용합니다 (Java에서는 파일의 이름이기도합니다).이 함수는 클래스가 속한 직관이 아니라 인스턴스에 속하는 직관을 제공합니다.

대조적으로 우리는 ClassA에서 다음 과 같이 정의 할 수 있습니다.

// File's name is ClassA
public int subtract(int a, int b){
    return a - b;
}
 

이 decleration 후에 우리는이 메소드를 다음과 같이 부를 수있다 :

ClassA a = new ClassA();
System.out.println(a.subtract(3, 5));
 

여기에서 우리는 ClassA 의 인스턴스를 생성하여 그 메소드의 subtract를 호출해야했습니다. 다음을 수행 할 수 없음을 유의 하십시오.

System.out.println(ClassA.subtract(3, 5));
 

이 줄은 인스턴스없이이 비 정적 메서드를 호출하여 컴파일 오류가 발생합니다.


클래스의 상태 사용하기

우리가 subtract 메소드를 다시 구현하려고한다고 가정 해보자. 이번에는 항상 (각 인스턴스에 대해) 같은 수를 빼기를 원한다. 다음 클래스를 생성 할 수 있습니다.

class ClassB {

    private int sub_amount;

    public ClassB(int sub_amount) {
        this.sub_amount = sub_amount;
    }

    public int subtract(int a) {
        return a - sub_amount;
    }

    public static void main(String[] args) {
        ClassB b = new ClassB(5);
        System.out.println(b.subtract(3)); // Ouput is -2
    }
}
 

이 코드를 실행하면 ClassB 클래스의 b 라는 새 인스턴스가 만들어지고 해당 생성자에 값 5가 제공 됩니다.
생성자는 이제 주어진 sub_amount 소요 (필드와 같은 인수 이름을이 규칙은 매우 자바로 알려져있다) 또한 sub_amount라는 자체 전용 필드로 저장합니다.
그 다음에 우리는 값을 3 으로하여 b 에 대해 메서드 빼기 를 호출 한 결과를 콘솔에 출력합니다.

뺄셈 의 구현에서 우리는 이것을 사용하지 않는다 this. 생성자 에서처럼.
Java this 이름은 해당 범위에 정의 된 동일한 이름의 다른 변수가있을 때 작성하면됩니다. 파이썬의 self 똑같이 작동합니다.
따라서 subtract에서 sub_amount 를 사용할 때 각 클래스마다 다른 private 필드를 참조합니다.

강조 할 또 다른 예.
위의 코드에서 main 함수를 다음과 같이 변경해 보겠습니다.

ClassB b1 = new ClassB(1);
ClassB b2 = new ClassB(2);

System.out.println(b1.subtract(10)); // Output is 9
System.out.println(b2.subtract(10)); // Output is 8
 

보시다시피, b1b2 는 독립적이며 각각 고유 한 상태 입니다.


인터페이스와 상속

인터페이스 는 계약이며 클래스가 가질 메소드와 그 기능을 정의합니다. 인터페이스에는 구현이 없으므로 필요한 작업 만 정의했습니다.
Java의 예는 다음과 같습니다.

interface Printalbe {
    public void print();
}
 

Printalbe 인터페이스는 print 라는 메소드를 정의하지만 구현 (Java에 대해서는 꽤 이상 함)을 제공하지 않습니다. 이 인터페이스를 implementing 하고있는 것으로 선언 한 모든 클래스는 draw 메서드에 구현을 제공해야합니다. 예 :

class Person implements Printalbe {

    private String name;

    public Person(String name) {
        this.name = name;
    }

    public void print() {
        System.out.println(name);
    }
}
 

PersonDrawable 구현으로 선언하지만 인쇄 구현을 제공하지 않으면 컴파일 오류가 발생하여 프로그램이 컴파일되지 않습니다.

상속은 다른 클래스를 확장 하는 클래스를 가리키는 용어입니다. 예를 들어 나이가 많은 사람이 있다고 가정 해 봅시다. 그런 사람을 구현하는 한 가지 방법은 Person 클래스를 복사하고 동일한 필드와 메서드를 가진 AgedPerson 이라는 새로운 클래스를 작성하는 것입니다.하지만이 클래스에는 또 다른 속성이 있습니다.
클래스에 간단한 기능을 추가하기 위해 전체 코드를 복제하기 때문에 이것은 끔찍할 것입니다.
Person 으로부터 상속 받기 위해 상속을 사용할 수 있으므로 모든 기능을 얻은 다음 새로운 기능으로 기능을 향상시킬 수 있습니다.

class AgedPerson extends Person {

    private int age;

    public AgedPerson(String name, int age) {
        super(name);
        this.age = age;
    }

    public void print() {
        System.out.println("Name: " + name + ", age:" + age);
    }
}
 

다음과 같은 몇 가지 새로운 일이 있습니다.

  • 우리는 저장된 단어가 사용되는 extends 우리는 사람이 상속을 표시하기 위해 (인쇄로도 구현하고, 그래서 우리는 선언 할 필요가 없습니다 implementing Printable 다시).
  • 우리는 super 라는 단어를 사용하여 Person 의 생성자를 호출했습니다.
  • Person인쇄 메소드를 새로운 것으로 오버라이드했습니다.

이것은 꽤 자바 기술을 사용하고 있으므로이 주제에 대해 더 깊이 다루지는 않을 것입니다. 그러나 상속과 인터페이스를 사용하기 전에 익히 알고 있어야하는 극단적 인 사례가 많이 있음을 언급 할 것입니다. 예를 들어 어떤 메소드와 함수가 상속 되는가? 수업을 상속 할 때 개인 / 공공 / 보호 된 필드는 어떻게됩니까? 등등.

추상 클래스

추상 클래스 는 인터페이스와 상속의 조합을 설명하는 OOP의 상당히 진보 된 용어입니다. 이것은 구현 된 메소드와 구현되지 않은 메소드 / 함수를 모두 가지고있는 클래스를 작성할 수있게 해줍니다. 자바에서는 abstract 라는 키워드를 사용하여 이루어지며 간단한 예를 더 설명하지는 않겠습니다.

abstract class AbstractIntStack {

    abstract public void push(int element);

    abstract public void pop();

    abstract public int top();

    final public void replaceTop(int element) {
        pop();
        push(element);
    }
}
 

참고 :이 클래스에서 상속 할 때이 메서드를 재정의 할 수 없다는 final 키워드가 나와 있습니다. 클래스가 final로 선언되면 클래스는 클래스를 상속받을 수 없습니다.