상속

 

클래스 상속

현실에서 상속은 부모가 자식을 선택해서 물려주지만,

프로그램에서는 자식이 부모를 선택

package sec01.exam01;

선언
class Aaa {
	
}
// 부모 
public class Ppp {
	int x;
}

//상속
class Ccc extends Ppp {

}

실행
package sec01.exam01;

public class Ex1 {

	public static void main(String[] args) {
		Ccc ccc = new Ccc();
		ccc.x = 100;
		System.out.println(ccc.x);

	}

}

 

 

자바 상속 특징

1. 여러 개의 부모 클래스를 상속할 수 없음

2. 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외

부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 

메소드도 상속 대상에서 제외됨

 

실습

부모
package sec01.exam01.Phone;

public class CellPhone {
	// 부모
	
	//필드
	String model;
	String color;
	
	//생성자
	

	
	//메소드
	void powerOn() {System.out.println("전원을 켭니다.");}

	void powerOff() {System.out.println("전원을 끕니다.");}
	void bell() {System.out.println("벨이 울립니다.");}
	void sendVoice(String message) {System.out.println("자기:" + message);}
	void receiveVoice(String message) {System.out.println("상대방:" + message);}
	void hangUp() {System.out.println("전화를 끊습니다.");}
}
자식

package sec01.exam01.Phone;

public class DmbCellPhone extends CellPhone {
	//필드
	int channel;
	
	//생성자
	DmbCellPhone(String model, String color, int channel){
		
//		super(); 자동적으로 추가 
		this.model = model; // 부모
		this.color = color;
		this.channel = channel;
	}
	
	//메소드
	
		void turnOnDmb() {
			System.out.println("채널" + channel + "번 DMB 방송 수신을 시작합니다.");
		}
		void changChannelDmb(int channel) {
			this.channel = channel;
			System.out.println("채널" + channel + "번으로 바꿉니다.");
		}
		void turnOffDmb() {
			System.out.println("DMB 방송 수신을 멈춥니다.");
		}
	}
실행

package sec01.exam01.Phone;

public class DmbCellPhoneEx {

	public static void main(String[] args) {
		// DmbCellPhone 객체 생성
		DmbCellPhone dmbCellPhone = new DmbCellPhone("자바폰", "검정", 10 );
		
		// cellPhone 클래스로부터 상속받은 필드
		System.out.println("모델: " + dmbCellPhone.model);
		System.out.println("색상: " + dmbCellPhone.color);
		
		System.out.println("채널: " + dmbCellPhone.channel);
		
		dmbCellPhone.powerOn();// 부모
		dmbCellPhone.bell();
		dmbCellPhone.sendVoice("여보세요");
		dmbCellPhone.receiveVoice("안녕하세요? 저는 홍길동인데요");
		dmbCellPhone.sendVoice("아~ 반갑습니다.");
		dmbCellPhone.hangUp();
		
		dmbCellPhone.turnOnDmb();
		dmbCellPhone.changChannelDmb(12);
		dmbCellPhone.turnOffDmb();

	}
}
결과
모델: 자바폰
색상: 검정
채널: 10
전원을 켭니다.
벨이 울립니다.
자기:여보세요
상대방:안녕하세요? 저는 홍길동인데요
자기:아~ 반갑습니다.
전화를 끊습니다.
채널10번 DMB 방송 수신을 시작합니다.
채널12번으로 바꿉니다.
DMB 방송 수신을 멈춥니다.

 

부모 생성자 호출

현실에서 부모 없는 자식이 있을 수 없듯이 자바에서도 자식 객체를 생성하면, 부모 객체가 먼저 생

성되고 그다음에 자식 객체가 생성됨

DmbCellPhone(자식) 객체만 생성하는 것 처럼 보이지만, 사실은 내부적으로 부모인 CellPhone 객체가 먼

저 생성되고 자식인 DmbCellPhone 객체가 생성 

DmbCellPhone dmbCellPhone = new DmbCellPhone()

모든 객체는 클래스의 생성자를 호출해야만 생성되며, 부모 생성자는 자식 생성자의 맨 첫줄에서 호출됨

예를 들어, DmbCellPhone(자식)의 생성자가 명시적으로 선언되지 않았다면 컴파일러는 밑에 같이 기본

생성자를 생성함

public DmbCellPhone() {
	super();
}

super()는 부모의 기본 생성자

만약에 직접 자식 생성자를 선언하고 명시적으로 부모 생성자를 호출하고 싶다면 다음과 같이 작성

자식클래스( 매개변수선언, ... ){
	super(매개값, ...)
}

super(매개값, .. )는 매개값의 타입과 일치하는 부모 생성자를 호출

매개값의 타입과 일치하는 부모 생성자가 없을 경우 컴파일 에러가 발생

super(매개값, .. )가 생략되면 컴파일러에 의해 super()가 자동적으로 추가되기 때문에 부모의

기본 생성자가 존재해야함

부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자만 있다면 자식 생성자에서 반드시

부모 생성자를 호출을 위해 super(매개값, .. )를 명시적으로 호출해야함

super(매개값, .. )는 반드시 자식 생성자 첫 줄에 위치해야 하며, 그렇지 않으면 컴파일 에러가 발생

 

 

 

 

메소드의 재정의( 오버라이딩 )

부모 클래스의 모든 메소드가 자식 클래스에 맞게 설계되어 있다면 가장 이상적인 상속이지만

어떤 메소드는 자식 클래스가 사용하기에 적합하지 않을 수도 있습니다.

상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해야 합니다.

자바는 이런경우를 위해 메소드 재정의(오버라이딩) 기능을 제공

메소드 재정의 방법

메소드 재정의는 자식 클래스에서 부모 클래스의 메소드를 다시 정의하는 것을 말함

메소드를 재정의할 때는 다음과 같은 규칙에 주의

1. 부모의 메소드와 동일한 시그너처(리턴 타입, 메소드 이름, 매개 변수 목록)을 가져야함

2. 접근 제한을 더 강하게 재정의할 수 없음

3. 새로운 예외를 throws 할 수 없음

접근 제한을 더 강하게 재정의할 수 없다는 것은 부모 메소드가 public 접근 제한을 가지고 있을 경우

재정의하는 자식 메소드는 default나 private 접근 제한으로 수정할 수 없다는 뜻

 

 

실습1

부모

package sec01.exam01.Child01;

public class Parent {
	void method1() {
		System.out.println("부모의 method1");
	}
	void method2() {
		System.out.println("부모의 method2");
	}
}

자식
package sec01.exam01.Child01;

public class Child extends Parent {
	void method2() {
		System.out.println("자식의 method2");
	}
	void method3() {
		System.out.println("자식의 method3");
	}
	void method4() {
		super.method1();
		System.out.println("부모의 method1");
	}
	
	@Override // 재정의 
	void method1() {
		
		super.method1();
	}
	
	
}

재정의된 메소드 호출
package sec01.exam01.Child01;

public class ChildEx {

	public static void main(String[] args) {
		
		Child child = new Child();
		
		child.method1();
		//부모의 method2
		
		child.method2(); // 재정의된 메소드 호출
		//자식의 method2

		child.method3();
		//자식의 method3
		
		child.method4();
		//부모의 method1
		//부모의 method1
	}

}
결과
부모의 method1
자식의 method2
자식의 method3
부모의 method1
부모의 method1

 

 

실습2

부모

package sec01.exam01.Child02;

public class Calculator {
	double areaCircle(double r) {
		System.out.println("Calculator 객체의 areaCircle() 실행 ");
		return 3.14159 * r * r;// 정밀한 계산을 위해 수정
	}
}
자식

package sec01.exam01.Child02;

public class Computer extends Calculator {

	@Override // 재정의
	double areaCircle(double r) {
		System.out.println("Computer 객체의 areaCircle() 실행");
		return Math.PI * r *r;
	}
	
}
실행

package sec01.exam01.Child02;

public class ComputerEx {

	public static void main(String[] args) {
		int r = 10;
		
		Calculator calculator = new Calculator();
		System.out.println("원면적 : " + calculator.areaCircle(r));
		System.out.println();
		
		//computer.areaCircle(r) => 재정의된 메소드 호출
		Computer computer = new Computer();
		System.out.println("원면적 : " + computer.areaCircle(r));

	}

}
결과
Calculator 객체의 areaCircle() 실행 
원면적 : 314.159

Computer 객체의 areaCircle() 실행
원면적 : 314.1592653589793

 

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-06-07 14일차  (0) 2023.06.07
2023-06-02 13일차  (0) 2023.06.02
2023-05-31 11일차  (0) 2023.05.31
2023-05-30 10일차  (0) 2023.05.30
2023-05-26 9일차  (1) 2023.05.26

+ Recent posts