전체 방문자
오늘
어제
모달조아
Better than yesterday
모달조아
  • 분류 전체보기 (147)
    • PS (86)
      • BOJ (79)
      • 프로그래머스 (6)
    • 이론 (41)
      • 자료구조 (2)
      • 알고리즘 (8)
      • 데이터베이스 (1)
      • 운영체제 (1)
      • 네트워크 (3)
      • 디자인패턴 (7)
      • Java (13)
      • Spring (4)
      • JPA (1)
      • Git (1)
    • 개발 (18)
    • 프로젝트 (1)
    • 기록 (0)
      • 후기 (0)
    • etc (1)

최근 글

티스토리

hELLO · Designed By 정상우.
모달조아

Better than yesterday

이론/Java

OOP - 상속

2021. 7. 14. 00:20

상속

  1. 상속
  2. 접근제한자
  3. 추상클래스
  4. super와 부모생성자
  5. 오버라이딩
  6. 클래스 형변환

1. 상속

상속이란 부모가 자식에게 가진 것을 물려주는 것이다. 즉, 부모가 가진 것을 자식이 사용할 수 있게 된다.

  • 침대는 가구의 한 종류이다.
  • 버스는 자동차이다.

위와 같이 말할 수 있는 관계를 is a 관계 혹은 kind of 관계라고 하고 상속의 대표적인 관계이다. 코드를 보며 알아보자.

public class Car
{
    public void run()
    {
        System.out.println("달리다.");
    }
}

public class Bus extends Car
{
    public void ppangppang()
    {
        System.out.println("빵빵");
    }
}

Bus는 Car클래스를 상속받았다. 이때, Car클래스를 부모클래스, Bus클래스를 자식클래스라고 한다. Bus클래스에는 run메소드가 정의되어있지 않지만 사용할 수 있다. 추가로 ppangppang메소드는 당연하게 이용할 수 있다.

2. 접근제한자

접근제한자의 종류
- public
: 어떤 클래스는 접근 가능하다.

- protected
: 자기 자신, 같은 패키지, 서로 다른 패키지여도 상속받은 자식클래스일 경우 접근 가능하다.

- private
: 자기 자신만 접근 가능하다.

- default 접근제한자(접근제한자 적지 않은 경우)
: 자기 자신과 같은 패키지에서만 접근 가능하다.

3. 추상클래스

추상클래스란 구체적이지 않은 클래스를 의미한다. 예를 들자면, 오리, 참새, 비둘기 이런 것은 구체적인 새를 지칭하지만 새, 포유류와 같은 것은 구체적이지 않다. 이런 것을 구현한 클래스를 추상클래스라고 한다.

추상클래스를 정의해보자.

public abstract class Bird
{
    public abstract void sing();

    public void fly()
    {
        System.out.println("날다.");
    }
}

- 추상 클래스는 클래스 앞에 abstract 키워드를 이용해서 정의한다.
- 추상 클래스는 미완성의 추상 메소드를 포함할 수 있다.
- 추상 메소드란, 내용이 없는 메소드 이다. 즉 구현이 되지 않은 메소드이다.
- 추상 메소드는 리턴 타입 앞에 abstract라는 키워드를 붙여야 한다.
- 추상 클래스는 인스턴스를 생성할 수 없다.

추상클래스를 상속 받는 클래스를 만들어보자.

public class Duck extends Bird
{
    public void sing()
    {
        System.out.println("꽥꽥!");
    }
}

- 추상 클래스를 상속받은 클래스는 추상 클래스가 갖고 있는 추상 메소드를 반드시 구현해야 한다.
- 추상 클래스를 상속받고, 추상 클래스가 갖고 있는 추상 메소드를 구현하지 않으면 해당 클래스도 추상 클래스가 된다.

4. super와 부모생성자

class가 인스턴스화 될때 생성자가 실행되면서 객체를 초기화한다. 그 때 자신의 생성자만 실행이 되는것이 아니고, 부모의 생성자부터 실행된다. 코드로 한번 알아보자.

public class Car
{
    public Car()
    {
        System.out.println("Car의 기본생성자");
    }
}

public class Bus extends Car
{
    public Bus()
    {
        System.out.println("Bus의 기본생성자");
    }
}



public class BusMake
{
    public static void main(String args[])
    {
        Bus b = new Bus();
    }
}

- 결과
Car의 기본생성자
Bus의 기본생성자

- new 연산자로 Bus객체를 생성하면, Bus객체가 메모리에 올라갈때 부모인 Car도 함께 메모리에 올라간다.
- 생성자는 객체를 초기화 하는 일을 하는데, 생성자가 호출되면서 자동으로 부모생성자가 호출되고 부모 객체를 초기화한다.

super 키워드
- 자신을 가리키는 키워드가 this 라면, 부모들 가리키는 키워드는 super
- super() 는 부모의 생성자를 의미한다.
- 부모의 생성자를 임의로 호출하지 않으면, 부모 class의 기본 생성자가 자동으로 호출된다.
- 부모클래스가 기본생성자를 가지고 있지 않으면, 자식클래스의 생성자에서 직접 부모생성자를 호출해야한다.

5. 오버라이딩

오버라이딩이란 부모가 가지고 있는 메소드와 똑같은 모양의 메소드를 자식이 가지고 있는 것이다. 즉, 오버라이딩이란 메소드를 재정의 하는 것이다.
코드를 보며 알아보자.

public class Car
{
    public void run()
    {
        System.out.println("Car의 run메소드");
    }
}

public class Bus extends Car
{
    public void run()
    {
        System.out.println("Bus의 run메소드");
    }
}

public class BusMake
{
    public static void main(String args[])
    {
        Bus bus = new Bus();
        bus.run();
    }
}

- 결과
Bus의 run메소드

- 메소드를 오버라이드 하면, 항상 자식클래스에서 정의된 메소드가 호출된다.
- 오버라이딩 한다고 해서 부모의 메소드가 사라지는 것은 아니다. super 키워드를 이용하면 부모의 메소드를 호출 할 수 있다.

6. 클래스 형변환

부모타입으로 자식객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용할 수 있다. 자식객체가 가지고 있는 메소드나 속성을 사용하고 싶다면 형변환 해야 한다.
코드를 보며 알아보자.

public class Car
{
    public void run()
    {
        System.out.println("Car의 run메소드");
    }
}

public class Bus extends Car
{
    public void ppangppang()
    {
        System.out.println("빵빵.");
    }
}

public class BusMake
{
    public static void main(String args[])
    {
        Car car = new Bus();
        car.run();
        car.ppangppang(); // 컴파일 오류 발생
    }
}

- 부모 타입으로 자식 객체를 참조할 수 있다.
- 부모 타입으로 자식 객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용할 수 있다.
- ppangppang메소드를 호출하고 싶다면 Bus타입의 참조 변수로 참조해야한다.

public class BusMake
{
    public static void main(String args[])
    {
        Car car = new Bus();
        car.run();
        // car.ppangppang(); // 컴파일 오류 발생
        Bus bus = (Bus) car; // 부모타입을 자식타입으로 형변환
        bus.run();
        bus.ppangppang();
    }
}

- 객체들 끼리도 형변환이 가능하다. 단, 상속관계에 있었을 때만 가능하다.
- 부모 타입으로 자식 타입의 객체를 참조할 때는 묵시적으로 형변환이 일어난다.
- 부모 타입의 객체를 자식 타입으로 참조하게 할때는 명시적으로 형변환 해주어 한다. 단 이렇게 형변환 할때에는 부모가 참조하는 인스턴스가 형변환 하려는 자식 타입일 때만 가능하다.

저작자표시

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

final 키워드 헷갈리는 부분 정리  (0) 2021.11.11
java.lang 패키지 / 오토 박싱/ 오토 언박싱  (0) 2021.07.28
Java Object 클래스  (0) 2021.07.27
Java 콘솔 입출력(I/O)  (0) 2021.07.14
OOP - 클래스와 객체  (0) 2021.07.13
    '이론/Java' 카테고리의 다른 글
    • java.lang 패키지 / 오토 박싱/ 오토 언박싱
    • Java Object 클래스
    • Java 콘솔 입출력(I/O)
    • OOP - 클래스와 객체
    모달조아
    모달조아

    티스토리툴바