Java/Java의 정석

Chapter 07 객체지향 프로그래밍 II

계란💕 2022. 2. 22. 12:32

1. 상속(Inheritance)

  1.1 상속의 정의와 장점

  Def) 상속: 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것

  - 코드의 중복 제거, 생산성 향상, 유지 보수에 기여한다.

  - 'extends' 키워드 사용 

  - 두 클래스는 조상 - 자손 클래스 관계를 맺는다.

  - 자손은 조상의 "모든 멤버"를 상속 받는다. (멤버 - 멤버 변수나 메서드만 상속) 

  - 생성자와 초기화 블럭은 상속되지 않는다. 

  - 자손의 멤버 개수는 조상보다 적을 수 없다.  (클래스는 멤버들의 집합)

    -> 조상 클래스: 부모(parent)클래스, 상위(super) 클래스, 기반(base) 클래스

    -> 자손 클래스: 자식(child)클래스, 하위(sub) 클래스, 파생된(derived) 클래스, 유도 클래스

    Ex)

c++
열기

  Note) 실행결과

  - displayCaption(String text) 메서드는 캡션 상태가 On일 때만 text를 보여준다.

  - 자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다. 

 

 

  1.2 클래스간의 관계 - 포함관계

  Def) 포함(Composite): 한 클래스의 멤버 변수로 다른 클래스를 선언하는 것

  • 클래스 간의 포함관계를 맺어 주는 것은 한 클래스의 멤버 변수로 다른 클래스 타입의 참조 변수를 선언하는 것이다.
  • 작은 단위의 클래스를 먼저 만들고, 이 둘을 조합하여 하나의 커다란 클래스를 만든다.

 

 

  1.3 클래스 간의 관계 설정하기 - 상속 vs포함

  - 가능한 한 많은 관계를 맺어줘 재사용성을 높이고 관리하기 쉽도록 한다.

  - 'is-a'와 'has-a'를 가지고 문장을 만들어 본다. 

    -> 'is-a' : 상속 관계 - 더욱 객체지향적, 다형성과 관련됨

      ex) SportsCar is a Car.

    -> 'has-a': 포함 관계 - 재사용성을 높임

      ex) Circle has a Point. ( 'is a'보다 더 명확함.)

  Ex) 상속 

c++
열기

 

  Note) 실행 결과

  - Circle 클래스와 Shape는 상속관계 

    -> Shape클래스에는 draw()가 정의 되어 있다.

    -> 그런데, Circle클래스에서 다시 새로운 draw()를 정의한다..... "오버라이딩"

    -> 결과, Circle클래스의 draw()가 호출된다. 

  - Triangle클래스와 Point는 포함관계

 

 

  Ex) 포함 관계

java
열기

  Note) 실행 결과

 

  - pick()은 Card객체 배열 cardArr에 저장된 Card객체 중에서 하나를 꺼내 반환한다.

  - Card객체 배열 cardArr은 참조변수 배열이고, 이 배열에 실제 저장된 것은 객체의 주소이다.

  - toString()은 인스턴스의 정보를 문자열로 반환할 목적으로 정의되었다.

 

 

  1.4 단일 상속

  - Java는 단일 상속만을 허용한다.(C++, Python은 다중 상속 허용)

  - 비중 높은 클래스 하나만 상속 관계로, 나머지는 포함 관계로 본다.

 

  1.5 Object클래스 - 모든 클래스의 조상

  - 조상이 없는 클래스는 자동적으로 Object클래스를 상속 받게 된다. 

  - 상속계층도의 최상위에는 Object클래스가 위치한다.

  - 모든 클래스는 Object클래스에 정의된 11개의 메서드를 상속 받는다. 

     -> toString(), equals(Object obj), hashCode(), ...

 

 

2. 오버라이딩(Overriding)

  2.1 오버라이딩이란?

  Def) 오버라이딩

  - 조상클래스로부터 상속받은 메서드의 내용을 상속받는 클래스에 맞게 변경하는 것을 오버라이딩이라고 한다. 

  - "메서드 재정의", "메서드 대체"라고도 표현한다.

 

  2.2 오버라이딩의 조건

    1) 선언부가 같아야 한다. (이름, 매개변수, 반환형)

      - 매개변수가 달라지면 '오버로딩'

    2) 접근제어자를 좁은 범위로 변경할 수 없다. 

      - 조상의 메서드가 protected라면 범위가 같거나 넓은 protected나 public으로만 변경할 수 있다. 

      - final, private 인 메서드는 오버라이딩 불가능하다.

    3) 조상클래스의 메서드보다 많은 수의 예외를 선언할 수 있다. (조상 클래스가 선언한 예외 내에서만 선언 가능)

      - static메서드를 instance 메서드로 오버로딩/ 오버라이딩 할 수 없다.

 

  2.3 오버로딩 vs. 오버라이딩

  - 오버로딩: 기존에 없는 새로운 메서드를 정의하는 것(New) - 매개변수 다름

    -> 한 클래스 내에서 같은 이름의 메서드를 여러 개 정의한다.

  - 오버라이딩: 부모 클래스로부터 상속 받은 메서드의 내용을 변경하는 것(Change, Modify) 재정의 

  Ex) 

c++
열기

 

  2.4 super

  - super: this와 비슷한데 조상의 멤버자신의 멤버를 구별하는 데 사용한다. 

  - 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수이다.

  - super(): 부모 클래스의 생성자를 호출한다.

  - this: 인스턴스 자신을 가리키는 참조 변수, 인스턴스의 주소가 저장되어있음,

    -> 모든 인스턴스 메서드에 지역 변수로 숨겨진 채로 존재

  Ex)

c++
열기

  Note) 실행 결과

  - 같은 이름의 멤버변수 x가 조상클래스인 Parent에도 있고 자손 클래스인 Child클래스에도 있을 때는 super.x , Parent.x가 서로 다른 값을 참조한다. 

    -> super.x: 조상 클래스로부터 상속받은 멤버변수 x

    -> Parent.x: 자손 클래스에 선언된 멤버변수

 

  2.5 super() - 조상의 생성자  

  - 자손 클래스의 인스턴스를 생성하면 자손의 멤버와 조상의 멤버가 합쳐진 하나의 인스턴스가 생성된다. 

  - 조상의 멤버들도 초기화되어야 하므로 자손의 생성자의 첫 문장에서 조상의 생성자를 호출해야한다. 

  - Object클래스를 제외한 모든 클래스의 생성자 첫 글자에는 생성자(같은 클래스의 다른 생성자 또는 조상의 생성자)를 호출해야 한다.

    -> 그렇지 않으면 컴파일러가 자동적으로 'super()'를 생성자의 첫 줄에 삽입한다. 

 

 

3. Package와 Import

  3.1 패키지(Package)

  - 서로 관련된 클래스와 인터페이스의 묶음

  - 클래스가 물리적으로 클래스파일(*.)인 것처럼, 패키지는 물리적으로 폴더이다.

    -> 패키지는 서브 패키지을 가질 수 있으며 , '.'으로 구분한다. 

  - 클래스의 실제 이름(full name)은 패키지명이 포함된 것이다. 

    -> String클래스의 full name은 java.lang.String, (java: 패키지 이름, lang:서브패키지, String:클래스이름)

 

  3.2 패키지의 선언

  - package 패키지명;

  - 패키지는 소스 파일에 첫 번째 문장(주석 제외)으로 단 한번 선언한다.

  - 하나의 소스파일에 둘 이상의 클래스가 포함된 경우, 모두 같은 패키지에 속하게 된다. 

  - 클래스패스(classpath) 설정

    -> 클래스패스(classpath)는 클래스파일(*.class)를 찾는 경로. 구분자는 ';'

    -> 클래스패스에 패키지가 포함된 폴더나 jar파일을 (*.jar) 나열한다.

    -> 클래스패스가 없으면 자동적으로 현재 폴더가 포함되지만 클래스 패스를 지정할 때는 현재 폴더(.)도 함께 추가해줘야한다.

 

  3.3  import문 (Ctrl + Shift + O)

  - 사용할 클래스가 속한 패키지를 지정하는데 사용

  - import문을 사용하면 클래스를 사용할 때 패키지명을 생략할 수 있다. 

  - java.lang 패키지의 클래스는 import하지 않고도 사용할 수 있다. 

  - import문은 패키지문과 클래스선언의 사이에 선언한다. 

 

  3.4 import문의 선언

  - 형식: import.패키지명.클래스명; 또는 import.패키지명.*;

  - 이름이 같은 클래스가 속한 두 패키지를 import할 때는 클래스 앞에 패키지명을 붙여줘야 한다. 

 

  3.5 static import문

  - static import문을 사용하면 static멤버를 호출할 때 클래스 이름을 생략할 수 있다.   

    Ex)  

c++
열기

  Note) 만약 위와 같이 선언했다면 아래와 같이 간략히 사용할 수 있다. 

  - System.out.println(Math.random()); => out.println(random()); 

 

 

4. 제어자(modifier)

  4.1 제어자란?

  Def) 제어자: 클래스, 변수 또는 메세드의 선언부와 함께 사용되어 부가적인 의미를 부여한다.

  - 접근제어자(public, protectef, default, private) / 그 외(static, final, abstract, native, transient, ...)

 

  4.2 static - 클래스의 , 공통적인

  Def) static + 멤버변수: 인스턴스 변수는 하나의 클래스로부터 생성되더라도 각기 다른 값을 유지하지만 클래스 변수(static 멤버변수)는 인스턴스에 관계없이 같은 값을 갖는다. 

    -> 모든 인스턴스에서 공통적으로 사용되는 클래스 변수이다. 하나의 static 변수를  모든 인스턴스가 공유한다.

 

  Def) static + 메서드: 인스턴스를 생성하지 않고도 호출 가능한 메서드, 값을 생성하지 않아도 호출 가능, 메서드 내부에서 super, this사용 불가

 

  - static을 사용하면 객체를 선언하지 않고 객체의 변수를 바로 사용가능하다.

  - 멤버변수, 메서드, 초기화 블럭에 사용된다.

    -> 변수나 메서드의 특성을 바꾸는 키워드

  - 하나의 클래스 변수를 모든 인스턴스가 공유한다. (메모리에 한 번만 할당된다.)

  - 객체가 만들어지기 전부터 static변수가 먼저 만들어진다.

  - 멤버변수/ 메서드/ 초기화 블럭에 사용될 수 있다. 

  - static, final 모두 대문자로 쓴다.

 

  4.3 final - 마지막의, 변경될 수 없는(상수)

  - 클래스, 메서드, 멤버변수, 지역변수

    -> final + 클래스: 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다. (다른 클래스의 조상이 될 수 없다.) - 상속 불가능 클래스

        ex) String 클래스

    -> final + 메서드: 변경될 수 없는 메서드이다. 즉, final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.

    -> final + 멤버변수/ 지역변수: 값을 변경할 수 없는 "상수"가 된다. (반드시 한 번만 할당 가능)

  - 생성자를 이용한 final 멤버 변수 초기화

    -> final을 붙이면 상수이므로 보통 선언과 초기화를 동시에 하지만, 인스턴스 변수의 경우 생성자에서 초기화한다. 

  - final 앞에 static을 선언하는 경우가 많다.

  - static과는 다르게 객체를 생성한 다음, final이 쓰인 멤버변수를 쓸 수 있다. 

 

  4.4 abstract - 추상의, 미완성의

  - 클래스, 메서드에 사용가능

    -> abstract + 클래스: 클래스 내에 추상 메서드가 선언되어 있음을 의미한다.

    -> abstract + 메서드: 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다. 

  - 추상클래스는 인스턴스를 생성하지 못한다. 

 

  4.5 접근 제어자(access modifier)

  - 멤버 또는 클래스에 사용되어 외부로부터의 접근을 제한한다. (접근 범위 조절)

  - 클래스, 멤버변수, 메서드, 생성자

    -> private: 같은 클래스

    -> (default): 같은 패키지 (접근 제어자가 없으면 default를 생략한 것이다.)

    -> protected: 같은 패키지 + 자손 클래스

    -> public: 접근 제한 전혀 없음

    -> (아래로 갈수록 범위가 넓다.)

 

  - 접근 제어자를 이용한 캡슐화(encapsulation)

    -> 접근제어자를 사용하는 이유: 데이터를 보호하기 위해, 내부적으로만 사용하는 부분을 감추려고

    -> 데이터가 유효한 값을 가지도록 하고, 비밀번호같은 데이터를 변경하지 못하도록 한다. 

    -> '데이터 감추기(data hiding)'

    -> private를 사용하면 외부에서 접근할 필요없는 멤버를 외부에 노출시키지 않음으로써 복잡성을 줄일 수 있다. 

 

  - 보통적으로

    -> 멤버변수의 값을 읽는 메서드이름 -> 'get멤버변수이름'

    -> 멤버변수의 값을 변경하는 메서드이름 -> 'set멤버변수이름' ...라고 정하는 암묵적인 규칙이 있다.  

    -> get으로 시작하는 메서드 => 겟터(getter)

    -> set으로 시작하는 메서드 => 셋터(setter)

 

   - 생성자의 접근 제어자

    -> 생성자에 접근 제어자를 사용함으로써 인스턴스의 생성을 제한할 수 있다.

    -> 일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치한다. 

    -> private클래스는 다른 클래스의 조상이 될 수 없다. 

  

  4.6 제어자의 조합

  1) 메서드에 static과 abstract를 함께 사용할 수 없다.

    -> static메서드에는 몸통(구현부)에 있는 메서드에만 사용할 수 있기 때문

  2) 클래스에 abstract, final을 함께 사용할 수 없다. 

    -> abstract(상속을 해야 완성이 된다) <=> final(클래스 확장 불가)

  3) abstract의 메서드의 접근제어자가 private일 수 없다. 

    -> abstract메서드는 자손클래스에서 구현해줘야 하는데 접근제어자가 private이면 자손클래스에서 접근 불가.

  4) 메서드에 final과 private 함께 사용 불가

     -> private 메서드는 오버라이딩 불가,(둘 중 하나만 사용해도 충분)

 

 

5. 다형성(polymorphism)

  5.1 다형성이란?

  Def) 다형성: 여러 가지 형태를 가질 수 있는 능력

  - 하나의 참조 변수로 여러 타입의 객체를 참조 가능 (한 객체가 여러 가지 타입을 가질 수 있다.)

  - 조상 클래스 타입의 참조변수로 자손클래스 타입의 객체를 다룰 수 있는 것이다.

  - 상속관계 / 업 캐스팅 / 다운 캐스팅 / 객체 확인 연산자 (instance of)

 

  Note) instanceof 

  - 피연산자1 instanceof 피연산자2  

  - 피연산자1이 객체변수가 참조하는 객체가 실제 피연산자2클래스 이름이면 true, 아니면 false를 반환한다.

  - 상속 관계가 없으면 문법 오류가 발생한다.

 

 

  Ex) Tv클래스를 상속받는 CaptionTv 클래스가 있다고 하자. 상속 관계에 있기 때문에

    인스턴스를 참조 변수로 참조 또는 조상 타입의 참조 변수로 참조하는 것이 모두 가능하다.

c++
닫기
CaptionTv c = new CaptionTv();  // 인스턴스를 같은 타입의 참조변수로 참조
Tv t		= new CaptionTv();  // 인스턴스를 조상타입의 참조변수로 참조

  Note) 

  - 위 코드에서 CaptionTv 인스턴스를 두 개 생성하고 참조변수 c, t가 생성된 인스턴스를 하나씩 참조하도록 했다. 

  - 이 경우 실제 인스턴스가 CaptionTv 타입이라고 할지라도,

  - 참조 변수 t로는 CaptionTv 인스턴스의 모든 멤버를 사용할 수 없다.

  - Tv타입 참조 변수로는 CaptionTv인스턴스 중에서 Tv클래스의 멤버들 (상속받은 멤버 포함)만 사용가능하다.

  - CaptionTv 인스턴스의 멤버 중에서 Tv클래스에 정의되지 않은 멤버인 text, caption()는 참조변수 t로 사용 불가능하다.

  - 즉, 둘 다 같은 타입의 인스턴스지만 참조 변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다.

  - 참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버 개수보다 같거나 적어야 한다. 

 

 

  5.2 참조변수의 형변환

  Def) 클래스 형변환: 부모 타입으로 자식 객체를 참조하게 되면 부모의 메서드만 이용 가능하다. 따라서, 자식 객체의 메서드나 속성까지 이용하기 위해 형변환할 수 있다.

 

  - 서로 상속관계에 있는 타입간의 형변환만 가능하다.

  - 자손 타입에서 조상 타입으로 형변환하는 경우, 형변환 생략 가능

    -> 자손 타입 -> 조상 타입(업 캐스팅, Up-casting): 형변환 생략 가능

    -> 조상 타입 -> 자손 타입(다운 캐스팅, Down-casting): 형변환 생략 불가

  - 형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조 변수의 형변환은 인스턴스에 아무런 영향을 미치지 않는다.

   - 단지 참조변수의 형변환을 통해서 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것 뿐이다. 

  Ex) 

c++
열기

  Note) 실행결과

  Ex)

c++
열기

  Note) 실행결과

  - 컴파일은 성공하지만 실행 시 에러(ClassCastException)가 발생한다.

    ->  컴파일 할 때는 참조변수 간의 타입만 체크하기 때문에 실행 시 생성될 인스턴스 타입에 대해서는 알지 못함.

  - Car  car = new Car(); 부분을 Car  car = new FireEngine();으로 바꿔야 에러가 안 난다.

 

  5.3 instanceof 연산자

  - 참조변수가 참조하는 인스턴스의 실제 타입을 체크하는데 사용

  - 이항연산자이며 피연산자는 참조형 변수와 타입, 연산 결과는 true, false

  - 형변환이 가능한지 알려준다. 

  - 참조변수.getClass().getName();참조변수가 가리키고 있는 인스턴스 클래스 이름을 문자열(String)로 반환한다. 

  - 어떤 타입에 대한 instanceof연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.

 

  5.4 참조변수와 인스턴스의 연결 

  - "멤버변수가 중복정의된 경우", 참조변수의 타입에 따라 연결되는 멤버변수가 달라진다.

    -> 참조변수 타입에 따라 달라진다.

  - "메서드가 중복정의된 경우", 메서드는 참조변수 타입에 관계없이 항상 실제 인스턴스에 정의된 메서드 호출된다.

    -> 참조변수 타입에 영향받지 않는다. 

  Ex)

c++
열기

 

  Note) 실행결과

  - 자손클래스 Child에 선언된 인스턴스 변수 x와 조상클래스 Parent로부터 상속받은 인스턴스 변수 x를 구분하는데 super, this가 사용된다.

  - x와 this.x는 Child클래스의 인스턴스변수 x를 뜻한다. 그래서 둘의 결과 값이 같다.

 

   5.5 매개변수의 다형성

  - 참조형 매개변수는 호출 시, 자신과 같은 타입 또는 자손 타입의 인스턴스를 넘겨줄 수 있다.

  Ex) 

c++
열기

  Note) 실행 결과

  - 고객이 buy메서드를 이용해서 Tv와 Computer를 구입하고 잔고와 보너스 포인트를 출력한다.

 

  5.6 여러 종류의 객체를 하나의 배열로 다루기

  - 조상 타입의 배열에 자손들의 객체를 담을 수 있다. 

  - java.util.Vector - 모든 종류의 객체들을 저장할 수 있는 클래스

 

  Ex) 앞서 공부한 예제의 클래스에서 구입한 제품을 저장하기 위해 Product 배열을 추가

c++
열기

  Note) 실행 결과

  - Vector클래스는 내부적으로 Object타입의 배열을 가지고 있어서 이 배열에 객체를 추가하거나 제거 가능.

  - 배열의 크기를 알아서 관리해주기 때문에 저장한 인스턴스 개수에 신경쓰지 않는다. 

  - 구입한 물건을 반환할 수 있도록 refund(Product p)를 추가한다.

  

 

6. 추상클래스 (abstract class)

  6.1 추상클래스란?

  Def) 추상 클래스: 클래스설계도라면 추상 클래스는  '미완성 설계도'

  - 상속받는 클래스에 따라 내용이 달라질 수 있기 때문에 미완성

  -  하나 이상의 추상 메서드(미완성 메서드)를 포함하고 있는 클래스 - 일반 클래스와 차이점

  - 완성된 설계도가 아니므로 인스턴스를 생성할 수 없다.  

  - 다른 클래스에 도움을 주기 위해 사용된다. (자손 클래스에 의해서만 완성 가능)

  - 일반 메서드가 추상 메서드를 호출할 수 있다. 

  - 추상 클래스 자체는 객체 생성 불가

  -  형식

c++
열기

 

  Note) 추상클래스/ 인터페이스 차이점

  - 추상 클래스는 멤버를 작성할 수 있다. (인터페이스는 멤버가 없다.)

  - 추상 클래스는 추상 메서드를 하나 이상 포함하는 클래스 / 인터페이스는 모든 메서드가 추상 메서드이다.

  - 추상클래스는 상속 받는 클래스를 만들어서 기능을 이용하고 확장하는데 목적이 있다. 

    -> 인터페이스는 추상메서드의 구현을 강제함으로써 인터페이스를 구현한 객체들에 대해 같은 동작을 보장한다.

 

  6.2 추상 메서드(abstract method)

 - 선언부만 있고 구현부(몸통, body)가 없는 메서드 (구현부는 자식 클래스에 따라 다를 수 있음) 

 - 자식 클래스에서 반드시 오버라이딩 해야하는 메서드

 Ex)

java
열기

 

  6.3 추상클래스의 작성

  - 어떤 클래스에 공통적으로 사용될 수 있는 추상클래스를 바로 작성하거나 기존클래스의 공통 부분을 뽑아서 조상클래스를 만든다. 

 

 

7. 인터페이스(interface)

  7.1 인터페이스란?

  Def) 인터페이스

  - 일종의 추상클래스, 추상클래스(미완성 설계도)보다 추상화 정도가 높다. (기본 설계도)

  - 실제 구현된 것이 전혀 없는 기본 설계도(껍데기)

  - 추상 메서드와 상수만을 멤버로 가질 수 있다.

  - 인스턴스를 생성할 수 없고, 클래스 작성에 도움 줄 목적으로 사용된다. 

  - 이미 정해진 규칙에 맞게 구현하도록 표준을 제시하는데 사용된다. 

  - 다중 상속처럼 이용할 수 있다.

  - 몸통 없는 클래스라고 볼 수 있다.

 

  7.2 인터페이스의 작성

  - 구성요소(멤버)는 추상 메서드와 상수만 가능

  - 모든 멤버변수는 "public static final"이어야 하며 생략 가능 - (static 상수만 정의 가능)

  - 모든 메서드는 "public abstract"이어야 하고 생략 가능

    -> 단, static메서드와 default메서드는 예외 ( JDK1.8부터 )

 

  7.3 인터페이스의 상속

  - 클래스처럼 상속 가능하다. 그러나 인터페이스는 클래스와 다르게 다중 상속이 가능하다.

    ex) public class 엘지리모콘 implements 리모콘, 전화기능 { }

  - 클래스와 같은 최고 조상(Object)이 없다.

  - 클래스와 인터페이스를 동시에 상속하는 것도 가능하다.

    ex) 클래스(군인), 인터페이스(IBS, 대테러진압, 산악행국) => public class SSU extends 군인 implements IBS, 대테러진압, 산악행국

 

  7.4 인터페이스 구현

  - 인터페이스를 구현하는 것은 클래스를 상속받는 것과 같다.

    -> 'implements'사용 i.e. 구현한다는 뜻

  - 인터페이스에 정의된 추상메서드를 완성해야한다. 

  - 상속과 구현이 동시에 가능하다.

 

  7.5 인터페이스를 이용한 다중상속

  7.6 인터페이스를 이용한 다형성

  - 인터페이스 타입의 변수로 인터페이스를 구현한 클래스의 인스턴스를 참조할 수 없다.

  - 인터페이스를 메서드의 매개변수 타입으로 지정할 수 없다. 

  - 인터페이스를 메서드의 반환형으로 지정할 수 있다. 

  - 반환형이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 뜻.  - 암기!

 

  7.7 인터페이스의 장점

  1) 개발 시간을 단축시킬 수 있다.

  2) 표준화 가능

  3) 서로 관계없는 클래스들에게 관계를 맺어줄 수 있다.

  4) 독립적인 프로그래밍이 가능하다.

 

  7.8 인터페이스의 이해

  - 클래스를 사용하는 쪽(user)과 클래스를 제공하는 쪽(Provider)이 있다.

  - 매서들를 사용(호출)하는 쪽(user)에서는 사용하려는 메서드(Provider)의 선언부만 알면 된다. (내용을 몰라도된다.)

  - getInterface(): 인스턴스를 제공하는 메서드

  Ex)

c++
열기

  Note) 실행 결과

  - 인스턴스를 생성하지 않고, getInstance()를 통해 제공받는다.

  - 이렇게 하면 나중에 다른 클래스의 인스턴스로 변경되어도 A클래스의 변경없이 getInstance()만 변경하면 된다. 

    -> return new B(); => 이부분만 변경하면 된다. 

 

  7.9 디폴트 메서드와 static메서드

  - 디폴트 메서드(default method): 추상 메서드의 기본적인 구현을 제공하는 메서드이다. 

  - 디폴트 메서드는 추상 메서드가 새로 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다. 

 

  1) 여러 인터페이스의 디폴트 메서드 간의 충돌

    -> 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야한다.

  2) 디폴트 메서드와 조상 클래스와 메서드 간의 충돌

    -> 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다. 

 

 

8. 내부 클래스(inner class) 

  8.1 내부 클래스란?

  Def) 내부 클래스: 클래스 내에 선언된 클래스이다. (긴밀한 관계에 있는 클래스끼리)

  - 이 때 내부 클래스는 외부 클래스를 제외하고 다른 클래스에서 잘 사용되지 않는 것이어야 한다. 

  - 내부클래스의 장점

    -> 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근 가능하다. (외부 클래스에서는 내부 클래스 접근 불가)

    -> 코드의 복잡성을 줄일 수 있다. (캡슐화)

 

  8.2 내부 클래스의 종류와 특징

  - 인스턴스 클래스(instance class): 외부 클래스의 멤버변수 선언 위치에 선언, 외부클래스의 인스턴스멤버처럼 다뤄진다. 

  - 정적 클래스(static class): 외부 클래스의 멤버변수 위치에 선언, 외부 클래스의 static 멤버처럼 다뤄진다. 

  - 지역 클래스(local class): 외부 클래스의 메서드나 초기화 블럭 안에 선언하며 선언된 영역 내부에서만 사용될 수 있다.

  - 익명클래스(anonymous class): 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용)

 

  8.3 내부 클래스의 선언

  - 변수의 선언 위치와 동일하다. 

 

  8.4 내부 클래스의 제어자와 접근성

  - 인스턴스 클래스와 스태틱클래슨는 외부 클래스의 멤버 변수와 같은 위치에 선언된다. 

  - 그리고 멤버변수와 같은 성질을 갖는다. 

  - 인스턴스 멤버와 static멤버간의 규칙도 똑같이 적용된다. 

  Ex)

c++
열기

  Note) 스태틱 멤버는 인스턴스 멤버를 직접 호출할 수 없는 것처럼 외부 클래스의 인스턴스 멤버를 객체생성 없이 사용 불가

 

 Ex) 외부클래스가 아닌 다른 클래스에서 내부 클래스를 생성하고 내부 클래스의 멤버에 접근 경우

  - 컴파일 시 파일명: "외부 클래스$내부 클래스명.class"

 

  Ex) 내부 클래스와 외부 클래스에 선언된 변수의 이름이 같을 때 

  - 변수 앞에 "this"또는 "외부클래스명.this"를 붙여 구분가능

 

  8.5 익명 클래스(anonynous class)

  Def) 익명클래스는 다른 내부클래스와 다르게 이름이 없다. => 생성자도 없다. 

  - 클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한 번만 사용될 수 있고  오직 하나의 객체만을 생성.

  - 오로지 단 하나의 클래스를 상속 받거나 단 하나의 인터페이스만 구현할 수 있다. 

  - 일회용 클래스이다. 

  - 형식

c++
열기

 

  Ex)

c++
열기

 

  Note)  두 개의 독립된 클래스를 작성한 후에 다시 익명클래스를 이용하여 변경하면 된다. 

  - 오로지 하나의 클래스만 상속 받거나 하나의 인터페이스만 구현할 수 있다. 

 

  Note) 필드 참조 메서드 setter, getter

  - 객체를 만들었는데 객체의 

  - setter:필드의 값을 저장하는 메서드

  - getter: 필드의 값을 반환하는 메서드

 

  Ex) sette, getter

  - 필드 cardNumber가 private일 때 사용한다.

java
열기
java
열기

  Note) 실행 결과: 1234567812341234