일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 이것이 자바다
- 트리 지름 구하기
- 채팅GPT
- Java
- ArrayList 개념
- 이것이 자바다 확인문제
- 이노캠
- 이것이 자바다 연습문제
- 백준
- 3장 확인문제
- JAVA 기초
- BFS
- 자바
- dfs
- 조건문과 반복문
- 이노베이션 캠프
- Comparable과 Comparable
- 객체지향
- 이노베이션캠프 동북
- 이것이 자바다 13장
- 웹개발 기본지식
- 인프런
- Til
- 스프링 입문강의
- 자료구조
- 자바 언어 기초
- ChatGPT
- 자바의 정석 6장
- 이노베이션캠프
- 챗GPT 명령어 작성팁
- Today
- Total
기록공간
[JAVA] 객체 지향 프로그래밍 (OOP)의 5가지 핵심특징 본문
객체 지향 프로그래밍이란?
컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메세지를 주고받고, 데이터를 처리할 수 있다.
객체지향 프로그래밍의 5가지 특징
개요
1. 다형성 (Polymorphism)
2. 상속 (Inheritance)
3. 캡슐화 (Encapsulation)
4. 추상화 (Abstraction)
5. 은닉화 (Information Hiding)
객체지향 프로그래밍의 특징
1. 다형성
다형성이란, 하나의 인터페이스나 클래스를 다양한 형태로 구현할 수 있다는 것을 의미한다.
이를 통해, 코드의 유연성과 확장성을 높일 수 있다.
이해를 돕기위해 실세계와 비유해서 그림으로 표현하면 아래와같다.
운전자(클라이언트)는 자동차 (인터페이스)의 기능을 수행하는 K3 혹은 아반떼를 탈 수 있을것이다.
이때, 자동차는 자바에서 인터페이스 역할을하고, K3 혹은 아반떼는 이러한 자동차를 구현한 구현체 역할을 한다.
운전자, 자동차 = 역할
K3, 아반떼 , 테슬라 모델 = 인터페이스를 구현한 클래스 혹은 구현 객체를 의미한다.
이처럼, 객체를 설계할 때, 역할(인터페이스)를 먼저 부여하고, 그 역할을 수행하는 구현객체를 "Extends" 키워드를 사용해 만들어야한다.
해당 내용을 코드로 표현하자면 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
// Car 인터페이스
public interface Car {
void startEngine();
void stopEngine();
void accelerate();
void brake();
}
// Avante 클래스
public class Avante implements Car {
@Override
public void startEngine() {
System.out.println("아반떼 엔진이 켜졌습니다.");
}
@Override
public void stopEngine() {
System.out.println("아반떼 엔진이 꺼졌습니다.");
}
@Override
public void accelerate() {
System.out.println("아반떼가 가속하고 있습니다.");
}
@Override
public void brake() {
System.out.println("아반떼가 브레이크를 밟았습니다.");
}
}
// Tesla 클래스
public class Tesla implements Car {
@Override
public void startEngine() {
System.out.println("테슬라 엔진이 켜졌습니다.");
}
@Override
public void stopEngine() {
System.out.println("테슬라 엔진이 꺼졌습니다.");
}
@Override
public void accelerate() {
System.out.println("테슬라가 가속하고 있습니다.");
}
@Override
public void brake() {
System.out.println("테슬라가 브레이크를 밟았습니다.");
}
}
public class Main {
public static void main(String[] args) {
Car avante = new Avante();
Car tesla = new Tesla();
avante.startEngine();
avante.accelerate();
avante.brake();
avante.stopEngine();
tesla.startEngine();
tesla.accelerate();
tesla.brake();
tesla.stopEngine();
}
}
|
cs |
2)캡슐화
두번째의 특징으로는 캡슐화가 있다.
쉽게말해서, 속성과 행위를 하나의 클래스로 묶어서 관리하는것이다.
이를 통해, 외부에서 객체의 내부 구조에 직접 접근하지 못하게하고, 메서드를 통해 상태를 변경하거나 값을 얻을 수 있도록한다.
쉬운 이해를 돕기위해, 다음 예시를 봐보자.
사람이라는 객체를 만든다고 생각해보자. 사람의 특징(속성)으로, 이름과 나이가 있을 것이다.
아래 예제를 통해 자세히 살펴보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
public class Person {
private String name;
private int age;
// 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// name의 getter 메소드
public String getName() {
return name;
}
// name의 setter 메소드
public void setName(String name) {
this.name = name;
}
// age의 getter 메소드
public int getAge() {
return age;
}
// age의 setter 메소드
public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
System.out.println("나이는 0 이상이어야 합니다.");
}
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("John", 25);
System.out.println("이름: " + person.getName());
System.out.println("나이: " + person.getAge());
person.setName("Jane");
person.setAge(30);
System.out.println("이름: " + person.getName());
System.out.println("나이: " + person.getAge());
}
}
|
cs |
위 코드에서는 Person 클래스에서 name과 age 속성을 private 접근 제한자를 사용해, 외부에서 접근할 수 없도록 설정하였다.
즉, 객체를 한번 생성할때, 이름과 age를 한번에 입력받고 생성을 한번하면, 그다음 직접적인 접근으로 값을 바꿀수없다.
person.name ="Jane" 이런 식으로 말이다.
하지만, Getter 및 Setter 메소드를 통해 간접적으로 해당 객체의 속성에 접근할 수 있도록하여, 캡슐화를 구현하였다.
이를 통해 객체의 내부 상태를 보호하고, 필요한 경우에만 값을 변경할 수 있도록 할 수 있다.
3) 추상화
추상화를 통해 프로그램의 복잡성을 줄이고, 관련된 기능과 속성을 그룹화하여 코드의 재사용성을 높일 수 있다. 자바에서 추상화를 구현하는 방법 중 하나는 추상 클래스와 인터페이스를 사용하는 것이다.
이해를 돕기위해, 도형의 추상클래스를 정의하고, 이를 구현하는 Circle과 Rectangle 클래스를 구현한 것을 보여준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
// 도형 추상 클래스
abstract class Shape {
abstract double getArea(); // 면적을 구하는 추상 메소드
abstract double getPerimeter(); // 둘레를 구하는 추상 메소드
}
// 원 클래스
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
double getArea() {
return Math.PI * radius * radius;
}
@Override
double getPerimeter() {
return 2 * Math.PI * radius;
}
}
// 사각형 클래스
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
double getArea() {
return width * height;
}
@Override
double getPerimeter() {
return 2 * (width + height);
}
}
public class Main {
public static void main(String[] args) {
Shape circle = new Circle(5);
Shape rectangle = new Rectangle(4, 6);
System.out.println("원의 면적: " + circle.getArea());
System.out.println("원의 둘레: " + circle.getPerimeter());
System.out.println("사각형의 면적: " + rectangle.getArea());
System.out.println("사각형의 둘레: " + rectangle.getPerimeter());
}
}
|
cs |
위 코드에서는 `Shape` 추상 클래스는 도형의 공통적인 특성인 면적과 둘레를 구하는 메소드를 추상화하였다. 이후 `Circle`과 `Rectangle` 클래스는 각각 `Shape` 추상 클래스를 상속받아 해당 메소드를 구체화하였다. 이렇게 추상화를 통해 도형의 공통적인 특성을 그룹화하고, 각 도형에 맞게 구체화하여 코드의 재사용성을 높였다.
4) 상속
상속은 기존 클래스의 속성과 메소드를 새로운 클래스에 전달하는 과정이다. 자바에서 상속을 구현할 때는 `extends` 키워드를 사용한다. 상속은 기본적으로 클래스 간의 관계를 구축하고, 하위 클래스가 상위 클래스의 기능을 확장하거나 수정할 수 있게 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
// 동물 클래스
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + "이(가) 먹이를 먹습니다.");
}
public void sleep() {
System.out.println(name + "이(가) 잠을 잡니다.");
}
}
// 포유류 클래스
class Mammal extends Animal {
public Mammal(String name) {
super(name);
}
public void giveBirth() {
System.out.println("새끼를 낳습니다.");
}
}
// 고양이 클래스
class Cat extends Mammal {
public Cat(String name) {
super(name);
}
public void meow() {
System.out.println("야옹~");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat("고양이");
cat.eat(); // 상속받은 메소드
cat.sleep(); // 상속받은 메소드
cat.giveBirth(); // 상속받은 메소드
cat.meow(); // 고양이 클래스의 메소드
}
}
|
cs |
위 코드에서 `Animal` 클래스는 동물의 기본적인 행동인 먹기와 자기를 정의하였다.
`Mammal` 클래스는 `Animal` 클래스를 상속받아 기존의 행동에 추가로 새끼를 낳는 행동을 정의하였다.
마지막으로 `Cat` 클래스는 `Mammal` 클래스를 상속받아 기존의 행동에 추가로 야옹하는 행동을 정의하였다.
5) 은닉화
은닉화(Encapsulation)는 클래스의 속성과 메소드를 외부로부터 보호하고, 접근을 제한하는 과정이다.
은닉화를 통해 클래스의 내부 구현을 숨기고, 외부에서는 해당 클래스의 기능만 사용할 수 있도록 한다.
이를 통해 코드의 안정성을 높이고 유지 보수를 용이하게 한다.
자바에서 은닉화를 구현하기 위해 접근 제어자(Access Modifiers)를 사용한다. 접근 제어자에는 `private`, `protected`, `public` 등이 있습니다.
아래는 이해를 돕기 위한 예시 코드이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
// BankAccount 클래스 정의
class BankAccount {
// private 접근 제어자를 사용하여 외부로부터 보호되는 속성들
private String accountNumber;
private double balance;
// 생성자: 계좌 번호와 초기 잔액을 받아 객체를 생성
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
// 예금 메소드: 금액을 받아 잔액에 더함
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
} else {
System.out.println("예금액은 양수여야 합니다.");
}
}
// 인출 메소드: 금액을 받아 잔액에서 뺌
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
} else {
System.out.println("인출액은 양수이며, 잔액보다 작아야 합니다.");
}
}
// 잔액 조회 메소드: 현재 잔액을 반환
public double getBalance() {
return balance;
}
}
// Main 클래스 정의
public class Main {
// 메인 메소드: 프로그램 실행 시작점
public static void main(String[] args) {
// BankAccount 객체 생성 및 초기화
BankAccount account = new BankAccount("123456", 1000);
// 예금 메소드 호출
account.deposit(500);
// 인출 메소드 호출
account.withdraw(200);
// 잔액 출력
System.out.println("잔액: " + account.getBalance());
}
}
|
cs |
위 코드에서 `BankAccount` 클래스는 계좌 번호와 잔액을 `private` 접근 제어자를 사용하여 외부로부터 보호하고 있다. 이를 통해 외부에서 직접 접근할 수 없으며, 클래스 내부에서 정의된 메소드를 통해서만 값을 변경하거나 조회할 수 있다. 이렇게 은닉화를 통해 클래스의 내부 구현을 숨기고, 외부에서는 해당 클래스의 기능만 사용할 수 있도록 한다.
'JAVA & Spring' 카테고리의 다른 글
[JAVA] 이것이 자바다 13장 연습문제 (제네릭) (0) | 2023.04.03 |
---|---|
[JAVA] 이것이 자바다 11장 연습문제 (예외 처리) (0) | 2023.03.28 |
[Java] Comparable, Comparator 인터페이스의 이해와 사용 방법 (0) | 2023.03.16 |
[JAVA] 이것이 자바다 9장 확인 문제 (중첩 선언과 익명 객체 ) (0) | 2023.01.08 |
[JAVA] 이것이 자바다 8장 확인 문제 (인터페이스) (0) | 2023.01.05 |