OOP 원칙

Random-KO 그룹에 게시되었습니다
자바는 객체지향 언어이다. 이는 객체 지향 스타일을 사용하여 Java 프로그램을 작성해야 함을 의미합니다. 그리고 이 스타일은 프로그램의 객체와 클래스 사용을 기반으로 합니다.

OOP의 기본 원칙:

OOP의 원리 - 1예제를 통해 클래스와 객체가 무엇인지, 그리고 OOP의 기본 원칙인 추상화, 상속, 다형성 및 캡슐화를 실제로 적용하는 방법을 이해해 보겠습니다.

객체란 무엇입니까?

우리가 살고 있는 세상은 사물로 구성되어 있다. 주변을 둘러보면 우리 주변에는 집, 나무, 자동차, 가구, 접시, 컴퓨터가 있다는 것을 알 수 있습니다. 이러한 항목은 모두 개체이며 각 항목에는 일련의 특정 특성, 동작 및 목적이 있습니다. 우리는 사물에 익숙하며 항상 매우 특정한 목적을 위해 사물을 사용합니다. 예를 들어, 출근하려면 자동차를 사용하고, 식사를 하려면 접시를 사용하고, 휴식이 필요하면 편안한 소파가 필요합니다. 사람은 일상생활에서 발생하는 문제를 해결하기 위해 객관적으로 생각하는 데 익숙합니다. 이것이 프로그래밍에서 객체를 사용하는 이유 중 하나였으며, 프로그램 작성에 대한 이러한 접근 방식을 객체 지향이라고 했습니다. 예를 들어 보겠습니다. 새로운 휴대폰 모델을 개발했고 대량 생산을 시작하고 싶다고 상상해 보세요. 휴대폰 디자이너라면 휴대폰의 용도, 기능, 구성 요소(케이스, 마이크, 스피커, 전선, 버튼 등)를 알고 있을 것입니다. 그러나 이러한 부품을 연결하는 방법은 오직 귀하만이 알고 있습니다. 그러나 귀하는 전화기를 개인적으로 생산할 계획이 없으며 이를 위해 전체 직원이 있습니다. 휴대폰 부품을 연결하는 방법을 매번 설명할 필요가 없도록, 생산 중인 모든 휴대폰이 동일하게 되도록 생산을 시작하기 전에 다음과 같은 형태로 그림을 그려야 합니다. 휴대폰 구조에 대한 설명입니다. OOP에서는 이러한 설명, 그림, 다이어그램 또는 템플릿을 클래스라고 하며, 프로그램이 실행될 때 객체가 생성됩니다. 클래스는 필드, 메소드, 생성자로 구성된 일반적인 템플릿과 같이 아직 생성되지 않은 객체에 대한 설명이며, 객체는 이러한 설명을 기반으로 생성된 클래스의 인스턴스입니다.

OOP 추상화

이제 전화기를 예로 들어 현실 세계의 객체에서 프로그램의 객체로 어떻게 이동할 수 있는지 생각해 봅시다. 이 통신 수단의 역사는 100년이 넘으며 현대 전화기는 19세기 이전 전화기와는 달리 훨씬 더 복잡한 장치입니다. 우리는 전화기를 사용할 때 전화기의 구조와 내부에서 일어나는 프로세스에 대해 생각하지 않습니다. 우리는 단순히 전화 개발자가 제공하는 기능(버튼이나 터치 스크린)을 사용하여 번호를 선택하고 전화를 겁니다. 최초의 전화 인터페이스 중 하나는 전화를 걸 때 돌리는 손잡이였습니다. 물론 이것은 그다지 편리하지 않았습니다. 그럼에도 불구하고 손잡이는 제 기능을 제대로 수행했습니다. 가장 현대적이고 최초의 전화기를 살펴보면 19세기 후반의 장치와 초현대식 스마트폰 모두에 중요한 가장 중요한 세부 사항을 즉시 식별할 수 있습니다. 전화를 걸고(전화를 걸고) 전화를 받는 것입니다. 본질적으로 이것이 전화기를 전화기로 만드는 것이지 다른 것이 아닙니다. 이제 우리는 객체에 대한 가장 중요한 특성과 정보를 강조하는 OOP의 원칙을 적용했습니다. OOP의 이러한 원칙을 추상화라고 합니다. OOP의 추상화는 실제 문제의 요소를 프로그램의 객체로 표현하는 방법으로 정의될 수도 있습니다. 추상화는 항상 객체 또는 객체의 속성에 대한 일부 정보의 일반화와 관련되어 있으므로 가장 중요한 것은 해결되는 문제의 맥락에서 중요한 정보와 중요하지 않은 정보를 분리하는 것입니다. 이 경우 여러 수준의 추상화가 있을 수 있습니다. 추상화의 원리를 휴대폰에 적용해 보겠습니다. 먼저, 최초부터 현재까지 가장 일반적인 유형의 전화기를 강조해 보겠습니다. 예를 들어, 그림 1에 표시된 다이어그램 형식으로 표현할 수 있습니다. OOP의 원리 - 2이제 추상화를 사용하여 이 객체 계층 구조의 일반 정보를 강조 표시할 수 있습니다. 일반적인 추상 유형의 객체 - 전화, 일반적인 특성 전화기 - 제작 연도 및 공통 인터페이스 - 모든 전화기는 전화를 받고 보낼 수 있습니다. Java에서는 다음과 같습니다.
public abstract class AbstractPhone {
    private int year;

    public AbstractPhone(int year) {
        this.year = year;
    }
    public abstract void call(int outputNumber);
    public abstract void ring (int inputNumber);
}
이 추상 클래스를 기반으로 우리는 아래에서 고려할 다른 기본 Java OOP 원칙을 사용하여 프로그램에서 새로운 유형의 전화기를 만들 수 있습니다.

캡슐화

추상화의 도움으로 우리는 모든 객체에 공통적인 것을 강조합니다. 그러나 각 휴대폰 모델은 개별적이며 다른 휴대폰 모델과 다소 다릅니다. 프로그램에 어떻게 경계를 긋고 이 개성을 지정할 수 있을까? 사용자 중 누구도 실수로 또는 의도적으로 전화기를 파손하거나 한 모델을 다른 모델로 변환하려고 시도하는 일이 없도록 어떻게 보장할 수 있습니까? 실제 사물의 세계에서는 답이 분명합니다. 모든 부품을 전화기 본체에 넣어야 합니다. 결국, 이 작업을 수행하지 않고 휴대폰 내부와 이를 연결하는 전선을 모두 외부에 남겨두면 휴대폰 작동을 "개선"하고 싶어하는 호기심 많은 실험자가 분명히 있을 것입니다. 객체의 설계 및 작동에 대한 이러한 간섭을 피하기 위해 OOP는 캡슐화 원칙을 사용합니다 . 이는 객체의 속성과 동작이 하나의 클래스로 결합되고 객체의 내부 구현이 숨겨지는 OOP의 또 다른 기본 원칙입니다. 사용자와 객체 작업을 위한 개방형 인터페이스가 제공됩니다. 프로그래머의 임무는 공개적으로 액세스할 수 있는 속성과 메서드, 객체의 내부 구현이므로 수정해서는 안 되는 것을 결정하는 것입니다.

캡슐화 및 액세스 제어

생산 과정에서 휴대폰 뒷면에 제조 연도 또는 제조업체 로고 등 정보가 새겨져 있다고 가정해 보겠습니다. 이 정보는 이 모델의 상태를 매우 구체적으로 특성화합니다. 휴대폰 개발자가 이 정보의 불변성을 처리했다고 말할 수 있습니다. 누구도 조각 제거를 생각하지 않을 것입니다. Java 세계에서 미래 객체의 상태는 필드를 사용하여 클래스에 설명되고 해당 동작은 메소드를 사용하여 설명됩니다. 상태 및 동작을 변경하는 기능은 필드 및 메소드( private, protected, publicdefault(기본 액세스))에 대한 액세스 한정자를 사용하여 수행됩니다. 예를 들어, 생성 연도, 휴대폰 제조업체 이름, 메서드 중 하나는 클래스의 내부 구현에 속하며 프로그램의 다른 개체에 의해 변경될 수 없다고 결정했습니다. 코드를 사용하면 클래스를 다음과 같이 설명할 수 있습니다.
public class SomePhone {

    private int year;
    private String company;
    public SomePhone(int year, String company) {
        this.year = year;
        this.company = company;
    }
private void openConnection(){
    //findComutator
    //openNewConnection...
}
public void call() {
    openConnection();
    System.out.println("I'm calling a number");
}

public void ring() {
    System.out.println("Дзынь-дзынь");
}

 }
수정자는 private클래스의 필드와 메서드를 해당 클래스 내에서만 사용할 수 있도록 만듭니다. 즉, private외부에서 필드에 액세스할 수 없고 private메서드를 호출할 수도 없습니다. 메소드에 대한 액세스를 숨기면 openConnection이 메소드의 내부 구현을 자유롭게 변경할 수 있는 기회도 얻게 됩니다. 왜냐하면 이 메소드는 다른 객체에서 사용되지 않고 해당 객체의 작업을 방해하지 않기 때문입니다. 개체를 사용하여 작업하려면 수정자를 call사용하여 메서드를 열어 둡니다 . 객체 작업을 위한 공개 메소드를 제공하는 것도 캡슐화 메커니즘의 일부입니다. 객체에 대한 액세스가 완전히 거부되면 쓸모가 없게 되기 때문입니다.ringpublic

계승

다시 전화차트를 살펴보겠습니다. 아래에 있는 모델이 분기의 상위에 있는 모델의 모든 특성과 자체 특성을 모두 갖는 계층 구조를 나타내는 것을 볼 수 있습니다. 예를 들어, 스마트폰은 통신을 위해 셀룰러 네트워크를 사용하고(휴대폰의 속성을 가짐), 무선 및 휴대가 가능하며(무선 전화기의 속성을 가짐), 전화를 받고 걸 수 있습니다(전화의 속성을 가짐). 이 경우 객체 속성의 상속에 대해 이야기할 수 있습니다. 프로그래밍에서 상속은 기존 클래스를 사용하여 새 클래스를 정의하는 것입니다. 상속을 사용하여 스마트폰 클래스를 생성하는 예를 살펴보겠습니다. 모든 무선 전화기는 몇 시간 단위로 특정 작동 수명을 갖는 충전식 배터리로 전원을 공급받습니다. 이제 무선 전화 클래스에 이 속성을 추가해 보겠습니다.
public abstract class WirelessPhone extends AbstractPhone {

    private int hour;

    public WirelessPhone(int year, int hour) {
        super(year);
        this.hour = hour;
    }
    }
휴대폰은 무선 전화의 속성을 상속하며, 이 클래스에 call및 메서드 구현도 추가했습니다 ring.
public class CellPhone extends WirelessPhone {
    public CellPhone(int year, int hour) {
        super(year, hour);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("Calling a number" + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("A subscriber is calling you" + inputNumber);
    }
}
그리고 마지막으로 기존 휴대폰과 달리 본격적인 운영 체제를 갖춘 스마트 폰 클래스입니다. 이 운영 체제에서 지원하는 새 프로그램을 스마트폰에 추가하여 기능을 확장할 수 있습니다. 코드를 사용하면 클래스를 다음과 같이 설명할 수 있습니다.
public class Smartphone extends CellPhone {

    private String operationSystem;

    public Smartphone(int year, int hour, String operationSystem) {
        super(year, hour);
        this.operationSystem = operationSystem;
    }
public void install(String program){
    System.out.println("Installing" + program + "For" + operationSystem);
}

}
보시다시피, Smartphone클래스를 설명하기 위해 새로운 코드를 거의 만들지 않았지만 새로운 기능을 갖춘 새 클래스를 얻었습니다. OOP 상속 원칙을 사용하면 코드 양을 크게 줄일 수 있으므로 프로그래머의 작업이 더 쉬워집니다.

다형성

모든 휴대폰 모델을 살펴보면 모델의 모양과 디자인의 차이에도 불구하고 몇 가지 공통된 동작을 식별할 수 있습니다. 모두 전화를 받고 걸 수 있으며 상당히 명확하고 간단한 제어 버튼 세트가 있습니다. 이미 우리에게 알려진 OOP의 기본 원칙 중 하나인 프로그래밍 용어의 추상화를 적용하면 전화 개체에 하나의 공통 인터페이스가 있다고 말할 수 있습니다. 따라서 휴대폰 사용자는 장치의 기술적인 세부 사항을 다루지 않고도 동일한 제어 버튼(기계식 또는 터치식)을 사용하여 매우 편안하게 다양한 모델을 사용할 수 있습니다. 그래서, 당신은 끊임없이 휴대전화를 사용하고, 유선전화 상대방으로부터 쉽게 전화를 걸 수 있습니다. 프로그램이 객체의 내부 구조에 대한 정보 없이 동일한 인터페이스를 가진 객체를 사용할 수 있는 OOP의 원칙을 다형성 이라고 합니다 . 우리 프로그램에서 어떤 전화 모델을 사용해도 다른 사용자에게 전화를 걸 수 있는 사용자를 설명해야 한다고 가정해 보겠습니다. 수행 방법은 다음과 같습니다.
public class User {
    private String name;

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

    public void callAnotherUser(int number, AbstractPhone phone){
// here it is polymorphism - using the abstract type AbstractPhone phone in the code!
        phone.call(number);
    }
}
 }
이제 다양한 전화기 모델을 설명하겠습니다. 최초의 휴대폰 모델 중 하나:
public class ThomasEdisonPhone extends AbstractPhone {

public ThomasEdisonPhone(int year) {
    super(year);
}
    @Override
    public void call(int outputNumber) {
        System.out.println("Turn the Handle");
        System.out.println("Give me the phone number, sir");
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Phone calls");
    }
}
일반 유선전화:
public class Phone extends AbstractPhone {

    public Phone(int year) {
        super(year);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("I'm calling a number" + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Phone calls");
    }
}
그리고 마지막으로 멋진 비디오폰이 있습니다.
public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }
    @Override
    public void call(int outputNumber) {
        System.out.println("I connect a video channel for the subscriber" + outputNumber );
    }
    @Override
    public void ring(int inputNumber) {
        System.out.println("You have an incoming video call..." + inputNumber);
    }
  }
메서드에서 개체를 만들고 main()메서드를 테스트해 보겠습니다 callAnotherUser.
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Andrey");
user.callAnotherUser(224466,firstPhone);
// Rotate the knob
// Tell me the number of the subscriber, sir
user.callAnotherUser(224466,phone);
//Call number 224466
user.callAnotherUser(224466,videoPhone);
//I connect the video channel for subscriber 224466
객체에 대해 동일한 메소드를 호출함으로써 user우리는 다른 결과를 얻었습니다. call메소드 내의 특정 메소드 구현 선택은 callAnotherUser프로그램 실행 중 호출 객체의 특정 유형을 기반으로 동적으로 이루어졌습니다. 이것이 다형성의 주요 장점, 즉 프로그램 실행 중 구현 선택입니다. 위의 전화 클래스 예제에서는 메서드 서명을 변경하지 않고 기본 클래스에 정의된 메서드 구현을 변경하는 기술인 메서드 재정의를 사용했습니다. 이는 본질적으로 메서드 대체이며 프로그램이 실행될 때 호출되는 하위 클래스에 정의된 새 메서드입니다. 일반적으로 메서드를 재정의할 때 주석이 사용됩니다 @Override. 이는 컴파일러에게 재정의된 메서드와 재정의하는 메서드의 서명을 확인하도록 지시합니다. 결과적으로 프로그램 스타일이 OOP 개념과 OOP java 원칙을 준수하는지 확인하려면 다음 팁을 따르세요.
  • 물체의 주요 특징을 강조합니다.
  • 공통 속성과 동작을 강조하고 객체 생성 시 상속을 사용합니다.
  • 추상 유형을 사용하여 객체를 설명합니다.
  • 클래스의 내부 구현과 관련된 메서드와 필드를 항상 숨기도록 노력하세요.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION