Java OOP - 심화

hyoreal·2022년 8월 26일
0

[JAVA]

목록 보기
3/11
post-thumbnail

객체지향 프로그래밍의 4개의 기둥

상속 (Inheritance)

  • 상속 (Inheritance)

    • 상위클래스의 멤버(필드, 메서드, 이너클래스)를 하위클래스에게 확장시키는 것
    • 하위클래스의 멤버는 상위클래스의 멤버와 같거나 많다
    • 코드의 재사용성
    • 코드의 중복 제거
    • 다형적 표현 가능
    • 자바는 단일 상속만 가능(다중상속X)
      • 인터페이스(interface)를 통해 다중상속과 비슷한 효과를 낼 수 있다
  • Object 클래스는 자바의 클래스 상속계층도의 최상위 위치

  • 모든 클래스는 Object 클래스에게서 상속받는다

    • Object 클래스 대표 메서드

      메서드명반환타입내용
      toString()String객체정보를 문자열로 출력
      equals(Object o)boolean등가 비교 연산과 동일하게 스택 메모리값 비교
      hashCode()int객체 위치정보관련. Hashtable 또는 HashMap에서 동일 객체여부 판단
      wait()void현재 쓰레드 일시정지
      notify()void일시정지 쓰레드 재동작
  • 포함관계 (composite)

    • 상속처럼 클래스를 재사용하는 방법
    • 클래스의 멤버로 다른 클래스 타입의 참조변수를 선언하는 것
    관계판별기준(클래스간의 관계상태)적합관계
    ~는 ~이다 (IS-A)상속관계
    ~는 ~를 가지고있다 (HAS-A)포함관계
  • 메서드 오버라이딩 (Method Overriding)

    • 상위 클래스로부터 상속받은 메서드와 동일한 이름의 메서드를 재정의하는 것
    • 메서드 오버라이딩 사용 시 조건
      1. 메서드의 선언부(메서드 이름, 파라미터, 반환타입)이 상위클래스와 완전히 일치
      2. 접근 제어자의 범위가 상위 클래스의 메서드보다 같거나 넓어야함
      3. 예외는 상위 클래스의 메서드보다 많이 선언 불가
      4. 인스턴스 메서드를 static 또는 그 반대로 변경 불가
    public class InheritanceExample {
      public static void main(String[] args) {
        Apple apple = new Apple(); // 각각의 타입으로 선언 + 객체 생성
        Banana banana = new Banana();
        Orange orange = new Orange();
        
        // 오버라이딩되어 각각 다른 출력
        apple.taste();
        banana.taste();
        orange.taste();
        
        > 출력
        > Apple is sweet!
        > Banana is sweet!
        > Orange is sweet!
    ------------------------------------------------------- 
        Fruit apple2 = new Apple(); // 상위 클래스 타입으로 선언 + 각각 타입으로 객체 생성
        Fruit banana2 = new Banana();
        Fruit orange2 = new Orange();
        
        apple2.taste();
        banana2.taste();
        orange2.taste();
        
        > 출력
        > Apple is sweet!
        > Banana is sweet!
        > Orange is sweet!
    ------------------------------------------------------
        // 배열로 한번에 관리하기
        Fruit[] fruits = new Fruits[] {new Apple(), new Banana(), new Orange()};
        for (Fruit fruit : fruits) {
          fruit.taste();
        }
        
        > 출력
        > Apple is sweet!
        > Banana is sweet!
        > Orange is sweet!
      }
    }
    
    class Fruit {
      void taste() {
        System.out.println("Fruit is sweet!");
      }
    }
    
    class Apple extends Fruit {
      void taste() {
        System.out.println("Apple is sweet!");
      }
    }
    
    class Banana extends Fruit {
      void taste() {
        System.out.println("Banana is sweet!");
      }
    }
    
    class Orange extends Fruit {
      void taste() {
        System.out.println("Orange is sweet!");
      }
    }
  • super 키워드 : 상위 클래스의 객체 호출

    public class Super {
      public static void main(String[] args) {
        Lower low = new Lower();
        low.callNum();
      }
    }
    
    class Upper {
      int count = 20; // super.count
    }
    
    class Lower extends Upper {
      int count = 10; // this.count
      
      void callNum() {
        System.out.println("count = " + count);
        System.out.println("this.count = " + this.count);
        System.out.println("super.count = " + super.count);
      }
    }
    
    > 출력
    > count = 15
    > count = 15
    > count = 20
  • super() 메서드 : 상위 클래스의 생성자 호출

    • 생성자 안에서만 사용 가능
    • 생성자 첫 줄에 와야함
    • 첫 줄에 없는 경우 컴파일러가 자동으로 삽입함
    public class SuperMethod {
      public static void main(String[] args) {
        CoffeeMilk m = new CoffeeMilk();
      }
    }
        
    class Coffee {
      Coffee() {
        System.out.println("커피 생성자");
      }
    }
    
    class CoffeeMilk extends Coffee { // Coffee 로부터 확장(상속)
      CoffeeMilk() {
        super(); // Coffee 클래스의 생성자 호출
        System.out.println("커피우유 생성자");
      }
    }
    
    > 출력
    > 커피 생성자
    > 커피우유 생성자

캡슐화 (Encapsulation)

  • 캡슐화 (Encapsulation)

    • 특정 객체 안에 관련된 속성과 기능을 하나의 캡슐로 만들어 데이터를 외부로부터 보호하는 것
    • 캡슐화 목적
      • 데이터 보호
      • 내부적으로만 사용되는 데이터에 대한 불필요한 외부 노출 방지
    • 캡슐화 장점
      • 정보은닉 (data hiding).
      • 외부로부터 객체의 속성과 기능이 변경되지 못하도록 막고, 데이터가 변경되더라도 다른 객체에 영향을 주지 않기 때문에 독립성 확보
      • 유지보수, 코드 확장 시 오류범위 최소화
  • 패키지 (package)

    • 특정한 목적을 공유하는 클래스와 인터페이스 묶음
    • 클래스들을 그룹단위로 묶어 효과적 관리 위한 목적
    • 자바에서의 패키지는 하나의 디렉토리이고 .으로 구분됨
    • package java.util.*;
  • Import문

    • 다른 패키지 내의 클래스를 사용하기 위해 사용
    • 패키지문과 클래스문 사이에 작성
    package practicePackage.test; // package문
    
    import practicePackage.test2; // import문 작성
    
    public class PackageImp {
      ...생략...
    }
  • 접근제어자 (Access Modifier)

    • 제어자 (Modifier) : 클래스, 필드, 메서드, 생성자 등에 부가적인 의미 부여 키워드. 자바에서는 접근제어자와 기타제어자로 구분.
    접근제어자public, protected, default(미작성 시 기본설정), private
    기타제어자static, final, abstract, native, transient, synchronized 등
    • 접근제어자 (Access Modifier)
      • 외부로의 불필요한 노출 방지
      • 데이터 임의 변경 방지
      • 필드나 메서드 선언부 앞에 적어서 접근 범위 제한
    접근제어자클래스 내패키지 내다른 패키지의 하위 클래스패키지 외
    PrivateOXXX
    DefaultOOXX
    ProtectedOOOX
    PublicOOOO
  • getter / setter 메서드

    • 데이터 보호 위해 private로 선언 시, 객체의 변수의 데이터값을 추가 및 수정 불가
    • 그 때, getter 메서드로 데이터 값을 가져올 수 있음
    • 그 때, setter 메서드로 데이터 값을 수정할 수 있음
    public class updateNum {
      public static void main(String[] args) {
        GetSetNum getSetNum = new GetSetNum(25);
        System.out.println(getSetNum.getNum());
        
        getSetNum.setNum(50);
        System.out.println(getSetNum.getNum());
      }
    }
    
    class GetSetNum {
      private int num;
      
      GetSetNum(int num) {
        this.num = num;
      }
      
      // getter 사용시 메서드명은 get-
      public int getNum() {
        return this.num;
      }
      
      // setter 사용시 메서드명은 set-
      public void setNum(int num) {
        this.num = num;
      }
    }
    
    > 출력
    > 25
    > 50

다형성 (Polymotohism)

  • 다형성 (Polymorophism)

    • 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것
      • 상위 클래스 타입의 참조변수를 통해 하위 클래스의 객체를 참조할 수 있도록 허용한 것
      • 위 방법으로 선언한 객체는 상위클래스의 멤버만 사용 가능
    • 장점 : 코드의 중복을 줄여준다
    • 메서드 오버라이딩과 메서드 오버로딩도 다형성의 한 예시
  • 참조변수의 타입 변환 : 사용할 수 있는 멤버의 개수를 조절하는 것

    • 타입 변환 조건 3가지
      1. 서로 상속관계에 있는 상위 - 하위 클래스 사이만 타입변환 가능
      2. 하위클래스 -> 상위클래스로의 타입변환(업캐스팅)은 형변환 연산자(괄호) 생략 가능
      3. 상위클래스 -> 하위클래스로의 타입변환(다운캐스팅)은 형변환 연산자를 반드시 명시해야함
    public class CastingExample{
      public static void main(String[] args) {
        ParentClass parentClass = new ParentClass();
        ChildClass childClass = new ChildClass();
        
        ParentClass upcasting1 = childClass;
        ParentClass upcasting2 = (ParentClass) childClass;
        
        //ChildClass downcasting1 = parentClass; // 형변환연산자 생략 불가 Incompatable Type
        ChildClass downcasting2 = (ChildClass) parentClass; // ClassCastException 발생
    }
  • instanceof 연산자

    • 캐스팅 가능 여부를 boolean 형으로 반환하는 자바문법요소
    • 프로젝트 규모↑, 클래스↑ 사용시 좋음
    public class InstanceOfExample {
      public static void main(String[] args) {
        Animal animal = new Animal();
        System.out.println(animal instanceof Object); //true
        System.out.println(animal instanceof Animal); //true
        System.out.println(animal instanceof Bat); //false
        
        Animal cat = new Cat();
        System.out.println(cat instanceof Object); //true
        System.out.println(cat instanceof Animal); //true
        System.out.println(cat instanceof Cat); //true
        System.out.println(cat instanceof Bat); //false
      }
    }
    
    class Animal{};
    class Bat extands Animal{};
    class Cat extends Animal{};

추상화 (Abstraction)

  • 추상화(Abstraction)

    • 기존의 클래스들의 공통적인 요소들을 뽑아서 상위 클래스를 만들어 내는 것
    • 추상화 장점
      • 코드의 중복 제거
      • 효과적인 클래스간의 관계설정
      • 유지보수 용이
    • 주로 추상 클래스인터페이스라는 문법 요소로 구현
  • abstract 제어자

    • 주로 클래스와 메서드를 형용하는 키워드로 사용
  • 메서드 앞에 붙은 경우 '추상 메서드(abstract method)'

    • 메서드의 시그니처만 있고 바디는 없는 메서드
    • abstract 키워드를 메서드 이름 앞에 붙여주어 해당 메서드가 추상메서드임을 표시
    • 추상메서드는 미완성 메서드
    • 미완성 메서드를 포함하는 클래스는 미완성 클래스를 의미하는 추상 클래스
  • 클래스 앞에 붙은 경우 '추상 클래스(abstract class)'

    • 추상메서드를 하나 이상 갖고있는 클래스
    • abstract 키워드를 클래스 이름 앞에 붙여주어 해당 클래스가 추상클래스임을 표시
    • 추상클래스로 객체선언 불가
  • 추상클래스 사용 이유

    • 상속 관계에 있어 새로운 클래스를 작성하는데 매우 유용
      • 메서드 내용이 상속받는 클래스에 따라 달라지는 경우 상위클래스의 선언부만 작성한 뒤 구체적 내용은 하위클래스에서 구현하도록 비워두는 것
    • 추상화를 구현하는 핵심 역할
      • 상속계층도의 상층부에 가까울수록 공통적인 속성과 기능들이 정의
  • final 키워드

    위치의미
    클래스변경 또는 확장 불가능한 클래스, 상속 불가
    메서드오버라이딩 불가
    변수값 변경이 불가한 상수
  • Interface

    • 모든 필드는 public static final로 선언
    • 모든 메서드는 static, default 이외에는 public abstract로 정의
  • Interface 구현

    • 인터페이스 그 자체로 객체생성 불가
    • 메서드 바디를 정의하는 클래스를 따로 작성해야함
    • implements 키워드 사용
    • 특정 인터페이스를 구현한 클래스는 해당 인터페이스에 정의된 모든 추상메서드를 구현해야함
    • 다중 구현 가능
  • Interface 구현 장점

    • 역할과 구현의 분리
      • 복잡한 구현 내용 또는 변경과 상관없이 기능 사용 가능
    • 개발시간 단축
    • 독립적인 프로그래밍을 통해 한 클래스의 변경이 다른 클래스에 미치는 영햔 최소화
profile
좌충우돌 코린이 성장기

0개의 댓글