Java 기초 (20) 상속, super, 업캐스팅

코린이서현이·2023년 7월 20일
0

Java

목록 보기
20/46

🤔들어가면서🤔

자바의 상속에 대해서 알아보자. 많은 실제 예제를 가지고 코딩해보면서 익혀보자 

📕 상속

  • 자식클래스(하위클래스)가 부모클래스(상위클래스)를 상속받는다.
	class 하위클래스 extends 상위클래스 {
	}
  • 상위클래스 : 덜 구체적이다.
  • 하위클래스 : 상위클래스의 멤버변수와 메소드를 상속받아 더욱 구체적이다.
    (하위클래스는 상위클래스의 멤버변수나 메소드를 사용할 수 있다. )

🔍 필요한 추가 속성과 기능을 하위클래스를 통해 추가 구현할 수 있다.

📖 상속에서 클래스 생성

🤔 하위 객체를 생성할 때 상위객체의 멤버변수와 메소드를 쓸 수 있는 건 알았다.
그런데 어떻게 쓸 수 있는 걸까?
➡️ 하위클래스 생성자에서 자동으로 상위클래스 생성자를 컴파일 하기 때문이다.
  • 반드시 상위클래스의 생성자가 먼저 호출된다.
	class Extend0 {
	    public Extend0() {
        	System.out.println("Extend0 생성");
        }
    }
  	class Extend1 extends Extend0{
    	public Extend1() {
        	System.out.println("Extend1 생성");
        }
    }
    
    public class Inheritance {
    
   		public static void main(String[] args) {
        		//Extend0을 상속받은 Extend1 객체를 생성
                Extend1 e1 = new Extend1();
        }
    }
    

✍️ 실행화면
먼저 호출되는 것을 확인 할 수 있다.

	Extend0 생성
	Extend1 생성

📒하위클래스내에서 상위클래스생성자 호출 규칙

  1. 상위클래스의 생성자는 super 예약어를 사용한다.
  2. 상위클래스 생성자는 첫줄에 위치해야한다.
  3. 상위클래스 생성자에 매개변수가 있는 직접만든 생성자라면, 하위클래스에서 직접 생성자를 추가해야한다.
  4. 하위클래스에서 상위클래스생성자의 매개변수를 받아야한다.
  class Extend0 {	
      //상위클래스에 매개변수가 있는 경우 → 명시적으로 상위생성자 추가 필요
      public Extend0(int i) {
      }

  class Extend1 extends Extend0 {
  	  //하위클래스에서 상위클래스 생성자를 super예약어를 통해 작성
      public Extend1(int i) {
      	//첫 줄에 작성 & 동일한 타입의 매개변수
          super(i);
      }

📖 super예약어

  • 하위 클래스에서 상위클래스를 부르는 예약어이다.
    ⚠️ 동일한 이름의 멤버 변수나 메소드가 있을 때 상위클래스의 멤버변수나 메소드를 참조하기 위해서는 super예약어가 필수이다.

사용방법
1. 하위생성자에서 상위클래스 생성자 작성 : super();
2. 상위클래스 멤버변수참조 : super.상위클래스멤버변수;
3. 상위클래스 메소드 참조 : super.상위클래스메소드();

✍️ 예시코드2. 상위클래스 멤버변수참조


//상위 클래스 생성
class Extend0 {
	int i;
	//i값을 0으로 설정
	public Extend0() {
		this.i = 0;
	}
	
}
//하위 클래스 생성
class Extend1 extends Extend0 {
	int i;
	//i값을 1로 설정
	public Extend1() {
		this.i = 1;
	}
	//상위 i값 반환
	int getsuperI() {
		return super.i;
	}
}

public class Inheritance {

	public static void main(String[] args) {
		Extend1 e1 = new Extend1();
		

		System.out.println("extend1의 i값: "+e1.i);				  // 1	
		System.out.println("extend1의 상위 i값: "+e1.getsuperI());	// 0
	
		
	}
}

✍️ 실행화면

extend1의 i값: 1
extend1의 상위 i값: 0

➕ 한번 더 생각해보기 : Extend1 하위 클래스가 있다면?

<//상위 클래스 생성
class Extend0 {
	int i;
	//i값을 0으로 설정
	public Extend0() {
		this.i = 0;
	}
	
}
//하위 클래스 생성
class Extend1 extends Extend0 {
	int i;
	//i값을 1로 설정
	public Extend1() {
		this.i = 1;
	}
	//상위 i값 반환
	int getsuperI() {
		return super.i;
	}
}
//Extend2는 Extend1의 하위클래스
class Extend2 extends Extend1{
	int i;

	public Extend2() {
		this.i = 2;
	}

}

public class Inheritance {

	public static void main(String[] args) {
		Extend0 e0 = new Extend0();
		Extend1 e1 = new Extend1();
		Extend2 e2 = new Extend2();
		

		System.out.println("extend0의 i값: "+e0.i);							//0
		System.out.println("extend1의 i값: "+e1.i);							//1
		System.out.println("extend1의 상위 클래스의 i값: "+e1.getsuperI());	//0
		System.out.println("extend2의 i값: "+e2.i);							//2
		System.out.println("extend2의 상위 클래스의 i값: "+e2.getsuperI());	//0
		//getsuperI()는 e2의 상위클래스인 e1의 메소드: 따라서 e1의 상위클래스인 e0의 i값 반환
		
	}
}

✍️ 실행화면

extend0의 i값: 0
extend1의 i값: 1
extend1의 상위 클래스의 i값: 0
extend2의 i값: 2
extend2의 상위 클래스의 i값: 0

🔍 e2에게도 getsuperI()가 있다면 어떨까?

📖 메소드 오버라이딩

  • 상위클래스에서 정의한 메소드를 하위클래스에서 재정의하는 것
    메소드의 이름이 같더라도 현재객체의 메소드를 실행한다.

📒 오버라이딩 방법

반환형, 메소드 이름, 매개변수 개수, 매개변수 타입이 동일해야한다.
@Override로 컴파일러에게 알려준다. (없어도 실행이 되기는 하지만 써야함!!)

//Extend2는 Extend1의 하위클래스
class Extend2 extends Extend1{
	int i;

	public Extend2() {
		this.i = 2;
	}
    @Override
	int getsuperI() {
		return super.i;
	}

}
public class Inheritance {

	public static void main(String[] args) {
		Extend0 e1 = new Extend0();
        Extend1 e1 = new Extend1();
		Extend2 e2 = new Extend2();
		

		System.out.println("extend0의 i값: "+e0.i);							//0
		System.out.println("extend1의 i값: "+e1.i);							//1
		System.out.println("extend1의 상위 클래스의 i값: "+e1.getsuperI());	//0
		System.out.println("extend2의 i값: "+e2.i);							//2
		System.out.println("extend2의 상위 클래스의 i값: "+e2.getsuperI());	//1
		//e2의 오버라이딩된 getsuperI()호출 : e2의 부모클래스인 e1값 호출
		
	}
}

✍️ 실행화면
오버라이딩 전: extend2의 상위 클래스의 i값: 0
오버라이딩 후: extend2의 상위 클래스의 i값 : 1

  extend0의 i값: 0
  extend1의 i값: 1
  extend1의 상위 클래스의 i값: 0
  extend2의 i값: 2
  extend2의 상위 클래스의 i값: 1

📖 상위클래스로 묵시적 형변환

  • 하위클래스의 인스턴스를 상위클래스로 클래스 형변환하여 사용할 수 있다.
	//상위클래스 클래스명 = new 하위클래스의 생성자;
    Extend0 e00 = new Extend1();

📒 상위클래스로 형변환 한 경우

  1. 상위클래스의 멤버 변수, 메소드 👉 ⭕
  2. 생성클래스의 멤버 변수, 메소드 👉 ❌
  3. 생성클래스에서 상위클래스의 메소드가 오버라이딩 된 경우 👉 ⭕
    : 상위클래스와 하위 클래스에 같은 이름의 메서드가 존재할 때 호출되는 메소드는
    생성된 인스턴스 메소드를 호출한다. (가상메서드))

➕ 자바의 메모리 공간

스택영역 : 지역변수,참조변수등이 저장되는 곳
힙영역 : 인스턴스가 저장되는 영역
메소드영역(코드영역) : 메소드가 저장되는 영역

👉 같은 객체의 인스턴스들은 동일한 메소드 영역을 참조해서 사용한다.

➕ 가상메모리테이블

: 각 메소드 이름과 실제 메소드가 저장된 메모리주소

📖 가상메서드

싱위클래스형으로 묵시적 형변환을 한 인스턴스에 오버라이딩된 메서드가 존재할 때 생성된 인스턴스의 메서드가 실행된다.

✍️ 예시코드

		Extend0 e00 = new Extend1();

		//상위클래스로 형변환이 된 경우에는 본래 클래스의 변수를 사용할 수 없다.
		System.out.println(e00.e0);			//가능
//		System.out.println(e00.e1);		//오류
		
		//상위클래스로 형변환이 된 경우에는 본래 클래스의 메소드를 사용할 수 없다.
		e00.extend0f();				//가능
//		newe1.extend1f();			//오류
	
		//오버라이딩 된 경우에만 본래 클래스의 메소드 사용가능
		e00.extendf();

🤔마무리하면서🤔

조금 뒤죽박죽으로 정리를 한 것 같긴하다...
profile
24년도까지 프로젝트 두개를 마치고 25년에는 개발 팀장을 할 수 있는 실력이 되자!

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

좋은 글 감사합니다!

답글 달기