그냥 배우는 언어 기록하는 공간 :D

패캠 학습일지

[패스트캠퍼스] 자바 강의 추가 학습 일지

꾸준히_노력하기 2024. 3. 8. 11:22
배운 내용 정리

 

[ Part 4. 객체지향 프로그래밍 설계하기 ]

ch 01. 자바에서 상속이란

 

> 상속 (Inheritance)

= 수직적 구조 = 계층화 = 클래스와 클래스의 관계 설계 

: 클래스를 수직적 구조로 계층화하여 설계하는 방법.

: 객체를 설계할 때 비슷한 클래스의 경우 중복적인 요소가 발생함.

  → 수평적인 구조가 아닌 수직적인 구조로 설계해야 함.

 


> 상속 (extends)

: 클래스를 계층화하는 것.

: 부모 클래스가 가지고 있는 기능을 확장(재활용)시켜서

  여러 개의 하위 클래스를 만들어내는 방법.

: 자식 클래스 extends 부모 클래스 

 

> 단일상속

: 부모를 하나로 두는 상속구조.

: 자바는 단일상속만 지원함.

 

> 객체를 수직적인 구조로 설계하는 것의 장점
: 코드의 중복 부분을 최소화함.

: 새로운 요구사항 발생시 반영이 쉬움. (유지보수가 쉬움.)

  → 부모 클래스만 수정하면 되기 때문에

: 확장성이 좋음.

  → 부모 클래스를 재활용해서 다른 클래스를 확장시키는 것이 편리함.

 


> super( )

: 상위 클래스의 생성자를 호출함.

: 컴파일러는 생성자 안에 자동으로 super 메서드를 넣어줌. 
: 생성자 안에 super 메서드가 생략되어 있는 것. 

 

: 부모 클래스에도 super 메서드가 생략되어 있음. 
: 모든 객체는 부모가 있어야 함. 
: 자바에서 제공해 주는 최상위 클래스는 Object 클래스임. 
: 모든 클래스는 최상위 클래스(루트 클래스)인 Object를 상속받게 되어 있음. 

 

 

> 메모리를 통한 상속의 이해
: 상속관계에서는 나를 기준으로 위쪽에 있는 부모 객체가 먼저 생성이 되어야 함. 
: 나만 고려하는 것이 아닌 부모 객체의 여부도 고려해야 함. 
: 메모리에 부모부터 객체가 만들어져야 하고, 그 후에 내가 만들어져야 함. 

: Employee가 먼저 메모리에 만들어지려면,

  Employee의 생성자 메서드(①)가 호출되어야 함. 
: Employee의 생성자 메서드는 자식 클래스가 만들어질 때 호출됨. 
: 자식 클래스가 만들어지기 위해서 new 생성자를 사용한 것임. 

: 부모를 먼저 생성해야 하기 때문에

  자식 생성자 안에서 부모 생성자를 호출하기 위해 super 메서드를 사용함. 
   → 상위 클래스인 Employee의 생성자를 호출함. 
   → 메모리(기억공간)에 Employee 객체가 먼저 생성됨. 

: Employee와 RempVO는 실제로 메모리가 분리되어 있음. 
: 그러나 Employee 부분까지 확장되어서 메모리 전체를 RempVO가 사용할 수 있음. 
: 상속해 주었기 때문에 vo는 메모리 전체를 사용할 수 있게 된 것임.

 


> 상속 : UML (Unified Modeling Language)
: 상속을 표현할 때 UML(객체지향모델링언어)이라는 다이어그램을 사용함. 
: 설계를 할 때, 다이어그램을 그린 후 이를 참고하여 코드를 작성하는 것이 일반적임.


> 상속관계 실습

 

 

 

 


> 상속관계에서 객체생성

: 자식이 부모의 상태정보를 마음대로 접근하는 것은 정보은닉에 위배됨.

 

 

 


 

 

 

 

+ 접근제한자를 protected로 설정하면 안됨.
→ 정보은닉에 위배되기 때문에.

부모를 private으로 설계하고, 자식이 부모에게 값을 넘겨서
부모가 자신의 private 멤버에 값을 넣는 형식으로 초기화해야 함.


ch 02. 상속관계에서 객체생성 및 Override

 

> 수평적 구조 설계 실습

 

 

 


> 수직적 구조 설계 실습

 

 

 

 


> 동작 측면에서 상속 구조를 사용해야 되는 이유

① 내가 Dog 클래스를 직접 설계해서 직접 사용하는 경우
직접 설계했으니까 eat 메서드가 있다는 것을 알고 있음.
d.eat( ); 를 사용하는 데에 문제가 발생하지 않음.

② 다른 사람이 Dog 클래스를 설계한 경우
일반적으로 소스코드를 주지 않고, 완성된 클래스 파일만 받을 수 있음.
클래스 파일만 있으면 내부에 어떤 동작이 있는지 알 수 없음.
d.eat( ); 의 사용이 제한적임. 
설계가 바람직하지 않음.

③ 설계자는 이렇게 설계해서 배포해야 됨.
Dog 클래스를 구동시킬 수 있는 별도의 클래스를 만듦.
인터페이스 역할을 할 수 있는 클래스로 Dog 클래스를 동작시킬 수 있도록 설계해야 함.

부모클래스 자식클래스를 연동해서..
사용자가 부모클래스를 이용해서 자식클래스를 동작할 수 있는 원리로 클래스를 설계해야 함.

하위클래스의 동작을 알 수 없을 때에는 부모 타입으로 객체를 생성할 수밖에 없음.

 

 

+ 추가 설명

사람이 리모콘으로 TV를 동작시키는 것을 생각하면 이해하기 쉬움.

TV 같은 클래스와 TV를 동작시킬 수 있는 리모콘 같은 클래스를 같이 설계해서 배포해야 
사용자가 리모콘 클래스를 이용해서 TV 클래스를 동작할 수 있게 되는 것임.

클래스 안에 있는 정보를 노출시키고 싶지 않지만, 

클래스를 제공해서 다른 사람이 활용할 수 있게 하려면, 
리모콘과 TV의 관계처럼 클래스를 설계해서 배포해야 한다는 것임.

여기서 리모콘과 TV과 같은 관계를 상속이라고 함.
리모콘의 역할을 하는 것이 부모, TV의 역할을 하는 것이 자식임.

TV 안에 회로도를 사용자가 알 필요는 없음.
리모콘의 각 버튼이 무슨 역할을 하는지만 알면 얼마든지 TV를 구동시킬 수 있음.
클래스를 설계하는 입장에서 상속을 바라보자.

 


> 업캐스팅 실습

 

 


> 상속 체이닝

: 나보다 부모가 먼저

: 상속관계에서 객체가 생성될 때

  맨 위 부모클래스부터 객체가 생성되어 자식까지 연결되는 구조

 


> 상속 체이닝과 super

 

Animal 타입으로 만들면 Dog 클래스 기억공간에 접근할 수 없음.
접근할 수 있는 방법을 알아야 함.

Animal로 Dog 클래스를 구동시킨다는 것은 

Animal 타입으로 만들어도 Dog 클래스에 있는 기억공간도 접근할 수 있어야 한다는 것임.

 


 

 

 

 


> 재정의 (Override)

: 상속관계에서 하위클래스가

  상위클래스의 동작을 변경 혹은 추가(재정의)하는 행위

 


> 메서드의 재정의가 필요한 이유

① 컴파일 시점
타입이 우선이기 때문에 x.eat( ); 는 Animal 것임.

② 실행 시점
우선 Animal의 eat( ) 를 찾아가지만, 재정의가 되어 있는지 확인함.
재정의가 되어 있다면 부모가 아닌 자식의 eat( ) 를 구동시킴.
→ 동적 바인딩 (실행시점에서 사용될 메서드가 결정되는 바인딩)


+ 부모의 eat( ) 가 자신의 eat( ) 에 의해서 무시됨.
→ 재정의를 하면 원하는 결과를 얻을 수 있음.

 


> 재정의 (Override) 실습

 

 

 


ch 03. 객체 형변환(Object Casting)

 

> 부모와 자식 간에 형 변환 가능

: 부모는 여러 명의 자식을 가리킬 수 있음.

→ 부모와 자식은 상속관계이기 때문에

     DataType(자료형)이 달라도 부모가 자식을 가리킬 수 있음.

 

: 부모를 알면 자식들을 관리하기 쉬움.
자식에게 맞춰서 형 변환을 해야 함.
  자식마다 달래주는 스타일이 다르다는 것을 떠올리면 쉬움.


> Upcasting (업캐스팅, 자동형변환)

: 부모가 자식을 가리키는 객체생성방법

   ex. Dog 클래스와 Animal 클래스가 상속관계인 경우

         Animal ani=new Dog( ); 와 같이 객체를 생성하는 방법  


> Downcasting (다운캐스팅, 강제형변환)

: 상위클래스의 타입을 하위클래스의 타입으로 바꾸는 행위

 

 

업캐스팅이 되어야 다운캐스팅이 되는 것임.

 


> Upcasting과 Downcasting

 

: 타입이 Animal이면, Cat에 바로 갈 수 없음.
부모가 자식의 기억공간에 바로 갈 수 없음.
부모의 타입으로 자식의 타입에 바로 갈 수 없음.

: 재정의가 되어 있는 동작에는 갈 수 있음.
재정의가 되어 있지 않은 night( ) 에는 갈 수 없음.

: ani 라는 부모 타입을 Cat 타입으로 형을 바꿔서 받아야 함.
→ 다운캐스팅

 

: c의 타입은 Cat이기 때문에 전체 기억공간을 사용할수 있음.
: c.night( ); 로 Cat 타입에 있는 night( )에 접근할 수 있음.

 

 

+ 추가 설명
(cat)x.night( ); → X
(cat) → 캐스팅 연산자
. →  참조 연산자

참조 연산자가 우선 순위가 더 높음.
캐스팅 되기 전에 x.night( ); 가 먼저 실행되게 됨.
캐스팅을 먼저하고 night( ) 로 가야 하기 때문에 괄호 연산자를 써 주어야 함.
→ ((cat)x).night( );
괄호 연산자가 우선 순위가 높음.

 


ch 04. 다형성(Polymorphism)과 활용

 

> 다형성 (message polymorphism)

: 상위클래스가 동일한 메시지로

  하위클래스를 서로 다르게 동작시키는 객체지향 이론

 

: 다형성의 개념을 쓰게 되면,

  클래스를 확장시키기 쉽고, 유지보수도 쉽다는 장점이 있음.

 

> 다형성을 만족할 수 있는 전제조건
① 상속관계
② 재정의 (Override)
③ 업캐스팅 (Upcasting)

④ 동적 바인딩


> OOP(객체 지향 프로그래밍)의 3대 특징
① 정보은닉
② 상속
③ 다형성

 


> 다형성 (message polymorphism) 실습

 

 


> 다형성 인수
: 부모이기 때문에 하나의 타입으로 여러 가지 타입을 받을 수 있음

: 인수 = 인자 = argument = 매개변수

 

 

: eat( ) 출력을 main이 아닌 다른 메서드에서 하려고 하는 것.

: main 메서드에서 만든 Dog와 Cat 타입을 다른 메서드로 이동하는 것.
: 잘못된 프로그래밍은 아니지만, 타입이 늘어나면 display( ) 메서드도 늘어난다는 단점이 있음.


> 다형성 인수 활용 실습

 

 


 


: instanceof 
→ 타입 확인 연산자
→ 결과는 true or false

 


> 다형성 배열 (상위 타입 배열)

: 배열은 동일한 자료형만 저장할 수 있지만

  부모타입의 배열은 자식타입을 저장할 수 있음.

  하나의 배열에 서로 다른 타입 저장 가능 

 

 


 

 


ch 05. 추상클래스와 인터페이스의 등장

 

> 다형성을 보장한다

: 부모가 명령을 내리면 자식이 반드시 동작(반응)을 해야 함.

: 재정의를 하지 않으면 다형성이 보장되지 않음.

 

> 다형성을 보장하기 위해서는

: 다형성 전제조건 4가지가 필수적임.

: 반드시 재정의가 되어야 함.

: 부모클래스를 추상클래스(불완전한 클래스)로 만들어야 함.

 


> 추상메서드 (불완전한 메서드)

: 메서드의 구현부가 없는 메서드

: 반드시 자식이 완전하게 해야 함.

   (= 재정의 해야 함.)

 


> 재정의를 하지 않은 경우 실습

 

 

 

 

 


> 재정의한 경우 (다형성 보장) 실습

 

 

 


 

 

 

 


> 추상클래스
: 다형성을 일부 보장하기 위해 등장함.

  → 구현된 메서드도 있어서 일부라는 표현을 사용하는 것임.

 

: 서로 비슷한 클래스의 공통부분을 묶을 때 사용함.

: 단독으로 객체를 생성할 수 없음.

: 부모의 역할로 사용함. (Upcasting)
: 추상메서드도 가질 수 있고,

  구현된 메서드도 가질 수 있음. (move)

 

+

재정의가 되어 있기 때문에 에러 없이 설계해서 배포할 수 있었던 것.
추상클래스만으로 동작할 수 없기 때문에 노출해도 상관없음.

 

 

 


 

 


> 인터페이스 실습

 

 

 


 

 


> 인터페이스를 이용한 클래스 동작

: 다형성이 100% 보장됨.

: 인터페이스는 규약이라고 부르기도 함.
: 인터페이스를 상속받을 때는 implements(구현)를 사용함.

: 서로 다른 클래스를 같은 부모로 묶을 때는 

  인터페이스로 묶어서 추상메서드로만 동작을 하게 만듦.


: 구현메서드는 동작이 맞지 않는 클래스가 있을 수 있기 때문에 

  추상메서드로만 이루어진 인터페이스를 이용하는 것임.

 

 

 

 


 

 

 

 


> 인터페이스

: 다형성을 100% 보장하기 위해 등장함.

: 서로 다른 클래스의 공통부분을 묶을 때 사용함.

: 단독으로 객체를 생성할 수 없음.

: 부모의 역할로 사용함. (Upcasting)
: 추상메서드와 final static 상수만 가질 수 있음.

: 구현된 메서드를 가질 수 없음.

 


> 인터페이스에서 사용하는 final static 상수

 

Public interface RemoCon{

  public int MAXCH=99;  // static final이

  public int MINCH=1;      // 생략되어 있는 것

  // 위와 같은 표현

  public static final int MAXCH=99;

  public final static int MINCH=1;

 

  public void chUp( );

  public void chDown( );

  public void volUp( );

  public void volDown( );

}

 

final = 종단
→ 변수의 값을 초기화시키면 더이상 변수의 값을 변경할 수 없다는 것.
     한번 값이 정해지면 내부에서 수정하면 안 되기 때문에 final을 붙임.

static
: static을 붙이면 객체를 생성하지 않아도 접근할 수 있음.
: MAXCH, MINCH는 static이기 때문에 클래스 이름으로 접근할 수 있음.
      ex) RemoCon.MAXCH, RemoCon.MINCH

: 인터페이스는 객체를 생성할 수 없기 때문에, 

  인터페이스가 가지고 있는 값 변수에 접근하려면 static이 붙어야 함.

 

: final 키워드가 들어간 경우 한번 값이 들어가면 

  수정할 수 없기 때문에 여기에서 MAXCH와 MINCH는 상수임.

  → 상수는 대문자로 쓰는 것이 일반적.


> 가독성을 높인 식

 

public class TV implements RemoCon{

  private int currch=10;

  public void chUp(){

    currch++;

      if(currch>RemoCon.MAXCH){

          currch=1;

      }

    System.out.pfintln("TV 채널이 올라감");

  }

  public void chDown(){

    currch--;

    if(currch<RemoCon.MINCH){

        currch=99;

    }

    System.out.println("TV 채널이 내려감");

  }

}

 

1) 99보다 커질 수 없기 때문에 채널을 다시 1로 바꿈.
2) 1보다 적어질 수 없기 때문에 채널을 다시 99로 바꿈.

TV는 RemoCon이 가지고 있는 기능/동작을 구현했다(implements)고 표현함.

인터페이스 기호
<<RemoCon>>


> 다중상속을 지원하는 인터페이스
: 자바는 단일상속만 지원함.
  → 여러 개의 클래스를 상속받을 수 없음.

: 인터페이스는 다중상속처럼 지원함.

 


추상클래스 Animal에 방에서 함께 생활한다는 구현메서드 play( )를 추가한다고 해 보자.
모든 동물 클래스가 play( ) 기능이 상속됨.
그러나 사자, 호랑이처럼 애완동물이 아닌 동물 클래스에는 play( ) 기능이 해당되지 않음.

이런 경우 인터페이스를 사용하면 됨.
Pet 인터페이스에 추상메서드 play( )를 넣어 줌.
부분적으로 물려주고 싶은 클래스에만 인터페이스를 두고 play( )를 재정의해서 사용하면 됨.


인터페이스는 여러 개를 설정할 수 있음.
A, B가 가지고 있는 추상메서드를 C가 구현하면 되는 것임.

 


> 추상클래스와 인터페이스의 공통점

: 다형성을 보장하기 위해 등장한 개념.

: 추상메서드를 가질 수 있음.

: 단독으로 객체를 생성할 수 없음.: 부모의 역할로 사용함. (Upcasting)

 

 

> 추상클래스와 인터페이스의 차이점

 

추상클래스

: 서로 비슷한 클래스의 공통부분을 묶을 때 사용함.

: 추상메서드 + 구현메서드

 

인터페이스

: 서로 다른 클래스의 공통부분을 묶을 때 사용함.

: 추상메서드 + final static 변수(상수)

 


ch 06. 자바 최상위 클래스 Object

 

> 클래스를 한 개 만들면 기본적으로 생략된 코드 

 

 

① default package
자바에서 가장 많이 사용하는 클래스를 모아 놓은 패키지.

import java.lang.*; 


② java.lang.Object (최상위 클래스)
모든 객체는 부모가 있어야 함.
자바에서 클래스는 객체로 취급함.

③ default 생상자
클래스 이름과 메서드가 동일함.
리턴 타입을 쓰면 안 됨.
상위클래스 객체를 생성하는 super 메서드가 생략되어 있음.

클래스 하나를 만들면 ①②③이 생략되어 있다는 생각을 가지고 시작해야 함.


> A 클래스를 사용하기 위해 객체 생성하는 방법

 

 

1) 자기자신이 객체를 만드는 방법
2) 자식의 타입을 부모가 받는 방법 (다형성)

 

 

+ 추가 설명
Object는 자바에서 만든 것이기 때문에 display 메서드가 없음.

 obj.display();


부모 타입을 A(자식) 타입으로 바꿔서 다운캐스팅을 해야 함.

 ((A)obj).display();

 


> 다형성 인수로 Object 활용 실습

: Object 타입으로 Upcasting되면

  반드시 Downcasting을 하게 되어 있음.

 

 


 

 


> 다형성 배열로 Object[ ] 배열 활용 실습

 

 


> Object클래스의 toString( ) 메서드

: 객체가 생성된 번지는 16진수의 형태(숫자)로 되어 있음.


: 컴파일러가 메모리의 비어있는 곳에 객체를 만들기 때문에

  번지를 알고 싶다면 번지를 출력해 보면 됨.
  → 이때 사용하는 메서드가 toString( ) 임.

 

: 객체의 번지를 문자열로 출력할 수 있도록 

  Object 안에 toString 메서드를 만들어 놓은 것임.

 

+ toString( )

: 객체의 번지를 문자열로 출력