- 상속 (inheritance)

  1. 기존에 선언된 클래스의 필드를 다른 클래스에서 사용하고자 할 때
  2. 클래스들을 만들다 보니 공통 요소가 보여서 부모로 묶은 후 상속시켜 주어서 사용하고자 할 때
class A {
     A의 필드
}

class B extends A { // 관계성만 정의 
      B의 필드 
}

B b = new B();
// b객체는 실제로는 A의 필드 B의 필드 둘 다 가지고 있다.

A : 부모 클래스, 상위 클래스, 슈퍼 클래스, 기반 클래스

B : 자식 클래스, 하위 클래스, 서브 클래스, 파생 클래스

 

 
 
상속 보충 설명

 

SuperCar extends Car을 하면 SuperCar 클래스에는 부모 클래스 인 Car필드와 SuperCar 필드가 존재한다.

따라서 mycar 객체는 Car 클래스의 변수, 메소드와 SuperCar 클래스의 메소드를 사용할 수 있다.

 

 

 

- 자식 클래스의 생성자 호출 시 일어나는 일

자식 클래스의 객체는 자식 생성자를 호출하여 객체화를 진행한다.

메모리에 자식 클래스의 필드만 올라갔다면 자식 객체로 절대 부모 클래스에 선언되어있는 필드에 접근할 수 없다.

따라서 자식 생성자를 호출하게되면 상속받고 있는 클래스가 있는지 확인 후 부모의 생성자가 자동으로 먼저 호출된다.

(부모의 필드가 먼저 만들어진다.)

그 이 후 자식 객체는 부모 필드가 먼저 메모리에 생성되어있기 때문에 그 필드 쪽에 접근할 수 있게 된다.

→ 따라서 자식 생성자 첫 줄에는 항상!! super 클래스의 생성자가 호출된다.

명시적으로 적지 않으면 보이지 않지만 super() 호출이 되어있다. (super : 부모의 기본 생성자를 의미)

 


 

- 다형성 (Polymorphism)

1. 오버로딩 (Overloading)

같은 이름의 메소드를 여러 개 불러오는 (선언하는) 기법

매개 변수의 개수 혹은 타입이 다르면 같은 이름의 메소드로 여러 개를 선언할 수 있다.

→ 이름이 아닌 매개변수로 메소드를 구분하기 때문이다.

 

 

2. 오버라이딩 (Overriding) : 재정의

부모 필드에 이미 a()라는 메소드가 존재한다며 자식 객체 생성 시 부모 생성자가 먼저 호출되기 때문에 부모 클래스의 a()가 먼저 메모리에 올라간다. 그다음 자식의 필드를 완성시킬 때 같은 이름의 a()라는 메소드가 선언되어 있다면, 같은 이름의 두 개가 만들어지는 것이 아니라 기존에 만들어진 부모 필드의 a() 메소드에 자식에게 작성한 메소드 내용이 덮어씌워 지게 된다.

그러므로 자식 객체 a() 메소드를 사용하게 되면 재정의된 기능으로 사용하며 이를 "오버 라이딩"이라고 한다.

 


상속, 오버라이딩 사용해보기!

 

 

부모클래스 만들기

 

자식 클래스 만들기

 

메인메소드에서 사용하기

 

- 부모 클래스

public class Car {
	// 부모 클래스
	String brand;
	String color;
	int price;
	public Car() {}
	
	// Alt + Shift + O로 만듬 
	public Car(String brand, String color, int price) {
		this.brand = brand;
		this.color = color;
		this.price = price;
	}


	void engineStart() {
		System.out.println(brand + " 열쇠로 시동 켜기");
	}
	
	void engineStop() {
		System.out.println(brand + " 열쇠로 시동 끄기");
	}
}

 

 

- 자식 클래스

public class SuperCar extends Car{
	// 자식 클래스
	String pw;

	public SuperCar() {
		super();
	}
	
	// Alt + Shift + S > O
	public SuperCar(String brand, String color, int price) {
		super(brand, color, price);
	}
	
	public SuperCar(String pw) {
		this.pw = pw;
	}

	// Alt + shift + S > v 하면 오버라이드할수 있는 메소드가 나오고 선택해서 오버라이드 하면된다!
	// 오버라이드
	@Override
	void engineStart() {
		System.out.println(brand+ " 지문으로 시동켜기");
	}

	@Override
	void engineStop() {
		System.out.println(brand + " 지문으로 시동끄기");
	}
	
	void roofOpen() {
		System.out.println(brand + " 뚜껑 열기");
	}
	
	void roofClose() {
		System.out.println(brand+ " 뚜껑 닫기");
	}
	
}

 

 

- 메인 메소드

public class Road {
	// 메인메소드에서 사용하기!
	public static void main(String[] args) {
		SuperCar mycar = new SuperCar("Ferrari", "Red", 65000);
		Car momcar = new Car("K7", "White", 7000);
		
		mycar.engineStart();
		momcar.engineStart();
	}
}

- 업 캐스팅(Up Casting) : 상속이 기본 조건

부모 타입의 객체에 자식 필드의 주소 값을 담아주는 것이다.

 

 

- 업 캐스팅의 특징

업 캐스팅된 객체는 자식 클래스에서 추가된 내용을 사용할 수 없다.

단, 오버 라이딩된 메소드는 덮어 씌워진 내용이기 때문에 사용이 가능하다.

 

 

- 업 캐스팅 만드는 법

  1. 부모 타입의 객체에 자식 생성자 호출
  2. 부모타입의 객체에 자식 객체가 담고 있던 값을 대입 (자식 필드의 주소 값 대입)
  3. 부모 타입의 매개변수에 자식 객체 넘겨주기

 

 

 

업 캐스팅 보충 설명

 

위 그림에서 Car mycar = new SuperCar();로 만들었다. 이것이 업 캐스팅이다.

여기서 SuperCar로 생성자를 만들었기 때문에 필드는 "자식 필드"로 만들어지지만, 부모인 Car로 객체를 만들었기 때문에 사용할 수 있는 범위는 "부모인 Car" 만큼으로 제한된다.

따라서 SuperCar의 메소드 roofOpen()은 사용하지 못하지만 오버 라이딩된 engineStart()는 사용 가능하다.

 (Car의 engineStart()는 "열쇠로 시동 켜기"를 출력하고, SuperCar의 engineStart()는 "지문으로 시동켜기"를 출력한다.)

 


업 캐스팅 사용해보기!

 

업 캐스팅

- 다운 캐스팅 (Down Casting) : 업 캐스팅이 기본 조건

업 캐스팅된 객체를 다시 자식 타입으로 바꾸는

업 캐스팅된 객체에 다시 자식 클래스의 필드를 달아주는 것

업 캐스팅 시 잘려나갔던 자식 클래스의 추가된 내용들을 다시 사용할 수 있게 하려면 자식 타입으로 바꿔줘야 한다.

 

- 다운캐스팅 하는 방법

(자식 클래스) 업 캐스팅된 객체

 


 

- instanceof

객체 instanceof 클래스명 : 앞에 있는 객체가 뒤에 오는 클래스 타입인지를 비교한다.

→  true/ false로 나오는 조건식이다.

 

부모 객체 instanceof 부모 클래스 : true

자식 객체 instanceof 자식 클래스 : true

부모 객체 instanceof 자식 클래스 : false

자식 객체 instanceof 부모 클래스 : true

업 캐스팅된 객체 instanceof 부모클래스 : true

업캐스팅된객체 instanceof 자식 클래스 : true

 

복사했습니다!