Java

객체지향언어란

fw3d 2025. 3. 28. 17:52

1.객체(데이터와 메서드를 포함한 개념)지향의 시작 

 

 초기의 방식은 절차적 프로그래밍(procedural programing) 방식이였다. 입력을 받아 명시된 순서로 처리한뒤 그결과를내는방식. 이시기에는 프로그램을 명령어의 모음으로 인식했다. 기능에만 신경썻지 이프로그램이 어떤 데이터를취급하는지에는 관심이없었다. 이러한 방식은 알고리즘이 조금만 복잡해져도 순서도로 나타내는것이 불가능할정도로 꼬인스파게티코드가 된다.  명령어의 양이 많아지는것은 기본이고 흐름파악도 힘들며 중복코드대처도 골치아프다.  이러한 procedure단위로 나누고 호출하는 방법은 데이터의 처리방법을 구조화 했을 뿐 데이터 자체는 구조화하지못했다.  또한 gui 가 등장하며 같은 명령에도 다른결과( 비활성화된 창에 x 키 누르면 꺼지는게 아니라 폴더선택. 활성화된 창에다 x누르면 화면꺼짐 )를 내보내야하게되었다 (객체지향의 특징인 다형성) 

 

 이러한 상황에서 큰문제를 작게 쪼개는것이 아니라, 작은 문제들을 해결할 수 있는 객체들을 만든뒤 이객체들을 조합해서 큰문제를 해결하는 상향식bootom-up 해결법을도입한것이다. 이렇게 객체지향프로그래밍 개념이 발전하게 되었다.

프로그래밍의 관점이 procedure에서 객체로 확장된것에 가깝다. 

 

 절차적 프로그래밍이란 단순히 순차적인 명령수행이 아니라 함수, 메소드, 루틴 서브루틴(통틀어 procedure)를 이용한 프로그래밍 패러다임이다.절차적이지 않은 프로그래밍이란 건 애초에 존재하지 않는다.

따라서 객체지향프로그래밍의 반대말이 절차지향 프로그램이라는 말도 잘못된 표현이다. Procedural의 Procedure는 '절차'라는 의미가 아니라 위에도 언급되었듯 '프로시저'의 의미이다. 이 패러다임에서는 프로시저 콜, 즉 함수 호출을 통해서 추상화와 재사용성을 얻어내는 것이 본질이기 때문이다.  

 

 

2. Object Oriendted Programing 

 객체 지향프로그래밍은 프로그램 설계 방법론이다. 

 

 프로그램을 단순히 데이터와 처리방법으로 나누는것이 아니고, 프로그램을 객체라는 기본단위로 나누고 이들의 상호작용을 서술하는 방식이다.  객체는 메서드와 변수를 가지며 특정역할을 수행하도록 인간이 정의한 추상적인 개념이다.

 

2.1 객체지향의 주요특징

 

1. 캡슐화 encapsulation

변수와 함수를 하나의 단위로 묶는것. 메서드와 데이터를 객체안에 캡슐화 하는것. 외부에서는 객체가 제공하는 메서드를 통해서만 조작가능하다. 

캡슐화로 코드의 변경이 시스템 전체에 영향을 덜 미침

캡슐화에서 파생된 정보은닉이라는 개념이 있다. 

클래스 외부에서는 바깥으로 노출된  특정 메소드에만 접근이 가능하며 클래스 내부에서 어떤식으로 처리가 이루어지는 지는 알지못하도록 설계된다 

일반적으로 세종류의 접근제한이 사용된다

public 클래스의 외부에서 사용가능하도록 노출시키는것

protected 다른클래스에게는 노출되지 않지만, 상속받은 자식클래스에게는 노출되는것

private 클래스 내부에서만 사용되며 외부로 노출되지않는다.

객체지향이라는 특성에서 나온 보안관련개념

 

 2. 상속 inheritance

상속은 자식 클래스가 부모 클래스의 특성과 기능을 그대로 물려받는 것을 말한다. 기능의 일부분을 변경해야 할 경우 자식 클래스에서 상속받은 그 기능만을 수정해서 다시 정의하게 되는데, 이러한 작업을 '오버라이딩(overriding)'이라고 한다. 상속은 캡슐화를 유지하면서도 클래스의 재사용이 용이하도록 해 준다.

 

3 .다형성 polymorphism

동일한 메소드가 다양한 형태로 동작가능 

class animald의 함수 sound() 와 자식클래스 dog의 함수 sound() 가 다르게 동작한다 

인터페이스를 구현하는 상위 클래스를 생성하고, 해당 클래스를 상속받는 다수의 하위 클래스들을 만들어 상위 클래스의 포인터나 참조변수 등이 하위 클래스의 객체를 참조하게 하는 것이다. 이 때 각각의 하위 클래스는 상위 클래스의 메소드 위에 자신의 메소드를 덮어 쓰는 메소드 오버라이딩(method overriding)을 수행하며, 상위 클래스의 참조 변수가 어떤 하위 클래스의 객체를 참조하느냐에 따라 호출되는 메소드가 달라진다 

클래스가 상속 관계에 있을 때 나타나는 다채로운 성질

 

4. 추상화 abstraction 말그대로 추상적이다(=애매하다,모호하다) 라는뜻이다. 

복잡한 내부구현을 숨기고 필요한 기능만 외부에 제공 인터페이스 또는추상클래스르 통해 구현한다

추상 클래스는 자식 클래스들에 공통된 속성이나 메서드를 정의하고 자식 클래스는 이러한 구조를 물려받아 일관성 있는 설계를 따른다.

 

추상적이다. 객체지향이라는 특성에서 나오는 특징이다.

같은것을 묶어주는 부모클래스에서는 구체적인 기능을 구현하지 않는다. 개, 고양이, 사람이라는 인스턴스가 있으면 이들의 공통적인 특징. 먹는다 잠잔다. 를 추상화된 클래스에 명시한다. 


// 추상화된 클래스
abstract class Animal {
    abstract void eat(); a
    abstract void sleep(); }

// 구체적인 인스턴스 (구체적 구현)
class Dog extends Animal { void eat() { System.out.println("Dog eats bones."); } void sleep() { System.out.println("Dog sleeps in its kennel."); } }
class Cat extends Animal { void eat() { System.out.println("Cat eats fish."); } void sleep() { System.out.println("Cat sleeps on the sofa."); } }

 

그렇다면 클래스가 있는데, 굳이 추상클래스를 사용하는이유. 

 

구체적인 객체를 생성하고 사용 vs 공통설계와 구조를정의

인스턴스화 가능 vs 인스턴스화 불가

모든 메서드 구현 포함  vs  구현된 메서드 + 추상 메서드( 추상 메서드는 반드시 하위 클래스에서 구현한다. 강제성)

독립적이고 완전한 동작이 필요한경우   vs  공통 기능 제공 및 설계 강제

 

 

3. 객체지향 5원칙 SOLID

 

1.srp 단일책임원칙 single responsibility principle

객체는 오직 하나의 책임을 가져야한다 (객체는 오직 하나의 변경의 이유만을 가져야한다)

예로 사칙연산 함수를  가진 계산클래스가 있다면 이 계산클래스는 오직 사칙연산 기능만을 책임진다. . 만일 프로그램이 대대적으로 공사를 들어가게 되더라도 계산 클래스가 수정될 만한 사유는 누가 봐도 사칙 연산 함수와 관련된 문제뿐이다. 이처럼 단일 책임 원칙은 클래스의 목적을 명확히 함으로써 구조가 난잡해지거나 수정 사항이 불필요하게 넓게 퍼지는 것을 예방하고 기능을 명확히 분리할 수 있게 한다.

 

2. ocp  개방 폐쇄 원칙 open closed principle

객체는 확장에 대해서는 개방적이고 수정에 대해서는 폐쇄적이어야 한다는 원칙이다. 즉, 객체 기능의 확장을 허용하고 스스로의 변경은 피해야 한다.

클래스의 '이동' 메서드는 수정할 필요조차 없다(수정에 대해선 폐쇄). 그냥 이동의 하위 클래스 '이동 패턴 메서드'만 재정의하면 그만인 것이다(확장에 대해선 개방). 구현을 하위클래스에 맡긴다. 

 

3. lsp 리스코프 치환 원칙 liskov substitution prinsiple

자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있다는 원칙이다. 즉 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 계획대로 잘 작동해야 한다는 것. 상속의 본질인데, 이를 지키지 않으면 다형성을 지킬 수 없게 된다.

 

4. ISP 인터페이스 분리원칙 interface segregation principle

클라이언트에서 사용하지 않는 메서드는 사용해선 안 된다. 그러므로 인터페이스를 다시 작게 나누어 만든다. OCP와 비슷한 느낌도 들지만 엄연히 다른 원칙이다. 하지만 ISP를 잘 지키면 OCP도 잘 지키게 될 확률이 비약적으로 증가한다. 정확히 말하자면 인터페이스의 SRP라고 할 수 있다.

 

5. DIP 의존성 역전 원칙 dependency inversion principle

추상성이 높고 안정적인 고수준의 클래스는 구체적이고 불안정한 저수준의 클래스에 의존해서는 안 된다는 원칙으로서, 일반적으로 객체 지향의 인터페이스를 통해서 이 원칙을 준수할 수 있게 된다. (상대적으로 고수준인) 클라이언트는 저수준의 클래스에서 추상화한 인터페이스만을 바라보기 때문에, 이 인터페이스를 구현한 클래스는 클라이언트에 어떤 변경도 없이 얼마든지 나중에 교체될 수 있다. (디자인 패턴 중 전략 패턴을 떠올리면 된다)

제어의 역전을 의미하는 Inversion of control(IoC)과 용어가 비슷하기에 혼동하기 쉬우나, 혼동해서는 안 된다. IoC는 제어의 흐름에 대한 개념이지만(라이브러리와 프레임워크의 차이) DIP는 클래스 사이의 의존성에 대한 개념이다.