ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ฏ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ(Object-Oriented Programming, OOP)์ ์ํํธ์จ์ด๋ฅผ ๊ฐ์ฒด ๋จ์๋ก ๊ตฌ์ฑํ๊ณ , ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๋ฅผ ์ ์ํ์ฌ ํ๋ก๊ทธ๋๋ฐํ๋ ๋ฐฉ์์ผ๋ก, ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ ๋์ด๊ณ ์ฝ๋๋ฅผ ๋ ์ง๊ด์ ์ด๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๊ฒ ๋ง๋ ๋ค.
ํด๋์ค : ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํ ํ(์ค๊ณ๋)
๊ฐ์ฒด: ํด๋์ค์์ ์์ฑ๋ ์ค์ฒด(Instance)๋ก, ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น๋์ด ์ค์ ๋์ํ๋ ๋จ์
ํด๋์ค | ๊ฐ์ฒด | |
์ ์ | ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํ | ํด๋์ค์์ ์์ฑ๋ ์ค์ฒด |
๋ฉ๋ชจ๋ฆฌ | ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น๋์ง ์์ | ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น๋จ |
์ญํ | ์์ฑ๊ณผ ๋์์ ์ ์ | ์์ฑ๊ณผ ๋์์ ์ค์ ๋ก ๊ฐ์ง |
์์ | Car ํด๋์ค | myCar = new Car("Hyundai", 100); |
๊ทธ๋ฆฌ๊ณ ๊ฐ์ฒด์ ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ง์กฑํ๋ค.
- ํด๋์ค๋ฅผ ๋จผ์ ์ ์ํ ํ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผ ํจ
- ํด๋์ค ํ๋๋ก ์ฌ๋ฌ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์
- ๊ฐ์ฒด๋ ํด๋์ค์์ ์ ์ํ ์์ฑ๊ณผ ๋ฉ์๋๋ฅผ ๊ฐ์ง
class Dog {
String name;
Dog(String name) {
this.name = name;
}
void bark() {
System.out.println(name + "๊ฐ ๋ฉ๋ฉ ์ง๋๋ค");
}
}
public class Main {
public static void main(String[] args) {
Dog dog1 = new Dog("๋ฐ๋์ด");
Dog dog2 = new Dog("์ฝ์ฝ");
dog1.bark(); // ๋ฐ๋์ด๊ฐ ๋ฉ๋ฉ ์ง๋๋ค
dog2.bark(); // ์ฝ์ฝ๊ฐ ๋ฉ๋ฉ ์ง๋๋ค
}
}
๐ฏ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ 4๊ฐ์ง ํน์ง
1๏ธโฃ ์บก์ํ(Encapsulation)
๊ฐ์ฒด์ ์์ฑ๊ณผ ํ๋์ ํ๋๋ก ๋ฌถ๊ณ ์ธ๋ถ์์ ์ง์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ๋ณดํธํ๋ ๊ธฐ๋ฒ์ผ๋ก, ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ๊ณ , ์ฝ๋ ๋ณ๊ฒฝ ์ ์ํฅ์ ์ต์ํํ ์ ์๋ค.
private ์ ๊ทผ ์ ์ด์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ์๋ ํ, getter/setter๋ฅผ ์ ๊ณตํ๋ค.
๋ค์ ์ฝ๋์์๋ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๋ฉด์, deposit()๊ณผ withdraw() ๋ฉ์๋๋ฅผ ํตํด์๋ง ์ ๊ทผํ ์ ์๋๋ก ํ๋ค.
class BankAccount {
private double balance; // ๊ณ์ข ์์ก (private์ผ๋ก ๋ณดํธ)
public BankAccount(double balance) {
this.balance = balance;
}
// getter
public double getBalance() {
return balance;
}
// setter (์์ ํ ์
์ถ๊ธ์ ์ํด)
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
}
}
}
public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount(1000);
account.deposit(500);
account.withdraw(300);
System.out.println(account.getBalance()); // 1200.0
}
}
2๏ธโฃ ์์(Inheritance)
๋ถ๋ชจ ํด๋์ค์ ์์ฑ๊ณผ ๋ฉ์๋๋ฅผ ์์ ํด๋์ค๊ฐ ๋ฌผ๋ ค๋ฐ์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ธฐ๋ฅ์ด๋ค.
extends ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ชจ ํด๋์ค๋ฅผ ์์ํ ์ ์๋ค.
๋ค์ ์ฝ๋์์๋ Dog ํด๋์ค๊ฐ Animal ํด๋์ค๋ฅผ ์์๋ฐ์ makeSound()๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
class Animal {
void makeSound() {
System.out.println("๊ฐ์ฅ๊ฐ ์๋ฆฌ๋ฅผ ๋
๋๋ค.");
}
}
class Dog extends Animal {
void bark() {
System.out.println("๋ฉ๋ฉ!");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.makeSound(); // ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋ ์ฌ์ฉ
dog.bark(); // ์์ ํด๋์ค์ ๋ฉ์๋ ์ฌ์ฉ
}
}
3๏ธโฃ ๋คํ์ฑ(Polymorphism)
ํ๋์ ๋ฉ์๋๋ ๊ฐ์ฒด๊ฐ ๋ค์ํ ํํ๋ก ๋์ํ ์ ์๋๋ก ํ๋ ๊ธฐ๋ฅ์ด๋ค.
์ฝ๋์ ์ ์ฐ์ฑ์ ์ฆ๊ฐ์ํค๊ณ , ๊ฐ์ฒด ๊ต์ฒด๊ฐ ์ฉ์ดํ๋ฉฐ ๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ(Overloading), ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ(Overriding)์ ์ฌ์ฉํ๋ฉด ๋๋ค.
๋ค์ ์ฝ๋๋ Animal ํ์ ๋ณ์์ Cat ๊ฐ์ฒด๋ฅผ ๋ฃ์์ง๋ง, makeSound()๊ฐ Cat ํด๋์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ์ด ์ ์ฉ๋ ๊ฒ์ด๋ค.
class Animal {
void makeSound() {
System.out.println("๋ฅ์ด๊ฐ ์๋ฆฌ๋ฅผ ๋
๋๋ค.");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("์ผ์น!");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Cat(); // ๋คํ์ฑ ์ ์ฉ
myAnimal.makeSound(); // "์ผ์น!" ์ถ๋ ฅ (Cat์ ๋ฉ์๋ ํธ์ถ)
}
}
4๏ธโฃ ์ถ์ํ(Abstraction)
๋ถํ์ํ ์ธ๋ถ์ ๋ณด๋ฅผ ์จ๊ธฐ๊ณ ํ์ํ ์ ๋ณด๋ง์ ๋๋ฌ๋ด๋ ๊ฒ์ ๋งํ๋ค.
abstract ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ถ์ ํด๋์ค ๋ฐ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๋ค.
abstract class Animal {
abstract void makeSound(); // ์ถ์ ๋ฉ์๋ (๊ตฌํ X)
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("๋ฉ๋ฉ!");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.makeSound(); // "๋ฉ๋ฉ!" ์ถ๋ ฅ
}
}
๐ฏ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ 5๊ฐ์ง ์์น
SOLID ์์น์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ ๋์ด๊ธฐ ์ํ 5๊ฐ์ง ์ค๊ณ ์์น์ด๋ค.
์ด ์์น์ ๋ฐ๋ฅด๋ฉด ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ ์์ง๋๋ฅผ ๋์ฌ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํ ์ฝ๋๋ฅผ ๋ง๋ค ์ ์๋ค.
1๏ธโฃ ๋จ์ผ ์ฑ ์ ์์น (SRP: Single Responsibility Principle)
ํด๋์ค๋ ๋จ ํ๋์ ์ฑ
์๋ง ๊ฐ์ ธ์ผ ํ๋ค.
ํ๋์ ํด๋์ค๋ ํ๋์ ์ญํ ๋ง ๋ด๋นํด์ผ ํ๋ฉฐ, ๋ณ๊ฒฝ์ด ํ์ํ ์ด์ ๋ ํ๋๋ง ์กด์ฌํด์ผ ํ๋ค.
๋ค์์ SRP์์น์ ์๋ฐํ ์์์ด๋ค.
ReportManager ํด๋์ค๊ฐ ๋ณด๊ณ ์ ์์ฑ, ์ถ๋ ฅ, ์ ์ฅ๊น์ง ๋ชจ๋ ์ฑ ์์ ๊ฐ์ง๊ณ ์์ด ์ ์ง๋ณด์๊ฐ ์ด๋ ค์ธ ์ ์๋ค.
class ReportManager {
public void generateReport() {
// ๋ณด๊ณ ์ ์์ฑ ๋ก์ง
}
public void printReport() {
// ๋ณด๊ณ ์ ์ถ๋ ฅ ๋ก์ง (ํ๋ฆฐํฐ ๊ด๋ จ)
}
public void saveToFile() {
// ํ์ผ ์ ์ฅ ๋ก์ง
}
}
๋ค์์ฒ๋ผ ๊ฐ ํด๋์ค๊ฐ ํ๋์ ์ญํ (์ฑ ์)๋ง ์ํํ๋๋ก ๋ถ๋ฆฌํ ๋ SRP๋ฅผ ๋ง์กฑํ๊ฒ ๋๋ค.
class ReportGenerator {
public void generateReport() {
// ๋ณด๊ณ ์ ์์ฑ ๋ก์ง
}
}
class ReportPrinter {
public void printReport() {
// ๋ณด๊ณ ์ ์ถ๋ ฅ ๋ก์ง
}
}
class ReportSaver {
public void saveToFile() {
// ํ์ผ ์ ์ฅ ๋ก์ง
}
}
2๏ธโฃ ๊ฐ๋ฐฉ-ํ์ ์์น (OCP: Open-Closed Principle)
์ํํธ์จ์ด ์์๋ ํ์ฅ์๋ ์ด๋ ค ์์ด์ผ ํ๊ณ , ์์ ์๋ ๋ซํ ์์ด์ผ ํ๋ค.
์ฆ, ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ๋ ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์๋๋ก ์ค๊ณํด์ผ ํจ์ ์๋ฏธํ๋ค.
๋ค์์ OCP๋ฅผ ์๋ฐํ ์์์ด๋ค.
๊ฒฐ์ ๋ฐฉ์์ด ์ถ๊ฐ๋ ๋๋ง๋ค if-else๋ฌธ์ ์์ ํด์ผ ํ๋ฏ๋ก ์์ ์ด ์์ฃผ ์ผ์ด๋๊ฒ ๋๋ค.
class PaymentProcessor {
public void processPayment(String type) {
if (type.equals("creditCard")) {
System.out.println("Processing credit card payment");
} else if (type.equals("paypal")) {
System.out.println("Processing PayPal payment");
}
}
}
ํ์ง๋ง ๋ค์์ฒ๋ผ ์์ ํ๋ฉด ์๋ก์ด ๊ฒฐ์ ๋ฐฉ์์ด ์ถ๊ฐ๋์ด๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ์ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ฉฐ ํ์ฅ์ด ๊ฐ๋ฅํ๋ค.
interface Payment {
void pay();
}
class CreditCardPayment implements Payment {
public void pay() {
System.out.println("Processing credit card payment");
}
}
class PayPalPayment implements Payment {
public void pay() {
System.out.println("Processing PayPal payment");
}
}
class PaymentProcessor {
public void processPayment(Payment payment) {
payment.pay();
}
}
3๏ธโฃ ๋ฆฌ์ค์ฝํ ์นํ ์์น (LSP: Liskov Substitution Principle)
์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์ฒดํ ์ ์์ด์ผ ํ๋ค.
์ฆ, ๋ถ๋ชจ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๊ณณ์์ ์์ ํด๋์ค๋ฅผ ๋ฃ์ด๋ ์ ์์ ์ผ๋ก ๋์ํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
LSP๋ฅผ ์๋ฐํ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
Rectangle์ ๊ธฐ๋ํ๊ณ Square๋ฅผ ์ฌ์ฉํ์ ๋ ์์๊ณผ ๋ค๋ฅด๊ฒ ๋์ํ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
class Rectangle {
protected int width, height;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public int getArea() {
return width * height;
}
}
class Square extends Rectangle {
@Override
public void setWidth(int width) {
this.width = width;
this.height = width; // ์ ์ฌ๊ฐํ์ ๋๋น์ ๋์ด๊ฐ ๊ฐ์์ผ ํจ
}
@Override
public void setHeight(int height) {
this.width = height;
this.height = height;
}
}
๋ค์๊ณผ ๊ฐ์ด Rectangle๊ณผ Square๋ฅผ Shape ์ธํฐํ์ด์ค๋ก ๋ถ๋ฆฌํ๋ฉด ๋์ฒด ๊ฐ๋ฅ์ฑ์ด ์ ์ง๋๋ฉฐ LSP๋ฅผ ๋ง์กฑํ๊ฒ ๋๋ค.
interface Shape {
int getArea();
}
class Rectangle implements Shape {
protected int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getArea() {
return width * height;
}
}
class Square implements Shape {
private int side;
public Square(int side) {
this.side = side;
}
public int getArea() {
return side * side;
}
}
4๏ธโฃ ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น (ISP: Interface Segregation Principle)
ํด๋ผ์ด์ธํธ๋ ์์ ์ด ์ฌ์ฉํ์ง ์๋ ๋ฉ์๋์ ์์กดํ์ง ์์์ผ ํ๋ค.
์ฆ, ์ธํฐํ์ด์ค๋ฅผ ์ธ๋ถํํ์ฌ ๊ผญ ํ์ํ ๋ฉ์๋๋ง ์ ๊ณตํด์ผ ํจ์ ์๋ฏธํ๋ค.
๋ค์์ ISP ์๋ฐ ์์๋ก Developer๋ eat() ๋ฉ์๋๊ฐ ํ์ ์๋๋ฐ๋ ๊ตฌํํด์ผ ํ๋ค.
interface Worker {
void work();
void eat();
}
class Developer implements Worker {
public void work() {
System.out.println("์ฝ๋ฉ ์ค...");
}
public void eat() {
// ๊ฐ๋ฐ์๋ ์์ฌ๋ฅผ ํ์ง ์์ ์๋ ์์ (๋ถํ์ํ ๋ฉ์๋ ๊ตฌํ)
}
}
๋ค์๊ณผ ๊ฐ์ด ์ธํฐํ์ด์ค๋ฅผ ๋ถ๋ฆฌํด์ฃผ๋ฉด ISP๋ฅผ ๋ง์กฑํ๋ค.
interface Workable {
void work();
}
interface Eatable {
void eat();
}
class Developer implements Workable {
public void work() {
System.out.println("์ฝ๋ฉ ์ค...");
}
}
class Employee implements Workable, Eatable {
public void work() {
System.out.println("์
๋ฌด ์ํ ์ค...");
}
public void eat() {
System.out.println("์ ์ฌ ์์ฌ ์ค...");
}
}
5๏ธโฃ ์์กด ์ญ์ ์์น (DIP: Dependency Inversion Principle)
๊ณ ์์ค ๋ชจ๋์ ์ ์์ค ๋ชจ๋์ ์์กดํ๋ฉด ์ ๋๋ฉฐ ๋ ๋ค ์ถ์ํ์ ์์กดํด์ผ ํ๋ค.
DIP๋ฅผ ์๋ฐํ ์์๋ ๋ค์๊ณผ ๊ฐ๊ณ Application์ด MySQLDatabase์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋์ด ์๋ค.
class MySQLDatabase {
public void connect() {
System.out.println("MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ");
}
}
class Application {
private MySQLDatabase database = new MySQLDatabase(); // ์ง์ ์์กด
public void start() {
database.connect();
}
}
ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ด ์ธํฐํ์ด์ค(Database)์ ์์กดํ๋๋ก ๋ฐ๊พธ๋ฉด DIP๋ฅผ ๋ง์กฑํ๋ค.
interface Database {
void connect();
}
class MySQLDatabase implements Database {
public void connect() {
System.out.println("MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ");
}
}
class Application {
private Database database;
public Application(Database database) {
this.database = database;
}
public void start() {
database.connect();
}
}
'Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JDBC, JDK, JRE, JVM (0) | 2025.02.16 |
---|---|
Java์ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ์ ๊ฐ๋น์ง ์ปฌ๋ ์ (0) | 2025.02.09 |
Java Collections Framework (0) | 2025.01.20 |