Part7 상속

상속

  • 상속이란? 부모가 가진것을 자식에게 물려주는 것을 의미한다.
    • 노트북은 컴퓨터의 한 종류다.
    • 침대는 가구의 한 종류다. 혹은 침대는 가구다.
    • 소방차는 자동차다.

이렇게 말할 수 있는 관계를 is a 관계 혹은 kind of 관계라고 한다.

  • Car를 상속받은 Bus를 class로 표현하는 방법
    • 자바는 클래스 이름 뒤에 extends 키워드를 적고 부모 클래스 이름을 적게 되면 부모 클래스가 가지고 있는 것을 상속받을 수 있게 된다.
    • 상속이란 부모가 가지고 있는 것을 자식이 물려받는 것을 말한다. 즉, 부모가 가지고 있는 것을 자식이 사용할 수 있께 된다.
    public class Car{

    }

    public class Bus extends Car{

    }
  • 부모 클래스와 자식 클래스의 메소드
    • 자식 클래스는 부모 클래스에 선언된 메소드를 사용할 수 있다.
    • 자식 클래스는 부모가 가지고 있는 메소드 외에 추가로 메소드를 선언할 수 있다.
      • 이것을 확장하였다고 표현한다.

접근제한자

접근 제한자란 클래스 내에서 멤버의 접근을 제한하는 역할을 한다.

  • 접근 제한자의 종류
    • public
      • 어떤 클래스든 접근할 수 있다는 것을 의미
    • protected
      • 자기 자신, 같은 패키지, 서로 다른 패키지다 하더라도 상속받은 자식 클래스에서는 접근할 수 있다는 것을 의미
    • private
      • 자기 자신만 접근할 수 있다는 것을 의미
    • 접근제한자를 적지 않으면 default 접근 지정자
      • 자기자신과 같은 패키지에서만 접근할 수 있다는 것을 의미(상속X)
    • public > protectd > default > private

추상클래스

추상 클래스란 구체적이지 않은 클래스를 의미한다. 독수리, 타조는 구체적인 새를 지칭하는데 새, 포유류 같은 것은 구체적이지 않다.

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

        public void fly(){
            System.out.println("날다.");
        }
    }
  • 추상 클래스를 상속받는 클래스 생성하기
    • 추상 클래스를 상속받은 클래스는 추상 클래스가 갖고 있는 추상 메소드를 반드시 구현해야 한다.
    • 추상 클래스를 상속받고, 추상 클래스가 갖고 있는 추상 메소드를 구현하지 않으면 해당 클래스도 추상 클래스가 된다.

super와 부모생성자

  • class가 인스턴스화 될 때 생성자가 실행되면서 객체의 초기화를 한다. 그 때 자신의 생성자만 실행이 되는 것이 아니고, 부모의 생성자부터 실행된다.
    • new 연산자로 자식 객체를 생성하면, 자식객체가 메모리에 올라갈 때 부모인 객체도 함께 메모리에 올라간다.
    • 생성자는 객체를 초기화 하는 일을한다.
    • 생성자가 호출될 때 자동으로 부모의 생성자가 호출되면서 부모객체를 초기화 하게된다.
  • super
    • 자신을 가리키는 키워드가 this 라면, 부모를 가리키는 키워드는 super
    • super()는 부모의 생성자를 의미한다.
    • 부모의 생성자를 임의로 호출하지 않으면, 부모 class의 기본 생성자가 자동으로 호출된다.
  • 부모의 기본생성자가 아닌 다른 생성자를 호출하는 방법
    • 클래스는 기본 생성자가 없는 경우도 존재한다.
    public Bus(){
        super("소방차"); // 문자열을 매개변수로 받는 부모 생성자를 호출하였다.
        System.out.println("Bus의 기본생성자입니다.");
    }

super 키워드는 자식에서 부모의 메소드나 필드를 사용할 때도 사용한다.

오버라이딩

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

  • 메소드 오버라이딩
    • 메소드를 오버라이드 하면, 항상 자식클래스에서 정의된 메소드가 호출된다.
    • 오버라이딩 한다고 해서 부모의 메소드가 사라지는 것은 아니다.
      • super 키워드를 이용하면, 부모의 메소드를 호출 할 수 있다.
    //run 메소드를 가지고 있는  Car클래스 
    public class Car{
        public void run(){
            System.out.println("Car의 run메소드");
        }
    }

    //Car 를 상속받는 Bus 클래스 
    public class Bus extends Car{

    }
    
    //오버라이딩
    public class Bus extends Car{
        public void run(){
            System.out.println("Bus의 run메소드");
        }
    }
  
    //super 키워드
    public class Bus extends Car{
        public void run(){
            **super.run();**  // 부모의  run()메소드를 호출 
            System.out.println("Bus의 run메소드");
        }
    }

오버라이딩 vs 오버로딩
오버로딩(Overloading) : 같은 이름의 메소드를 여러개를 가지면서 매개변수의 유형과 개수가 다르도록 하는 기술
오버라이딩(Overriding) : 상위 클래스가 가지고 있는 메소드를 하위 클래스가 재정의해서 사용

클래스 형변환

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

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

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

상속 관계란 is a 관계다. “Bus는 Car다.”라는 관계가 성립된다.

  • 부모타입으로 자식객체를 참조할 수 있다.
    • 부모타입으로 자식객체를 참조하게 되면 부모가 있는 메소드만 사용할 수 있다.
    public class BusExam{
        public static void main(String args[]){
            Car car = new Bus();
            car.run();
            car.ppangppang(); // 컴파일 오류 발생
        }
    }
  • ppangppang()메소드를 호출하고 싶다면 Bus 타입의 참조변수로 참조 해야한다.
    public class BusExam{
        public static void main(String args[]){
            Car car = new Bus();
            car.run();
            //car.ppangppang(); // 컴파일 오류 발생

            Bus bus = (Bus)car;  //부모타입을 자식타입으로 형변환 
            bus.run();
            bus.ppangppang();
        }
    }
  • 객체들 끼리도 형변환이 가능하다. 단 상속관계에 있었을 때만 가능하다.
  • 부모타입으로 자식타입의 객체를 참조할 때는 묵시적으로 형변환이 일어난다.
  • 부모타입의 객체를 자식타입으로 참조하게 할 때는 명시적으로 형변환 해주어야 한다. 단, 이렇게 형변활 할때에는 부모가 참조하는 인스턴스가 형변환 하려는 자식타입일 때만 가능하다.

과연 이 형변환을 왜 언제 사용할까! 라는 의문을 가졌다면,,,, 이런 상황들을 생각해보자
첫번째, VIP 회원을 VVIP 회원으로 등급을 올려줄 때
두번째, 모험가 직업을 가진 플레이어가 전사 직업을 가지게 되었을 때…
보통 다형성을 활용하려고 사용한다고 한다… 코드 한줄만 바꿔도 돌아갈수 있도록…?

댓글남기기