상속(Inheritance)

2020. 3. 11. 09:34자바 Java/자바 공부 java study

반응형

상속이란

 

상속이란 어떤 클래스가 다른 클래스의 멤버 변수와 멤버 함수를 물려받는  것

상속은 원래의 것에 이어 붙이는 개념 

상속이라고 생각하지말고 extend! 부모클래스에서 확장된 객체를 갖게 된다고 생각하자. 

 

상속받는 클래스-> 자식 클래스, 하위 클래스 또는 서브 클래스

상속을 해주는 클래스-> 부모 클래스, 상위 클래스 또는 슈퍼 클래스

 

 

  • 부모 클래스(parent class) 와 자식 클래스(children class)는 자바 지정예약어 extends에 의하여 정해진다.

  • 하나의 부모 클래스(parent class)는 여러개의 자식 클래스(children)을 가질 수 있다.

  • 반대로 하나의 클래스는 여러개의 클래스로부터 상속을 받을수는 없다. ->즉 단일 상속만 가능 하다. 
    (인스턴스를 사용하여 다중상속을 할 수 있다. ) 

  • 부모 클래스(parent class)로부터 상속받은 자식 클래스는 부모 클래스의 자원(source) 모두를 사용 할 수 있다.

  • 반대로 부모클래스는 자식클래스의 자원을 가져다 쓸 수는 없다.

  • 자식클래스는 또다른 클래스의 부모 클래스가 될 수 있다. 

  • 자식클래스는 부모클래스로부터 물려받은 자원을 override 하여 수정해서 사용 할 수 있다.

  • 부모클래스가 상속받은 자원도 자식클래스가 사용 가능하다.

 

* 자식 클래스가 더 다양한 기능이 가능하므로 자식 클래스로 인스턴스를 생성하는 것이 효율 적이다. 

만약 동일한 이름의 변수가 상위 클래스와 하위 클래스에 존재하면 상위 클래스의 변수는 가려진다.

static 변수도 상속 가능

하위클래스에서 객체 생성시 메모리 할당

 단, 접근제어자가 private을 갖는 필드나 메소드는 상속이 불가하고, 패키지가 다를 경우 접근제어자가 default인 경우도 상속이 불가하다.

 

 

 

 

상속을 쓰는 이유 

 

기존 클래스의 필드와 메소드 같은 자원의 재사용성을 높이고 자원을 변형하거나 추가,변경하는 역할을 한다. 

기존 클래스의 일부 변경도 가능 코드의 간결성 향상 

상속은 이미 작성된 검증된 스프트웨어를 재사용

신뢰성 있는 소프트웨어를 손쉽게 개발, 유지 보수

코드의 중복을 줄일수 있다. 

 

 

 

 

상속의 사용 방법(선언) 

 

상속의 키워드 : extends 

 상속을 받는 방법은 간단하다. 상속받을 자식 클래스 뒤에 extends 키워드를 사용하고 부모 클래스를 적어주면 된다.

 

super

- this 는 자기자신의 멤버필드를 사용할때 객체를 생성하지않고 접근할 수 있는 지정예약어,  super는 자신의 부모의 멤버필드에 접근하는 지정예약어이다. this와마찬가지로 생략하여 사용 할 수있다. 

  • super() 는 부모의 생성자를 의미한다.
  • 부모의 생성자를 임의로 호출하지 않으면, 부모 class의 기본 생성자가 자동으로 호출된다.
    (오버라이드 하는 경우에서 부모의 메소드를 그대로 가져다 쓸 때를 제외하고 오버라이드를 통해 메소드를 재정의 하려고 할때는 super()을 쓰면 부모의 메소드도 호출하게 된다. )

 

메소드 재정의 (method overriding) : 서브 클래스가 필요에 따라 상속된 메소드를 다시 정의 하는 것 

override 는 한글로 '보수'이라는 의미입니다. 보수 공사 하다 할때 그 보수요 ! 부모에게서 물려받은 자원을 그대로 사용해도 되지만, 조금 변형시켜 사용하고자 할 때 자원을 override 하여 사용합니다.

메소드 재정의 하려면 메소드의 이름 반환형, 매개변수의 개수와 데이터 타입이 일치해야 한다. 
예를 들어 부모와 자식클래스가 같은 이름의 메소드를 가지고 있을 경우 자식

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

예를 봐보자 

 

 

여기 부모클래스인 Car 클래스가 있다. 

public class Car {
	int speed;
	int gear;
	String color;

	public void speedUp(int increment) {
		speed += increment;
	}

	public void speedDown(int decrement) {
		speed -= decrement;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public int getGear() {
		return gear;
	}

	public void setGear(int gear) {
		this.gear = gear;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}

 

 

그리고 SportsCar 는 Car 클래스를 상속받은 자식 클래스이다. 

 

 

public class SportsCar extends Car {
	public boolean turbo;

	public boolean isTurbo() {
		return turbo;
	}

	public void setTurbo(boolean turbo) {
		this.turbo = turbo;
	}

}

 

자식 클래스인 SportsCar는 부모클래스와 다르게 isTurbo 메소드와 setTurbo 메소드를 가지고 있다. 

 

 

public class CarTest {

	public static void main(String[] args) {

		SportsCar sCar = new SportsCar();

		sCar.setColor("RED");
		sCar.setGear(3);
		sCar.speedUp(100);

		sCar.setTurbo(true);
	}

}

 

다음과 같이 메모리에 그려진다.  SportsCar는 부모인 Car클래스로 부터 받은 gear, color, speed, 와 SportsCar의  turbo 메소드를 가진 새로운 객체를 만든다.  그리고 sCar는 이 주소를 참조한다. 

<heap 영역> 

gear

color

speed

turbo

 

 

 

super를 이용한 예제 

 

class Parent {
	int data = 100;

	public void print() {
		System.out.println("부모임");
	}
}

class Child extends Parent {
	int data = 200;

	public void print() {
		int data = 300;
		super.print();    
		System.out.println("자식임");
		System.out.println("data : " + data);  // 지역변수 불러옴 
		System.out.println("this.data: " + this.data);  // this 가 붙었으므로 객체의 멤버변수 부름 . 
		System.out.println("super.data: " + super.data);  //super가 붙었으니 부모의 데이터 부름 
	}
}

public class ParentTest {

	public static void main(String[] args) {
//		new Child().print();
		Child c = new Child();
		c.print();
// 부모임
// 자식임
// data : 300
// this.data : 200     //int data=200; 지우면 this data=100 나옴 
// super.data : 100
	}

}

 

 

 

객체의 실제 타입을 알아내는 방법 

 

instanceof 연산자를 사용한다 

   [참조변수] instanceof [타입] -> 참조변수가 타입의 객체를 참조할 수 있다면  true 아니면  false

 

 

 

 

 

final 관련 키워드 정리 => 다시 정리 

 

final 클래스 : 상속할수 없는 클래스

final 메소드 : 재정의 할 수 없는 메소드

- final 필드 : 값을 변경할 수 없는 필드

 

 

 

 

자식 클래스가 부모클래스로 부터 상속받는 상속 관계가 형성되면

자식클래스의 객체를 인스턴스화 할때,  부모타입으로 가능하게 된다. 

package d02;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Academy computer=new Computer(); //  Academy 가 부모클래스, Computer,English,Piano가 자식클래스. 
		 Academy english=new English();
		Academy piano=new Piano();
		 
         
         //당연히,  Computer computer =new Computer(); 와 같이 자기자신 타입으로 자식클래스의 객체를 인스턴스로 만드는것이 가능하다 

 

 

 

1. 객체 형 변환의 개요

 

Parent parent = new Child();

 

위의 대입연산에서 왼쪽 항(Parent)과 오른쪽 항(Child)의 객체 유형이 서로 다른 경우, 두 유형이 서로 상속 관계에 있고 왼쪽 객체(Parent)가 오른쪽 객체(Child)의 상위 클래스인 경우에만 내부적인 형 변환이 일어난다. 즉, 하위 클래스에서 상위클래스 유형으로 할당하는 것은 가능하나 그 반대의 경우에는 강제 형 변환을 해야 한다. 그러나 상위 클래스 유형을 하위 클래스 유형으로 강제 형 변환하는 경우에는 할당되는 인스턴스 유형에 따라서 실행 오류가 발생할 수 있다.



2. 오버라이딩(Overriding)된 메소드의 호출

 

대입연산에 의해 객체의 유형이 변환될 수 있다. 형 변환에 참여한 서로 상속관계에 있는 두 클래스 간에는 동일한 이름의 변수가 존재하거나 메소드가 오버라이딩되어 있을 수 있는데, 이와 같은 경우에 생성된 객체 변수를 통해 멤버에 접근하는 데는 주의해야 할 점이 있다.

 

변수에 대한 접근은 객체의 유형에 의해 결정되며, 메소드 호출은 new 로 할당된 인스턴스에 의해 결정된다.

 


위의 Parent 클래스와 Parent 를 상속받은 Child 클래스가 있다.

 

(1) 상위 클래스 = 상위 클래스

 


(2) 하위 클래스 = 하위 클래스

(3) 상위 클래스 = 하위 클래스

 

(4) 하위 클래스 = (Casting) 상위 클래스

 

 

 

 

3. 인터페이스의 형 변환

 

인터페이스의 경우도 클래스는 클래스가 구현하고 있는 인터페이스 유형으로도 변환할 수 있다. 즉, 왼쪽 항에 있는 인터페이스 유형의 객체 참조변수에 그 인터페이스를 구현하고 있는 클래스의 객체 오른쪽 항에 두어 할당할 수 있다.

이 경우도 클래스의 형 변환과 마찬가지로 인터페이스 유형의 객체 참조변수는 인터페이스에 선언된 요소에만 접근할 수 있으며, 변환된 객체를 가지고 인터페이스를 구현하고 있는 클래스에서 선언한 요소에 접근하면 에러가 발생하게 된다.




 

 

 

 

반응형