Java 객체지향프로그래밍(OOP)

fever·2023년 12월 10일

Java 기초

목록 보기
4/10

⭐️ 객체지향프로그래밍(OOP)

  • 코드를 객체 단위로 구성하여 모듈화하고 재사용성을 높이는 개념.
  • 현실 세계의 개념과 구조를 모델링하여 소프트웨어를 개발하는 방법론.

1. 클래스와 객체

  • 클래스(Class): 객체를 만들기 위한 일종의 틀 또는 설계도로 변수와 메서드를 포함하며, 데이터와 행동을 정의한다.
  • 객체(Object): 클래스의 인스턴스로, 실제로 메모리에 할당되어 사용되는 개체로 각 객체는 고유한 상태를 가지며, 클래스에서 정의된 행동을 수행할 수 있다.
// 클래스 정의
class Car {
    // 멤버 변수 설정
    String brand;
    int year;

    // 생성자 설정
    public Car(String brand, int year) {
        this.brand = brand;
        this.year = year;
    }

    // 메서드 생성 (출력 메서드)
    public void start() {
        System.out.println("The " + year + " " + brand + " is starting.");
    }
}


public class Main {
    public static void main(String[] args) {
        // 객체 생성
        Car myCar = new Car("Toyota", 2022);

        // 객체 메서드 호출
        myCar.start();
    }
}

💻 출력 결과
The 2022 Toyota is starting.

2. 캡슐화(Encapsulation)

  • 데이터와 그 데이터를 다루는 메서드를 하나로 묶는 것으로 객체 내부의 세부 구현은 숨기고, 외부에서는 객체의 인터페이스만을 이용할 수 있게 함.
  • 정보 은닉을 통해 안정성과 유지보수성을 높이기 위해 사용한다.
//사람 클래스 생성
class Person { //클래스에서만 사용할 수 있는 private 변수 사용
    private String name;
    private int age;

    // 생성자 (방법1)
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 게터와 세터 (방법2)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
       this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        // 객체 생성 (방법 1번 사용)
        Person person = new Person("fever", 30);

        // 게터를 통한 정보 반환
        System.out.println("Name: " + person.getName());
        System.out.println("Age: " + person.getAge());

        // 세터를 통한 정보 변경 (방법 2번 사용)
        person.setName("max");
        person.setAge(25);

        // 변경된 정보 출력
        System.out.println("Updated Name: " + person.getName());
        System.out.println("Updated Age: " + person.getAge());
    }
}

💻 방법 1번 출력
Name: fever
Age: 30

💻 방법 2번 출력
Updated Name: fever
Updated Age: 25

3. 상속(Inheritance)

  • 기존 클래스의 특성을 그대로 물려받아 새로운 클래스를 생성하는 개념으로 코드의 재사용성을 증가시키며, 계층 구조를 통해 간결하고 확장 가능한 코드를 작성할 수 있다.
// 부모 클래스 생성
class Animal {
    public void eat() { //부모 메서드 생성
        System.out.println("Animal is eating.");
    }
}

// 자식 클래스 생성 후 부모 클래스 상속
class Dog extends Animal {
    public void bark() { //자식 메서드 생성
        System.out.println("Dog is barking.");
    }
}

public class Main {
    public static void main(String[] args) {
        // 상속을 통한 메서드 호출
        Dog myDog = new Dog();
        myDog.eat();  // 상속된 메서드
        myDog.bark(); // 자식 클래스의 메서드
    }
}

💻 출력 결과
Animal is eating.
Dog is barking.

4. 다형성(Polymorphism)

  • 하나의 인터페이스나 메서드가 여러 형태로 구현될 수 있는 능력.
  • 오버로딩(한 클래스 내에서 메서드 이름은 같지만 매개변수가 다른 경우)과 오버라이딩(하위 클래스에서 상위 클래스의 메서드를 재정의)을 통해 구현.
// 부모 클래스
class Animal {
    public void makeSound() {
        System.out.println("Some generic sound");
    }
}

// 자식 클래스1
class Dog extends Animal {
    @Override
    public void makeSound() { //부모의 메서드를 재정의한 오버라이딩
        System.out.println("Woof! Woof!");
    }

    // 같은 메서드명(makeSound)이지만 매개변수가 다른 오버로딩
    public void makeSound(int times) {
        for (int i = 0; i < times; i++) {
            System.out.print("Woof! Woof! ");
        }
    }
}



public class Main {
    public static void main(String[] args) {
        // 객체 생성
        Dog dog = new Dog();

        dog.makeSound(); // 오버라이딩된 Dog 클래스의 메서드 호출
        dog.makeSound(3); // 오버로딩된 Dog 클래스의 메서드 호출
    }
}

💻 출력 결과
Woof! Woof!
Woof! Woof! Woof! Woof! Woof! Woof!

4. 추상화(Abstraction)

  • 복잡한 시스템에서 핵심적인 개념 또는 기능을 간추려 표현하는 과정.
  • 클래스에서 중요한 특성만을 추출하여 모델링하고, 불필요한 세부 사항을 숨겨 간단하게 표현.
  • 개념을 일반화하여 공통된 특징을 나타내는데 중점.
// 추상 클래스: 자동차 공장
abstract class Car {
    // 공통된 특징
    String brand;
    int year;

    // 추상 메서드: 구체적인 모델에서 구현할 내용
    abstract void start();
    abstract void stop();

    // 공통 메서드
    void honk() {
        System.out.println("출발합니다.");
    }
}

// 구체적인 클래스: 세단
class Sedan extends Car {
    // 추상 메서드 구현
    @Override
    void start() {
        System.out.println("Sedan 출발합니다.");
    }

    @Override
    void stop() {
        System.out.println("Sedan 멈춥니다.");
    }
}

// 구체적인 클래스: SUV
class SUV extends Car {
    // 추상 메서드 구현
    @Override
    void start() {
        System.out.println("SUV 출발합니다. ");
    }

    @Override
    void stop() {
        System.out.println("SUV 멈춥니다.");
    }

    // SUV만의 추가 특징
    void offRoadMode() {
        System.out.println("SUV의 off-road mode를 사용합니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        // 다형성을 통한 추상화 활용
        Car sedanCar = new Sedan();
        Car suvCar = new SUV();

        // 공통 메서드 호출
        sedanCar.honk(); 
        suvCar.honk(); 

        // 추상 메서드 호출
        sedanCar.start();  
        suvCar.start(); 

        // 추가 특징 활용 (부모 클래스로 만들어서 자식 클래스로 다운캐스팅 필요)
        ((SUV) suvCar).offRoadMode(); 
    }
}

💻 출력 결과
출발합니다.
출발합니다.
Sedan 출발합니다.
SUV 출발합니다.
SUV의 off-road mode를 사용합니다.

5. 인터페이스(Interface)

  • 관련된 메서드들의 집합으로, 구현 세부 사항은 제공하지 않고 추상적인 메서드의 정의만을 포함.
  • 다중 상속을 지원하고, 클래스들 간의 표준화된 통신을 가능하게 함.
  • 특정 행위(동작)에 중점을 두어 다양한 객체들이 동일한 행위를 할 수 있도록 사용.
// 인터페이스: 전기 제품이 사용하는 콘센트 형태를 정의
interface Socket {
    void plugIn();
}

// 구현 클래스1: 노트북
class Laptop implements Socket {
    @Override
    public void plugIn() {
        System.out.println("노트북을 연결했습니다.");
    }
}

// 구현 클래스2: 스마트폰
class Smartphone implements Socket {
    @Override
    public void plugIn() {
        System.out.println("스마트폰을 연결했습니다.");
    }
}

// 구현 클래스3: 헤어 드라이어
class HairDryer implements Socket {
    @Override
    public void plugIn() {
        System.out.println("헤어드라이기를 연결했습니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        // 다형성을 통한 인터페이스 활용
        Socket laptopSocket = new Laptop();
        Socket smartphoneSocket = new Smartphone();
        Socket hairDryerSocket = new HairDryer();

        // 각 전기 제품을 콘센트에 연결  (인터페이스는 명시적인 형변환 없이 바로 가능.)
        laptopSocket.plugIn(); 
        smartphoneSocket.plugIn();
        hairDryerSocket.plugIn();
    }
}

💻 출력 결과
노트북을 연결했습니다.
스마트폰을 연결했습니다.
헤어드라이기를 연결했습니다.

profile
선명한 삶을 살기 위하여

0개의 댓글