ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java와 객체지향
    Java/이론&문법 2023. 10. 28. 19:56

     

    🐟 클래스와 객체 : 정말 붕어빵틀과 붕어빵인가? 

     

    • 클래스 :  분류에 대한 개념이지 실체가 아니다. 같은 특성을 지닌 여러 객체를 총칭하는 집합의 개념이다. 
    • 객체 : 실체이고, 세상에 존재하는 유일무이한 사물이다.

     

    클래스 - 객체의 관계는 분류와 사물의 관계로 봐야 한다. 

    EX ) 펭귄(클래스) - 뽀로로(객체), 쥐(클래스) - 미키마우스(객체) 이런 느낌이다. 

     

     

     


    객체 지향의 4대 특성 

    🎨 추상화 : 모델링

    • 구체적인 것을 분해해서 관심영역(만들려고 하는 어플리케이션이 어디에 사용되는지)에 대한 특성만을 가지고 재조합하는 것이다. 
    • 실제 사물을 정확히 복제하는 것이 아닌, (ex. 사람의 모든 특성을 다 나열할 수는 없다) 목적에 맞게 관심이 있는 특성만을 추출해서 표현하고, 실제 사물을 단순하게 묘사하는 것이다. 

    EX) 병원에서 사람이라는 클래스가 있다면, 사람이라는 클래스의 직업이나 연봉과 같은 특성들은 필요가 없으므로 제거하고, 나이, 몸무게, 혈액형 등 필요한 특성들만 필드로 선언해두는 것 

     

     


     

     

    ♻️ 상속 : 재사용과 확장 

     

    하위 클래스는 상위 클래스이다. 

    • 상속을 단순히 할아버지 - 아버지 관계처럼 부모 - 자식 개념으로 생가하면 아버지는 할아버지다 라는 어색한 문장이 된다.
    • 하지만 포유류 (상위) - 고래 (하위) 라고 생각해보면 고래는 포유류이므로 이 문장이 어색하지 않다. 
    • 부모 - 자식이 아닌 상위 - 하위 클래스 뉘앙스로 기억하자. 

    상속을 is A 관계가 아닌, is a kind of로 생각하자. 

    ex ) 펭귄은 동물의 한 분류이다. 

     

    정리하자면, 상속은 상위 클래스의 특성을 재사용, 확장하는 것이고 is a kind of 관계를 만족해야 한다. 

     

     

    자바는 왜 다중 상속을 지원하지 않는가? 

    다이아몬드 상속 문제라고 많이 소개되는데, 굉장히 책에 쉬운 예시가 있다.

    • 인어공주는 물고기와 사람 클래스를 상속 받았다면, 인어공주는 수영할 때 물고기처럼 수영할까? 아니면 사람처럼 수영할까? 
    • 어느 쪽의 메소드를 수행해야 할 것인지 모호하다. 

     

    인터페이스는 ? 

    구현 클래스 is able to 인터페이스(구현 클래스는 인터페이스 할 수 있어야 한다.)

    무엇을 할 수 있는 ~ 이라는 표현 형태로 만들자. 

     

    ex ) 헤엄을 칠 수 있는 ~ 

    고래도 헤엄을 칠 수 있고 펭귄도 헤엄을 칠 수 있다.

    고래 클래스와 펭귄 클래스가 헤엄이라는 메소드를 구현한다. 

     

    • 상위 클래스는 물려줄 특성이 풍성할수록 좋고, 인터페이스는 구현을 강제할 메소드가 적을 수록 좋다. 

     

     


     

    👨‍👩‍👧‍👦 다형성 : 사용편의성

    • 오버로딩 : 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 중복정의
      • 만약 이러한 특성이 지원되지 않는다면, 덧셈 함수를 만들 때를 생각해보자
        • 오버로딩이 지원될 경우
          • 정수 + 정수, 정수 + 소수, 소수 + 소수 3가지 모두 같은 함수 이름 add 사용이 가능
          • add(int a, int b) , add (int a, double b) , add (double a, double b) 이런식으로 작성해둠
          • 사용하는 측에서 그냥 add만 쓰면 매개변수 따라 적합한 함수 매핑되어 수행
        • 오버로딩이 지원되지 않는다면? 
          • addIntToInt, addDoubleToInt, addDoubleToDouble .... 다 이름이 다르게 생성해야 한다.
          • 또한 사용할 때도, 정수끼리 덧셈이라면 addIntoInt 부르고, 실수끼리 덧셈이라면 addDoubleToDouble부르고...
          • 사용 편의성이 현저히 떨어진다! 
    • 오버라이딩 : 같은 메서드 이름, 같은 인자 목록으로 상위의 메서드를 재정의
      • 상위 클래스의 객체 참조변수를 사용하더라도 하위 클래스에서 오버라이딩한 메서드가 호출된다
      • 형변환이나 instanceof 연산자로 일일이 하위 클래스 무엇인지 신경쓰지 않아도 된다. (알아서 하위 클래스가 오버라이딩한 메서드를 자동으로 호출해주므로)
    // Penguin extends Animal
    // Animal의 showName -> Penguin에서 오버라이딩
    
    Animal pingu = new Penguin();
    pingu.showName(); // Penguin의 메소드가 호출된다!

     


     

    💊 캡슐화 : 정보 은닉

    • 접근 제어자
      • public
      • protected
      • default
      • private
    package one;
    class A {
        public int pub;
        protected int pro;
        int def;
        private int pri;
    
        static public int pubStatic;
        static protected int proStatic;
        static int defStatic;
        static private int priStatic;
        
        void runSomething() {
        
        }
        
        static void runStatic() {
        
        }
    }

     

    runSomething( ) 

    • 상속 받았다면 객체를 생성하지 않아도 자식 클래스에서 부모의 인스턴스 변수(객체 변수) 접근 가능
    • 상속을 받지 않았다면 new ClassA() 로 객체 생성 후 접근 가능
    • 정적 변수들은 classA.pub 이런식으로 접근 가능

    runStatic( )

    • class A의 인스턴스 변수들은 모두 객체를 생성한 후 접근이 가능
    • 정적 변수들은 classA.pub 이런식으로 접근 가능 

     

    각 접근 제어자, 패키지 별 접근 가능성 여부 

    // 동일 패키지 (package one)
    class AA extends A
    class B
    
    // 다른 패키지 (package two)
    class AB extends A
    class C

     

    class AA extends A

    • runSomething()
      • 상속 받았으므로 객체를 생성하지 않아도 public, protected, default 접근 가능
      • classA.pubStatic, classA.proStatic, classA.defStatic 접근 가능
    • runStatic() 
      • Static 메소드이므로 new ClassAA() 후 public, protected, default 접근 가능
      • classA.pubStatic, classA.proStatic, classA.defStatic 접근 가능

     

    class B 

    • runSomething()
      • 상속 받지 않았으므로 new ClassA() 한 후 public, protected, default 접근 가능
        • protected는 동일 패키지라면 상속 여부 상관없이 접근이 가능하고, 다른 패키지라면 상속받은 애만 접근 가능 
      • classA.pubStatic, classA.proStatic, classA.defStatic 접근 가능
    • runStatic() 
      • Static 메소드이므로 new ClassA() 후 public, protected, default 접근 가능
      • classA.pubStatic, classA.proStatic, classA.defStatic 접근 가능

     

    package two

    class AB extends A 

    • runSomething()
      • 상속 받았으므로 객체 생성하지 않아도 public, protected 접근 가능
      • classA.pubStatic, classA.proStatic 접근 가능
    • runStatic() 
      • Static 메소드이므로 new ClassAB() 후 public, protected 접근 가능(상속받았으므로 얘도 가지고 있다)
      • classA.pubStatic, classA.proStatic 접근 가능

    class C 

    • runSomething()
      • 상속 받지 않았으므로 new ClassA() 한 후 public만 접근 가능
      • classA.pubStatic만  접근 가능
    • runStatic() 
      • Static 메소드이므로 new ClassA() 후 public만 접근 가능
      • classA.pubStatic만 접근 가능

     

     


    스프링 입문을 위한 자바 객체지향의 원리와 이해를 학습하고 정리한 내용입니다.

    'Java > 이론&문법' 카테고리의 다른 글

    Java와 객체지향(3)  (0) 2023.11.01
    Java와 객체지향(2)  (0) 2023.11.01
    Java 8 - Optional, default method, Stream 연산  (0) 2023.10.09
    Java I/O, NIO  (0) 2023.10.08
    Java I/O에 대해 알아보자  (0) 2023.09.29
Designed by Tistory.