CNU_SW_모각코

모각코 4주차 결과(2022.07.28)

nayeonee__ 2022. 7. 28. 17:30
  1. 상속(inheritance)

 

 

* 1-1. 상속의 정의와 장점

 

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

       코드의 재사용성을 높이고 코드의 중복을 제거한다.

 

조상클래스 – 부모(Parent)클래스, 상위(Super)클래스, 기반(base)클래스

자손클래스 – 자식(child)클래스, 하위(sub)클래스, 파생된(derived)클래스

ex )

class Parent{}

class Child extends Parent{}

 

  • 생성자와 초기화 블록은 상속되지 않는다. 멤버만 상속된다.
  • 자손 클래스의 멤버 개수는 조상클래스보다 항상 같거나 많다.
  • 자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.

 

 

 

 * 1-2. 클래스간의 관계 – 포함관계

 

클래스 간의 포함관계를 맺어 주는 것은 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것

 

ex )

class Point{

int x;

int y;

}

class Circle{

Point c = new Point();

int r;

}

 

Circle에 Point의 x, y좌포를 포함시켰다.

 

 

* 1-3. 클래스 간의 관계 결정하기

 

간단히 is-a 와 has-a 로 결정한다.

 

원(Circle)은 점(Point)이다. - Circle is a Point.

원(Circle)은 점(Point)을 가지고 있다. - Circle has a Point

 

두 번째 문장이 더 옳다는 것은 명백하다. 따라서 둘은 포함관계다.

 

상속관계 ‘~은 ~이다.(is-a)’

포함관계 ‘~은 ~을 가지고 있다.(has-a)’ 

 

 

*1-4. 단일 상속(single inheritance)

다른 객체지향언어인 C++에서는 여러 조상으로부터 상속받는 것을 허용하지만 자바에서는 단일 상속만을 허용한다.

 

*1-5. Object 클래스 – 모든 클래스의 조상

 

모든 클래스 상속계층도의 최상위에 있는 조상클래스이다.

 

컴파일러가 모든 클래스에 자동적으로 ‘extends Object’를 추가하여 Object클래스로부터 상속받도록 한다. 다만 이미 상속을 받는 클래스에는 추가되지 않으며, 조상의 조상을 거슬러 올라가다 보면 최상위에 Object 클래스가 나올 뿐이다.

 

 

 

2. 오버라이딩(Overriding)

 

2-1. 오버라이딩

: 조상클래스로부터 상속받은 메서드의 내용을 변경하는 것

 

2-2. 오버라이딩의 조건

 

        자손 클래스에서 오버라이딩하는 메서드는 조상클래서의 메서드와

         1. 이름이 같아야 한다.

         2. 매개변수가 같아야 한다.

         3. 반환타입이 같아야 한다. 

   => 즉, 선언부가 일치해야 한다는 것

 

 

        접근제어자와 예외의 경우 제한된 조건 하에서 변경할 수 있다.

        1. 접근제어자는 조상클래스의 메서드보다 좁은 범위로 변경할 수 없다.

        2. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.

        3. 인스턴스메서드를 static메서드로 또는 그 반대로 변경할 수 없다.

        (조상클래스에 있는 static메서드를 자손클래스에 선언하는 것은 오버라이딩이 아니며,          완전히 별개의 static메서드를 새로 선언한 것이다. static멤버들은 자신이 정의된 클          래스에 묶여있어야 한다.)

 

 

2-3. 오버로딩 VS 오버라이딩

오버로딩(overloading) : 기존에 없는 새로운 메서드를 정의하는 것(new)

오버라이딩(overriding) : 상속받은 메서드의 내용을 변경하는 것(change, modify)

 

2-4. super

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

상속받은 멤버와 자신의 클래스에 정의된 이름이 같을 때 super를 붙여서 구별할 수 있다.

 

2-5. super() - 조상클래스의 생성자

조상클래스의 생성자를 호출하는데 사용된다.

 

Object 클래스를 제외한 모든 클래스의 생성자 첫 줄에 생성자 this() 또는 super()를 호출해야한다. 그렇지 않으면 컴파일러가 자동적으로 ‘super();’를 생성자의 첫 줄에 삽입한다.

 

 

 

 

3. package 와 import

 

3-1. 패키지(package)

 

  • 하나의 소스파일에는 첫 번째 문장으로 단 한번의 패키지 선언만을 허용한다.
  • 모든 클래스는 반드시 하나의 패키지의 속해야 한다.
  • 패키지는 점(.)을 구분자로 하여 계층 구조로 구성할 수 있다.
  • 패키지는 물리적으로 클래스파일(.class)을 포함하는 하나의 디렉토리이다.

 

ex) java.lang.String에서 lang은 디렉토리 String이 클래스

 

 

3-2. 패키지의 선언

소스파일에 다음과 같이 한줄만 적어주면 된다

package 패키지명;

 

 

 

 

 

3-3. import 문

클래스 작성 전에 import문으로 사용하고자 하는 클래스의 패키지를 미리 명시해주면 소스코드에 사용되는 클래스 이름에서 패키지명을 생략할 수 있다.

 

컴파일 시 컴파일러는 import문을 통해 소스파일에 사용된 클래스들의 패키지를 알아 낸 다음, 모든 클래스이름 앞에 패키지명을 붙여준다.

 

3-4. import문의 선언

모든 소스파일(.java)에서 import문은 package다음, 클래스 선언문 이전에 위치해야 한다.

package와 달리 여러 번 선언할 수 있다.

 

일반적인 소스파일(*.java)의 구성은 다음의 순서로 되어있다.

1.package문

2.import문

3.클래스 선언

 

선언방법

 

import 패키지명.클래스명 ;     또는     import 패키지명.*;

 

클래스이름을 지정해주는 대신 ‘*’을 사용하면 컴파일러가 패키지에서 일치하는 클래스이름을 찾아 컴파일 시에 적용시킨다. 실행시 성능상의 차이는 전혀 없다.

 

3-5. static import문

static 멤버를 호출할 때 클래스 이름을 생략할 수 있다. 특정 클래스의 static멤버를 사용할 때 좋다.

 

ex)

import static java.lang.Integer.*; // Integer클래스의 모든 static 메서드

import static java.lang.Math.random; // Math.random()만. 괄호 안붙임 -> random()

import static java.lang.System.out; // System.out을 out만으로 참조가능 -> out

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

 

 

4. 제어자(modifier)

 

4-1. 제어자

: 클래스, 변수 또는 메서드의 선언부와 함께 사용되어 부가적인 의미를 부여한다.크게 접근 제어자와 그 외의 제어자로 나뉜다.

 

하나의 대상에 여러 제어자를 조합하여 사용하는 것이 가능하지만, 접근 제어자는 한번에 네 가지 중 하나만 사용할 수 있다.

접근제어자 – public, protected, default, private

그 외 – static, final, abstract, native, transient, synchronized, volatile, strictfp

 

4-2. static – 클래스의, 공통적인

 

인스턴스변수는 하나의 클래스로부터 생성 되었더라도 각기 다른 값을 유지하지만, 클래스 변수(static멤버 변수)는 인스턴스에 관계없이 같은 값을 갖는다. 하나의 변수를 모든 인스턴스가 공유하기 때문이다.

 

static이 붙은 멤버변수와 메서드, 초기화 블록은 인스턴스를 생성하지 않고도 사용할 수 있다.

 

인스턴스 메서드와 static메서드는 메서드 내에서 인스턴스 멤버를 사용하는 가의 차이가 있다.

 

static이 사용될 수 있는 곳 : 멤버변수, 메서드, 초기화 블록

   static 멤버변수 – 모든 인스턴스에 공통적으로 사용되는 클래스 변수가 된다.

                  - 클래스 변수는 인스턴스를 생성하지 않고도 사용이 가능하다.

                  - 클래스가 메모리에 로드될 때 생성된다.

   

   static 메서드 – 인스턴스를 생성하지 않고도 호출이 가능해진다.

                - static 메서드 내에서는 인스턴스 멤버들을 직접 사용할 수 없다.

 

4-3. final – 마지막의, 변경될 수 없는

거의 모든 대상에 사용될 수 있다.

변수에 사용되면 상수가 되고, 메서드에 사용되면 오버라이딩이 불가해진다. 클래스에 사용디면 자손클래스로의 확장이 불가해진다

 

final이 사용될 수 있는 곳 – 클래스, 메서드, 멤버변수, 지역변수

 

final 사용시

클래스 – 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다. 즉, 조상이 될 수 없다.

메서드 – 변경될 수 없는 메서드, 오버라이딩이 불가하다

멤버변수 – 값을 변경할 수 없는 상수가 된다.

지역변수 – 값을 변경할 수 없는 상수가 된다

 

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

final 이 붙은 변수는 상수이므로 일반적으로 선언과 동시에 초기화하지만, 인스턴스 변수의 경우 생성자에서 초기화되도록 할 수 있다.

 

클래스 내에 매개변수를 갖는 생성자를 선언하여, 인스턴스를 생성할 때 final이 붙은 멤버변수를 초기화하는데 필요한 값을 생성자의 매개변수로부터 제공받는 것이다. 

 

4-4. abstract – 추상의, 미완성의

메서드의 선언부만 작성하고 실제 수행내용은 구현하지 않은 추상 메서드를 선언하는데 사용된다. 또한 클래스에 사용되어 추상메서드 존재여부를 알 수 있게도 한다.

 

abstract 사용시

클래스 – 클래스 내에 추상 메서드가 선언되어 있음을 의미한다.

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

 

 

4-5. 접근제어자(access modifier)

멤버 또는 클래스에 사용되어, 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 한다. 이 때 default는 생략가능하다.

 

접근 제어자가 사용될 수 있는 곳 – 클래스, 멤버변수, 메서드, 생성자

 

private : 같은 클래스 내에서만 접근 가능

default : 같은 패키지 내에서만 접근 가능

protected : 같은 패키지내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.

public : 접근 제한이 전혀 없다.

 

범위

public > protected > (default) > private

 

접근 제어자를 이용한 캡슐화

: 클래스나 멤버, 주로 멤버에 접근 제어자를 사용하는 이유는 클래스의 내부에 선언된 데이터를 보호하기 위해서이다. 데이터가 유효한 값을 유지하도록, 또는 비밀번호와 같은 데이터를 외부에서 변경하지 못하도록 외부로부터의 접근을 제한하는 것이 필요하다.

 

이것을 데이터 감추기(data hiding)라고 하며, 객체지향개념의 캡슐화(encapsulation)에 해당하는 내용이다.

 

접근제어자를 사용하는 이유

  • 외부로부터 데이터를 보호하기 위해서
  • 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서

 

생성자의 접근제어자

  • 생성자의 접근 제어자를 사용함으로써 인스턴스의 생성을 제한할 수 있다.
  • 보통 생성자의 접근 제어자는 클래스의 접근 제어자와 같지만, 다르게 지정할 수도 있다.

 

 

 

4-6. 제어자(modifier)의 조합

 

 대상 사용가능한 제어자
클래스 public, (default), final, abstract
메서드 모든 접근 제어자, final, abstract, static
멤버변수 모든 접근 제어자, final, static
지역변수 final

대상에 따라 사용할 수 있는 제어자

 

 

제어자를 조합해서 사용할 때 주의해야 할 사항

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

     static메서드는 몸통이 있는 메서드에만 사용할 수 있기 때문이다.

  1. 클래스에 abstract와 final을 동시에 사용할 수 없다.

      클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고 abstract는 상속을 통해        서 완성되어야 한다는 의미이므로 서로 모순되기 때문이다.

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

       abstract 메서드는 자손클래스에서 구현해주어야하는데 접근제어자가 private이면 자손         클래스에서 접근할 수 없기 때문이다.

  1. 메서드에 private과 final을 같이 사용할 필요는 없다.

       접근제어자가 pirvate인 메서드는 오버라이딩이 될 수 없기 때문이다. 이 두 중 하나만         사용해도 의미가 충분하다.

 

 

5. 다형성(polymorphism)

 

5-1. 다형성

: 여러 가지 형태를 가질 수 있는 능력

  구체적으로는 ‘조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다는 것’

 

  • 조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있다.
  • 반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수 는 없다.

 

5-2. 참조변수의 형변환

참조변수도 형변환이 가능하다. 단, 서로 상속관계에 있는 클래스사이에서만 가능하기 때문에 자손타입과 조상타입 서로간의 형변환만 가능하다.

 

자손타입 -> 조상타입(up-casting) : 형변환 생략가능

조상타입 -> 자손타입(down-casting) : 형변환 생략불가

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

 

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

 

서로 상속관계에 있는 타입간의 형변환은 양방향으로 자유롭게 수행될 수 있으나, 참조변수가 가리키는 인스턴스의 자손타입으로 형변환은 허용되지 않는다. 그래서 참조변수가 가리키는 인스턴스의 타입이 무엇인지 확인하는 것이 중요하다.

 

 

 

출처 : https://hearthole.tistory.com/17?category=710136 

 

자바의 정석 7장 (5) 다형성(polymorphism)

5. 다형성(polymorphism) 5-1 다형성이란? '여러 가지 형태를 가질 수 있는 능력'을 의미한다. 구체적으로는 '조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다는 것'

hearthole.tistory.com

 

 

제어자와 관련하여 헷갈렸던 부분들이 많았는데 개념을 정리하게 되어서 조금은 이해가 가는 것 같다.