[Java] 객체지향 정리
객체지향
객체지향 모델의 특징 및 객체지향 언어의 장점
Object Oriented Programming languages are defined by the following key words: abstraction, encapsulation, inheritance, and polymorphism
1. 캡슐화 : encapsulation
- 관련된 데이터와 알고리즘(코드)이 하나의 묶음으로 정리된 것으로써 개발자가 만들었으며, 관련된 코드와 데이터가 묶여있고 오류가 없어 사용이 편리하다.
- 데이터를 숨기고 외부 세계와의 상호작용은 필드와 메소드를 통하는 방법
- 스스로 동작하며 외부에 의존하지 않는다.
- 메소드:
- 메시지에 따라 실행시킬 프로시저로서 객체지향 언어에서 사용되는 것.
- 객체지향 언어에서는 메시지를 보내 메소드를 수행시킴으로써 통신(communication)을 수행
-
라이브러리로 만들어 업그레이드하면 쉽게 바꿀 수 있다.
- 예시 코드
public class BankAccount { private String accountNumber; private double balance; public BankAccount(String accountNumber, double balance) { this.accountNumber = accountNumber; this.balance = balance; } public String getAccountNumber() { return accountNumber; } // setter public void setAccountNumber(String accountNumber) { this.accountNumber = accountNumber; } // getter public double getBalance() { return balance; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) { if (balance >= amount) { balance -= amount; } else { System.out.println("Insufficient funds."); } } }
-
BankAccount
클래스에는accountNumber
와balance
라는 두 개의private
인스턴스 변수가 있는데, 이러한private
변수는 클래스 외부에서 직접 액세스할 수 없다. - 이러한
private
변수에 대한 제어된 액세스를 제공하기 위해, 클래스는accountNumber
및balance
에 대한getter
및setter
메서드를 가지고 있다.getAccountNumber
메서드는 계좌 번호를 반환하며,setAccountNumber
메서드는 계좌 번호를 변경할 수 있다.getBalance
메서드는 계좌 잔액을 반환한다.
- 클래스에는 계좌에서 돈을 입금하고 출금하는 두 가지 메서드가 있고, 클래스 외부에서 액세스할 수 있다.
private
변수는 클래스 외부에서 숨겨지며, 클래스가 제공하는 공개 메서드를 통해서만 액세스할 수 있다. 이는 데이터를 보호하고 외부 코드에서 데이터를 수정하거나 손상시키는 것을 방지하여 안정성을 향상시키는 데 도움이 된다.
2. 상속 inheritance
- 상속은 이미 작성된 클래스를 이어 받아서 새로운 클래스를 생성하는 기법으로 위에서 말한 기존 코드를 재활용해서 사용하는 것을 의미한다.
- 객체지향 방법의 큰 장점중 하나이다.
+----------------+
| Animal |
+----------------+
| - name: String |
| - age: int |
+----------------+
| + eat(): void |
| + sleep(): void|
| + move(): void |
+----------------+
^
|
+-------+-------+
| |
| Dog |
| |
+---------------+
| + bark(): void|
+---------------+
- 위 클래스 다이어그램에서,
Animal
클래스는Dog
클래스의 슈퍼 클래스이다. Animal
클래스는name
과age
라는 두 개의private
인스턴스 변수와eat()
,sleep()
,move()
라는 세 개의public
메서드를 가지고 있다.Dog
클래스는bark()
라는 새로운public
메서드를 추가해Animal
클래스를 상속한다.Animal
클래스의name
과age
변수가private
으로 선언되어 있기 때문에Dog
클래스는Animal
클래스에서 상속 받은 메서드를 통해 이 변수들에 접근한다. (getter, setter
)
3. 다형성 polymorphism
- 하나의 이름(방법)으로 많은 상황에 대처하는 것을 뜻한다.
- 동일한 작업을 하는 함수들에 똑같은 이름을 부여할 수 있으므로 코드가 더 간단해지는 효과가 있다.
class Helper {
// Method with 2 integer parameters
static int Multiply(int a, int b)
{
// Returns product of integer numbers
return a * b;
}
// Method 2
// With same name but with 2 double parameters
static double Multiply(double a, double b)
{
// Returns product of double numbers
return a * b;
}
}
- 위 코드는 같은 이름을 가지고 있으나 메소드의 인자가 정수형인지 실수형인지 여부에 따라 (데이터 타입에 의거해) 다르게 작동한다. (Compile-time Polymorphism)
class Parent {
// Method of parent class
void Print()
{
// Print statement
System.out.println("parent class");
}
}
// Class 2
// Helper class
class subclass1 extends Parent {
// Method
void Print() { System.out.println("subclass1"); }
}
// Class 3
// Helper class
class subclass2 extends Parent {
// Method
void Print()
{
// Print statement
System.out.println("subclass2");
}
}
}
- 위 코드는 메소드 오버라이딩을 수행한다. (Runtime polymorphism)
- 추상화
- 객체를 단순화하고 필수적인 특징들만을 추려내어 표현해, 객체를 더욱 쉽게 이해하고 사용하기 쉽게 만든다.
- 객체의 상세 구현을 숨겨, 외부에서 해당 객체를 사용할 때에는 구현의 복잡성을 신경 쓰지 않고 객체의 핵심적인 특징과 기능에만 집중할 수 있다. => 유지보수성과 코드 재사용성이 높아짐
abstract class Shape {
String color;
// these are abstract methods
abstract double area();
public abstract String toString();
// abstract class can have the constructor
public Shape(String color)
{
System.out.println("Shape constructor called");
this.color = color;
}
// this is a concrete method
public String getColor() { return color; }
}
class Circle extends Shape {
double radius;
public Circle(String color, double radius)
{
// calling Shape constructor
super(color);
System.out.println("Circle constructor called");
this.radius = radius;
}
@Override double area()
{
return Math.PI * Math.pow(radius, 2);
}
@Override public String toString()
{
return "Circle color is " + super.getColor()
+ "and area is : " + area();
}
}
class Rectangle extends Shape {
double length;
double width;
public Rectangle(String color, double length,
double width)
{
// calling Shape constructor
super(color);
System.out.println("Rectangle constructor called");
this.length = length;
this.width = width;
}
@Override double area() { return length * width; }
@Override public String toString()
{
return "Rectangle color is " + super.getColor()
+ "and area is : " + area();
}
}
Shape
클래스는 추상 클래스이므로, 객체를 직접 생성할 수 없다.- 추상 메소드
area()
와toString()
을 가지고 있으며, 구현되지 않은 메소드로 이를 상속받은 구체 클래스에서 구현해야 한다.
- 추상 메소드
Circle
클래스와Rectangle
클래스에서는area()
와toString()
메소드를 각각 구현하여, 해당 도형의 면적과 문자열 표현을 반환한다.Shape
클래스에서 추상적으로 선언한 메소드를 구체적으로 구현할 수 있다.
위의 특성들로 인해 생기는 객체지향 방법의 장점은 다음과 같다:
- 신뢰성 있는 소프트웨어를 쉽게 작성할 수 있다. (개발자가 만든 데이터를 사용하기에 신뢰할 수 있다.)
- 코드를 재사용하기 쉽다.
- 업그레이드가 쉽다.
- 디버깅이 쉽다.
5원칙(SOLID)
SOLID 원칙은 객체지향 설계에서 적용할 수 있는 가이드라인으로, 유지보수성, 확장성, 재사용성을 높일 수 있는 중요한 원칙이다.
- 단일 책임 원칙 (Single Responsibility Principle)
- 클래스는 단 하나의 책임만을 가져야 한다.
- 한 클래스가 너무 많은 일을 하게 되면, 클래스의 변경이 불안정해지고, 재사용성이 낮아지며, 유지보수가 어려워질 수 있다.
- 개방-폐쇄 원칙 (Open/Closed Principle)
- 확장에는 열려 있으나 수정에는 닫혀 있어야 한다.
- 새로운 기능을 추가할 때는 기존의 코드를 변경하지 않고, 확장을 통해 추가해야 한다.
- 리스코프 치환 원칙 (Liskov Substitution Principle)
- 자식 클래스는 언제나 부모 클래스로 대체할 수 있어야 한다.
- 자식 클래스는 부모 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행하도록 해야 한다.
- 인터페이스 분리 원칙 (Interface Segregation Principle)
- 클라이언트는 자신이 사용하지 않는 인터페이스를 구현해서는 안된다.
- 하나의 일반적인 인터페이스보다 여러개의 구체적인 인터페이스가 낫다.
- 의존 역전 원칙 (Dependency Inversion Principle)
- 고차원 모듈은 저차원 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 한다.
- 인터페이스나 추상 클래스와 같은 추상화를 통해 의존성을 역전시켜야 한다.
객체지향, 절차지향, 함수형 프로그래밍의 차이점
- 객체지향 프로그래밍 (OOP) : 객체를 중심으로 코드를 작성하는 패러다임
- 데이터와 해당 데이터를 처리하는 메서드를 하나의 논리적 단위인 객체로 묶어내는 방식이다.
- 객체 지향 프로그래밍의 주요 특징으로는 캡슐화, 추상화, 상속, 다형성이 있다.
- 절차지향 프로그래밍 (Procedural Programming) : 절차를 중심으로 코드를 작성하는 패러다임
- 문제를 일련의 절차로 분해하고 이를 프로그래밍 코드로 표현한다.
- 데이터와 메서드는 서로 분리되어 있으며, 함수를 이용하여 처리한다.
- 함수형 프로그래밍 (Functional Programming) : 함수를 중심으로 코드를 작성하는 패러다임
- 입력값과 출력값 간의 관계를 함수로 정의하고 이를 조합하여 프로그램을 작성한다.
- 상태를 변경하는 것이 불가능하며, 함수의 반환값만으로 결과를 예측할 수 있다.
Leave a comment