OOP(Object Oriented Programming) 이해
특징
- 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수 많은 ‘객체’라는 기본 단위로 나누고 이 객체들을 상호작용으로 서술하는 방식.
장점
- 코드 재사용 용이
- 남이 만든 클래스를 가져와 활용하거나 상속을 통해 확장 사용 가능
- 유지보수가 쉬움
- 절차지향 프로그래밍에서 코드를 수정해야하는 경우 일일이 찾아 수정해야하는 반면, 객체지향 프로그래밍에서는 수정해야할 부분이 클래스 내 멤버변수 혹은 메서드로 있기 때문에 수정이 쉬움.
- 대형 프로젝트에 적합
- 클래스 단위로 모듈화시켜 개발 가능하므로, 대형 프로젝트와같이 여러 집단에서 개발이 필요할 시 업무분담이 쉬움.
단점
- 처리 속도가 상대적으로느림
- 객체가 많으면 용량이 커질 수 있음
- 설계시 많은 시간과 노력 필요
절차지향 프로그래밍과의 차이
- 절차지향 프로그래밍은 함수를 기계, 데이터를 원료로 생각해 데이터가 함수 사이를 통과하면서 순서대로 가공되어 나가는 방식.
- 객체지향 프로그래밍은 데이터를 중심으로 메서드가 데이터가 접근해서 수정하는 개념.
특성
-
추상화(Abstraciton)
공통의 속성이나 기능을 묶어 이름을 붙이는 것
-
객체지향 관점에서 클래스를 정의하는 것을 추상화라고 할 수 있다.
- ex) 물고기, 뱀, 사자, 토끼, 뱀이 있을 때 이를 동물 or 생물이라는 추상적인 객체로 정의할 수 있다. 이 때 동물 또는 생물이라고 묶는 것을 추상화라고 칭한다.
-
목적: 코드를 재수정 없이 재활용하는 것
-
사물들의 공통된 특징, 즉 추상적 특징을 파악해 인식의 대상으로 삼는 행위.
-
구체적인 사물들의 공통적인 특징을 파악해서 이를 하나의 개념(집합)으로 다루는 수단.
-
각 개체의 구체적인 개념에 의존하지 말고, 추상적 개념에 의존해야 설계가 유연해짐.
-
구체적 개념의 예
switch(자동차 종류) case 아우디: // 아우디 엔진 오일을 교환하는 과정을 기술 case 벤츠: // 벤츠 엔진 오일을 교환하는 과정을 기술 case bmw: // BMW 엔진 오일을 교환하는 과정을 기술 // 새로운 종류의 자동차가 나올 때마다 계속 추가해야하는 번거로움 존재.. end switch
-
추상적 개념의 예
void changeEngineOil(Car c) { c.changeEngineOil() // 추상 메서드 }
- 메소드의 인자로 아우디, 벤츠의 추상화 개념인 Car 클래스 이용
- 어떤 새로운 자동차의 종류가 나와도 변경할 필요가 없는 코드다.
- 다형성의 원리에 따라 각 구체적인 클래스에서 오버라이드된 changeEngineOil() 호출.
-
-
예시
public class Clock { // Field int hour; int minute; int second; // Method public void view() { // 시간 출력 } }
-
-
캡슐화(Encapsulation)
객체의 필드(변수)와 메소드(함수)를 하나로 묶고 실제 구현 내용을 감추는 것
- 외부 객체는 내부 객체의 구조를 할 수 없고, 내부 객체가 제공하는 필드와 메소드만 이용 가능.
- 은닉화: 객체를 외부로부터 숨기고 접근 못하게 하는 것.
- private 지시자 이용.
- 캡슐화의 한 부분.
- 은닉화: 객체를 외부로부터 숨기고 접근 못하게 하는 것.
-
외부에서 직접적으로 데이터를 접근시켜서는 안되며, 함수를 통해서 접근시키도록 해야 함.
-
캡슐화를 하낟면 은닉화도 자연스럽게 된 것.
-
예시
public class CoffeeMachine { private int coffee; private int sugar; piblic int getCoffee() { return coffee; } public void setCoffee(int shot) { sugar = shot; } public void getSugar() { return sugar; } public void setSugar(int count) { sugar = count; } } public class Cafe { public static void main(String args[]) { CoffeeMachine cm = new CoffeeMachine(); cm.setCoffee(3); cm.setSugar(2); System.out.println("주문한 커피는 " + cm.getCoffee() + "샷, 설탕은 " + cm.getSugar + "개 첨부되었습니다."); } }
- 외부 객체는 내부 객체의 구조를 할 수 없고, 내부 객체가 제공하는 필드와 메소드만 이용 가능.
-
상속성(Inheritance)
상속 개념의 특징을 하위 개념이 물려받은 것
-
부모역할을 하는 상위 객체가 자식 역할을 하는 하위 개체에게 자신이 가진 속성(필드, 메소드)을 물려주는 것.
-
하위 객체는 상황에 맞게 상위 객체에게 물려 받은 메소드를 오버라이딩해서 사용할 수 있음.
-
이미 만들어져 있는 상위 객체를 재사용하여 하위 객체를 쉽고 빨리 설계할 수 있도록 도와줌.
-
상위 객체의 수정으로 모든 하위 객체들에게도 수정 효과를 낼 수 있음 → 유지보수 탁월
-
예시
class Human { String name; int height; // 생성자 public Human(String name, int height) { this.name = name; this.height = height; } public void showInfo() { System.out.println("이름: " + name); System.out.println("키: " + height); } } class SuperMan extends Human { int power=0; public Superman() { super("슈퍼맨", 170); } public Superman(String name, int height, int power) { super(name, height); this.power = power; } } public class Inheritance { public static void main(String args[]) { Superman m1 = new Superman("김철수", 190, 550); SUperman m2 = new Superman("박유리", 290, 540); m1.showInfo(); m2.showInfo();) } }
-
-
다형성(Polymorphism)
같은 메세지에 대해 클래스에 따라 다른 행위를 하게 되는 특징
-
같은 이름을 가지는 메서드에 대해 인자의 개수와 데이터형에 따라 수행되는 행위가 달라짐
-
서로 다른 객체를 같은 방식으로 사용할 수 있게 됨.
-
오버라이딩(Overriding), 오버로딩(Overloading)이 가능하다는 의미.
- Overriding: 부모클래스의 메소드와 같은 이름, 매개변수 재정의.
- Overloading: 같은 이름의 함수를 여러개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개변수에 따라 호출될 수 있게 하는 것.
-
하나의 타입에 여러 가지 대입을 할 수 있기 때문에 다양한 기능 이용 가능
-
상속과 연계되어 동작하면 매우 강력한 힘 발휘
-
JAVA의 경우,
- 다형성을 위해 부모클래스나 인터페이스의 타입 변환 허용
- 부모 타입에는 모든 자식 객체가 대입될 수 있고, 인터페이스 타입에는 모든 구현 객체 대입 가능.
-
다형성을 사용하는 경우 구체적으로 현재 어떤 클래스 객체가 참고되는지와 무관하게 프로그래밍 가능.
-
일반화 관계에 있을 때 부모 클래스의 참조 변수가 자식 클래스의 객체를 참조할 수 있기 때문에 새로운 자식 클래스가 추가되어도 크게 영향을 받지 않음.
- 단, 부모 클래스의 참조 변수가 접근할 수 있는 것은, 부모 클래스가 물려준 변수가 메서드 뿐임.
-
예시
- 다형성 사용하지 않는 경우
public class Cat { public void meow() { System.out.println("야옹"); } } public class Dog { public void bark() { System.out.println("멍멍"); } } public class Parrot { public void sing() { System.out.println("안녕"); } } public class Main { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); Parrot parrot = new Parrot(); // 세 마리의 울음소리 호출 cat.meow; dog.bark(); parrot.sing(); } }
- 다형성 사용하는 경우
//부모 클래스 public abstract class Pet { public abstract void talk(); } // 자식 클래스 public class Cat extends Pet { public void talk() { System.out.println("야옹"); } } public class Dog extends Pet { public void talk() { System.out.prinln("멍멍"); } } public class Parrot extends Pet { public void talk() { System.out.println("안녕"); } } public class Main() { public static void main(String[] args) { Pets[] pets = { new Cat(), new Dog(), new Parrot() }; for(int i=; i<3; i++) { pets.talk(); } } }
-