[JAVA] 객체지향 프로그래밍

yuna·2022년 9월 18일
0

java

목록 보기
1/1

class란?

  • 객체 지향 프로그래밍(OOP, Object-Oriented Programming)은 모든 데이터를 객체(object)로 취급
  • 클래스(class)란 객체를 정의하는 틀 또는 설계도와 같은 의미 05-02 클래스 - 점프 투 자바 (wikidocs.net)
  • 객체(Object)와 인스턴스(Instance) 클래스를 사용하기 위해서는 해당 클래스 타입의 객체(object)를 선언해야 합니다. 이렇게 클래스로부터 객체를 선언하는 과정을 클래스의 인스턴스 화라고 합니다. 또한, 이렇게 선언된 해당 클래스 타입의 객체를 인스턴스(instance)라고 합니다. 즉, 인스턴스란 메모리에 할당된 객체를 의미합니다. 자바에서는 하나의 클래스로부터 여러 개의 인스턴스를 생성할 수 있습니다. 이렇게 생성된 인스턴스는 독립된 메모리 공간에 저장된 자신만의 필드를 가질 수 있습니다. 하지만 해당 클래스의 모든 메소드(method)는 해당 클래스에서 생성된 모든 인스턴스가 공유하게 됩니다.
class MyObject{
    private int index;
    MyObject(int index) {
        this.index = index;
    }
    public int getIndex() {
        return index;
    }
    public void setIndex(int index) {
        this.index = index;
    }
}
public class ClassType {
    public static void main(String[] args) {
        MyObject a = new MyObject(2);
        MyObject b = new MyObject(4);
        System.out.println(a.getIndex()); // "a" result is 2.
        a = b;
        System.out.println(a.getIndex()); // "a" result is 4.
        b.setIndex(6);
        System.out.println(a.getIndex()); // "a" result is 6.
    }
}

Interface 핵심 개념

  • 인터페이스의 특성

    1. 변수, 메서드의 껍데기만 있음
    2. 클래스를 선언할 때 implements 를 이용해 구현함
    3. 다중 상속이 가능함
    4. 인터페이스에 선언된 구조체는 모두 구현하도록 강제함
  • 인터페이스를 사용하는 이유

    1. 클래스를 파라미터로 받는 메소드가 있을 때, 클래스마다 다른 실행을 하기 위해 오버로딩(overloading)을 해야 함
      → 즉, 새로운 클래스가 생성될 때마다 오버로딩 메소드는 추가되어야 함
      ```java
      class ZooKeeper {
          void feed(Tiger tiger) {  // 호랑이가 오면 사과를 던져 준다.
              System.out.println("feed apple");
          }
      
          void feed(Lion lion) {  // 사자가 오면 바나나를 던져준다.
              System.out.println("feed banana");
          }
      }
      ```
    2. 구현체는 메소드의 파라미터는 인터페이스로 받아올 수 있음
      → tiger, lion은 각각 Tiger, Lion의 객체이기도 하지만 Predator 인터페이스의 객체이기도 하기 때문(IS-A 관계 적용)
      ```java
      interface Predator {
      		Stirng getFood()~~{}~~;
      		~~int age()~~
      }
      
      class Tiger extends Animal implements Predator {
      		public String getFood() {
              return "apple";
          }
      }
      
      class Lion extends Animal implements Predator {
      		public String getFood() {
              return "banana";
          }
      }
      
      class ZooKeeper {
          void feed(Predator predator) {
              System.out.println("feed "+predator.getFood());
          }
      }
      ```
      
      1. 구현체는 여러개가 될 수 있지만 인터페이스는 하나임
      → 파라미터로 받는 클래스에 의존적인 클래스 → 파라미터 클래스와는 상관없는 독립적인 클래스가 됨
  • 디폴트 메서드, 스태틱 메서드 - interface에서 미리 메서드 선언 가능

    interface Predator {
        String getFood();
    		(public static final) int pie = 3.14;
        default void printFood() {
            System.out.printf("my food is %s\n", getFood());
        }
    
        int LEG_COUNT = 4;  // 인터페이스 상수 - 자동으로 public static fianl 설정됨
    
        static int speed() {
            return LEG_COUNT * 30;
        }
    }

추상 클래스

  • 추상 클래스는 인터페이스의 역할&클래스의 기능도 갖고 있는 클래스
    • 추상 메소드를 작성하기 위해선 추상 클래스임을 선언해야 함
  • 클래스의 상속과 동일하게 구현하되, 추상 메소드를 생성하여 인터페이스처럼 사용이 가능함
  • 인터페이스와 동일하게 추상 메소드로 선언된 메서드는 반드시 구현되어야 함.
    즉, 추상 클래스를 바로 생성할 수 없으며 구현체 클래스를 생성해야 함.
  • 추상클래스를 상속받은 클래스에서는 구현된 클래스는 구현하지 않아도 됨
  • void printFood(), int speed()는 구현되어 있으므로 구현하지 않음
abstract class Predator extends Animal { //추상 클래스 선언
    abstract String getFood(); //추상 메소드 선언
		public static final int LEG_COUNT = 4;  // 추상 클래스의 상수는 static 선언이 필요하다. - static은 아래에서 확인
   
    void printFood() {
        System.out.printf("my food is %s\n", getFood());
    }

    int speed() {
        return LEG_COUNT * 30;
    }
}

class Tiger **extends Predator** implements Barkable {
		@Override // 추상메소드여도 @Override 어노테이션을 붙인다.
		String getFood(){
				(...생략...)
		}
}

Interface ≠ 추상 클래스

interface추상 클래스
메소드인터페이스는 구조체이므로 메소드 내용이 없다.추상클래스는 일반 클래스처럼 객체 변수, 생성자 등을 가질 수 있다.
변수선언시 자동으로 public static fianl이 붙어 변경이 불가능하다선언시 접근제한자, 정적 여부, 상수 여부를 직접 선언한다.
→ 일반 클래스에서의 선언과 동일
상속다중 상속 가능(implements)단일 상속(extends)
구현모든 메소드 구현 강제(default, static 제외)추상 메소드만 구현 강제(@Override 어노테이션 사용), 이미 구현된 메소드는 자율

사용 목적

💡 추상클래스: 클래스는 상속받아서 기능을 이용하고 확장 시킴
인터페이스: 함수의 껍데기만 선언하고 함수의 구현을 강제하여 구현 객체의 같은 동작을 보장

참고: 자바의 추상 클래스와 인터페이스 (brunch.co.kr), [초급 JAVA]자바 interface 와 abstract 예제로 이해하기 (tistory.com)

다형성

  • 다형성(Polymorphism): 하나의 객체가 여러개의 자료형 타입을 가질 수 있는 것
    같은 타입이지만 실행 결과가 다양한 결과가 나오는 성질
  • 다형성은 하나의 타입에서 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해줌.
  • 다형성을 위해 자바는 부모 클래스로 타입 변환을 허용함.
  • 모든 자식은 부모 객체로 타입 변환할 수 있음.
    • 이것을 응용하면 상위 타입에 대해 다양한 하위 타입을 적용하여 다형성을 이용할 수 있음.

    • 부모 클래스 변수 타입에 자식 클래스 변수를 할당하면 자식에서 부모로 자동으로 타입이 변환됨.

    • 자동 타입 변환된 부모 클래스에서 자식 클래스에 의해 오버라이드된 메소드를 호출하면, 오버라이드된 메소드가 호출됨.

      class Parent { ... }
      
      class Child extends Parent { ... }
      
      ...
      
      Parent pa = new Parent(); // 허용
      
      Child ch = new Child();   // 허용
      
      Parent pc = new Child();  // 허용
      
      Child cp = new Parent();  // 오류 발생.

필드의 다형성

필드의 타입은 변함이 없지만 실행 도중에 어떤 객체를 필드로 저장하느냐에 따라 실행 결과가 달라질 수 있음

예를 들어, 우리가 Tire라는 부모 클래스를 만들었다고 가정해 보자. 그런데 기술이 점점 발전하거나, 기기가 고장이 나서 타이어를 교체해야 하는 상황이 왔다고 하자. 이때, 만약 부모 타입의 클래스를 상속 받은 자식 객체에서, 더 좋은 기능을 장착한 후(오버라이딩), 타이어를 해당 타이어로 업그레이드할 수 있다면 어떨까?

새로 교체되는 타이어 객체는 기존 타이어와 사용 방법은 동일하지만 실행 결과는 더 우수하게 나와야 함.

→ 상속과 오버라이딩, 타입 변환을 이용하여 프로그램으로 구현

  • 타이어 프로젝트 실습

매개변수의 다형성

  • 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체 뿐만 아니라 자식 객체까지도 매개 값으로 사용할 수 있음
  • 매개 값으로 어떤 자식 객체가 제공 되느냐에 따라 메소드의 실행 결과가 달라짐
    ⇒ 매개변수의 다형성
    → 자식 객체가 부모의 메소드를 재정의(오버라이딩)했다면 메소드 내부에서 오버라이딩된 메소드를 호출함으로써 메소드의 실행 결과는 다양해짐

접근 제한자

profile
나는야 개발자

0개의 댓글