-
TIL-2024.04.12 - Basic - OOP. 객체지향프로그래밍(OOP)> 기초/백그라운드 2024. 4. 12. 17:18
질문:
- OOP 가 뭐야?
- 왜 OOP를 사용하는 거야?
1. OOP (Object Oriented Programming) 정의
- 말 그대로, 객체의 관점에서 프로그래밍하는 것을 의미 (자세히 말하자면 클래스는 설계도고 직접일을 하는 구현체는 인스턴스)
- OOP는 객체를 기준으로 코드를 나누어 구현하는데, JAVA의 경우 그 구성 부분 단위가 클래스.
// Person 클래스 정의 public class Person { // 필드(속성) private String name; private int age; // 생성자 public Person(String name, int age) { this.name = name; this.age = age; } // 메서드 public void introduce() { System.out.println("Hello, my name is " + name + " and I am " + age + " years old."); } // Getter 메서드 public String getName() { return name; } public int getAge() { return age; } } // 객체 생성 및 사용 public class Main { public static void main(String[] args) { Person person1 = new Person("Janku", 30); person1.introduce(); // "Hello, my name is Janku and I am 30 years old." System.out.println("Name: " + person1.getName()); // "Name: Janku" System.out.println("Age: " + person1.getAge()); // "Age: 30" } }
갑작스러운 JAVA예제이지만, 위의 예제를 살펴보면,
1) Person Class 정의
- Person 클래스는 name과 age라는 private 필드 가짐.
- Person 클래스의 생성자 Person(String name, int age)는 객체를 초기화할 때 name과 age를 설정.
- introduce() 메서드는 객체의 정보를 출력.
- getName()과 getAge() 메서드는 private 필드인 name과 age의 값을 외부에서 읽을 수 있게함.
2) 객체 생성 및 사용
- Main 클래스의 main 메서드에서 Person 클래스의 인스턴스인 person1 객체를 생성.
> 이때, 생성자를 호출하여 name을 "John", age를 30으로 초기화. - person1.introduce()를 호출해 Hello, my name is John and I am 30 years old."라는 메시지가 출력.
- person1.getName()과 person1.getAge()를 통해 name과 age의 값을 각각 "John"과 30으로 출력합니다.
2. OOP 사용 이유
- 기존 C 언어들은 절차 지향
- 절차 지향으로 해당 코드를 다시 작성하면, 아래와 같음
// Person 클래스의 필드(속성) private static String name; private static int age; // Person 객체 생성 및 사용 public class Main { public static void main(String[] args) { // Person 객체의 필드 초기화 name = "John"; age = 30; // introduce() 메서드 호출 introduce(); // "Hello, my name is John and I am 30 years old." // getName()과 getAge() 함수 호출하여 정보 출력 System.out.println("Name: " + getName()); // "Name: John" System.out.println("Age: " + getAge()); // "Age: 30" } // introduce() 함수 정의 public static void introduce() { System.out.println("Hello, my name is " + name + " and I am " + age + " years old."); } // getName() 함수 정의 public static String getName() { return name; } // getAge() 함수 정의 public static int getAge() { return age; } }
- 위의 코드와 같이 절차지향 프로그래밍으로 작성한 경우, 컴파일이나 런타임에 문제는 없음.
- 만약 다른 사람을 넣고 싶으면? (100명 정도) > 사람에 따라 새롭게 작성을 해줘야함 * 100.
- 만약 100명 넣은 코드를 바꿔야하면 ? > 새롭게 작성된 코드를 바꿔야함 * 100
- 이 말은, 해당 코드는 재사용이 불가 & 유지 보수 최악 의미.
- OOP를 사용하면, 이런 행위를 최소한으로 할 수 있음
... 생략 ... Person person1 = new Person("Janku", 30); person1.introduce(); // "Hello, my name is Janku and I am 30 years old." Person person2 = new Person("Jason", 12); person1.introduce(); // "Hello, my name is Jason and I am 12 years old." ... 생략 ...
3. OOP 특징
1) 캡슐화, Encapsulation : 객체의 데이터와 메서드를 묶음 (데이터와 메서드를 객체 하나로 묶고, 외부에서 직접 접근을 제어)
- 캡슐화는 데이터와 그 데이터를 처리하는 메서드를 하나로 묶음
- 이를 통해 객체의 내부 구현을 외부로부터 감추고 객체 간의 상호 작용은 정의된 인터페이스를 통해서만 가능.
public class Person { private String name; private int age; // 생성자 public Person(String name, int age) { this.name = name; this.age = age; } // Getter 메서드 public String getName() { return name; } public int getAge() { return age; } // Setter 메서드 (내부 데이터 변경을 허용하는 경우) public void setAge(int age) { if (age >= 0) { this.age = age; } } } // 위의 예제에서 Person 클래스는 name과 age라는 필드를 private으로 선언하여 외부에서 직접 접근 불가 // 대신에 getName()과 getAge() 메서드를 통해 외부에서 필드 값을 읽음. // 이렇게 하면 내부 데이터에 대한 접근을 제어하고, 데이터 유효성을 보장.
2) 은닉화, Information hiding : 필요한 녀석만 보기
- 은닉화는 캡슐화의 목표로, 객체의 내부 구현 세부 사항을 외부로부터 숨기는 것을 의미.
- 객체의 내부 상태는 private으로 선언하고, 외부에서 접근 가능한 메서드를 통해 데이터에 접근.
public class BankAccount { private double balance; // 은행 계좌 잔액 // 입금 메서드 public void deposit(double amount) { if (amount > 0) { balance += amount; } } // 출금 메서드 public void withdraw(double amount) { if (amount > 0 && balance >= amount) { balance -= amount; } } // 잔액 조회 메서드 public double getBalance() { return balance; } } // 위의 예제에서 BankAccount 클래스는 balance 필드를 private으로 선언하여 외부에서 직접 접근 불가. // 대신에 deposit(), withdraw(), getBalance() 메서드를 통해 입금, 출금, 잔액 조회 기능을 제공. // 이렇게 하면 잔액을 직접 조작하는 것을 외부로부터 숨김.
3) 상속, Inheritance : 재정의
- 상속은 기존 클래스(부모 클래스)의 속성과 메서드를 그대로 물려받아 새로운 클래스(자식 클래스)를 생성.
- 자식 클래스는 부모 클래스의 기능을 확장하거나 수정하여 재사용.
public class Animal { public void makeSound() { System.out.println("Animal sound"); } } public class Dog extends Animal { @Override public void makeSound() { System.out.println("Bark bark!"); } } // 위의 예제에서 Animal 클래스는 makeSound() 메서드 지님. // Dog 클래스는 Animal 클래스를 상속받았으며, makeSound() 메서드를 재정의하여 "Bark bark!"를 출력.
4) 추상화, Abstraction: 공통된 속성이나 기능을 묶음 (현실 세계의 개념을 간추려서 모델링하고 클래스로 표현)
- 추상화는 공통의 속성이나 기능을 묶어 이름을 붙이는 것을 의미.
- 추상화를 통해 객체의 중요한 특징에만 초점을 맞추고 불필요한 세부 사항을 숨김.
public abstract class Shape { public abstract double calculateArea(); } public class Circle extends Shape { private double radius; public Circle(double radius) { this.radius = radius; } @Override public double calculateArea() { return Math.PI * radius * radius; } } // 위의 예제에서 Shape 클래스는 도형의 추상적인 개념을 나타내며, calculateArea() 메서드를 추상 메서드로 선언. // Circle 클래스는 Shape 클래스를 상속받아 원의 면적을 구하는 기능을 구현.
5) 다형성, Polymorphism: 딴말하기 (Overload & Override)
- 다형성은 같은 이름의 메서드가 서로 다른 클래스에서 다르게 동작.
- 다형성을 통해 코드의 유연성과 재사용성을 높임.
public class Animal { public void makeSound() { System.out.println("Animal sound"); } } public class Dog extends Animal { @Override public void makeSound() { System.out.println("Bark bark!"); } } public class Cat extends Animal { @Override public void makeSound() { System.out.println("Meow!"); } } // 위의 예제에서 Animal 클래스의 makeSound() 메서드는 Dog 클래스와 Cat 클래스에서 각각 다르게 재정의되어 동작. // 이렇게 하면 동일한 메서드 이름으로 다양한 객체를 처리 가능
답변
- OOP 가 뭐야?
- OOP는 객체지향-프로그래밍으로 현실 세계를 추상화하여 데이터와 해당 데이터를 처리하는 메서드를 하나의 객체로 묶은 기법
- 좀 더 쉽게, 객체 위주로 (객체를 만들어) 코드를 짜는 기법 - 왜 OOP를 사용하는 거야?
- 조금 복잡하더라도, 한번 제대로 짜두면 높은 재사용성과 유지보수 측면에서 이득 !
'> 기초 > 백그라운드' 카테고리의 다른 글
TIL-2024.04.18 - Basic - Origin & Site (보험) (0) 2024.04.18 TIL-2024.04.17 - Basic - JWT - 1.5 - Token, XSS & CSRF (Refresh Token & Access Token 저장 위치) (0) 2024.04.17 TIL-2024.04.16 - Basic - JWT (JSON Web Token) (0) 2024.04.16 TIL-2024.04.11 - Basic - SOLID (0) 2024.04.11 TIL-2024.04.01 - Network - TCP & UDP (0) 2024.04.01