상속
부모 클래스(상위 클래스)와 자식 클래스(하위 클래스)가 있고
자식 클래스는 부모 클래스를 선택해서, 그 부모의 멤버를 상속받아 쓸 수 있는것이 상속이다.
상속을 하는 이유는 이미 만들어진 클래스를 재사용해서 새로운 클래스를 만들기 위함이다.
효율적이고, 개발시간을 줄여준다.
상속받은 모든 필드,메소드를 자식클래스에서 사용할 수 있는것은 아니다.
- 부모클래스의 private 접근제한자를 가지는 필드 및 메소드는 자식이 물려받을수없다.
- 부모와 자식클래스가 서로 다른 패키지에 있다면 부모의 default 접근제한자를 가지는 필드와 메소드에 접근할 수 없다.
- 그 이외의 접근제한자를 가지는 필드와 메소드는 모두 상속의 대상이 된다.
부모 생성자의 호출 - super(...);
자바에서 자식 객체를 생성하면 , 부모 객체를 먼저 생성한 후 자식 객체가 생성됩니다.
public class Parent {
int pVar;
Parent() {
System.out.println("부모클래스 생성자 실행");
}
}
class Child extends Parent{
Child() {
System.out.println("자식클래스 생성자 실행");
}
}
class Test {
public static void main(String[] args) {
Child child = new Child();
}
}
자식클래스 객체 생성시 부모클래스의 생성자가 실행되는것을 확인할 수 있다.
자바는 클래스의 생성자가 생략되어있을경우 컴파일러는 알아서 기본 생성자를 만든다.
자식클래스 생성자에 super()가 생략되었을경우 컴파일러는 알아서 첫줄에 super()를 생성해준다.
class Child extends Parent{
Child() {
//super()가 생략되어있으면 컴파일러가 실행시 생성해줌.
System.out.println("자식클래스 생성자 실행");
}
}
부모에게 기본 생성자는 없고, 매개 변수가 있는 명시적 생성자만 있다면 컴파일러는 기본생성자를 생성해주지않는다.
자식클래스의 생성자에서 반드시 첫줄에서 super(전달인자,전달인자.....)로 부모 생성자를 처리해줘야한다.
컴파일러는 super()로 기본생성자만 처리가능하기 때문이다.
public class Parent {
int pVar;
Parent(int pVar) {
this.pVar = pVar;
System.out.println("부모클래스 생성자 실행");
}
}
class Child extends Parent{
Child() {
super(1000);// 부모클래스의 매개변수가 존재하는 생성자가 존재한다면 해당 생성자에 맞게 super(..)를 처리해줘야한다.
System.out.println("자식클래스 생성자 실행");
}
}
다형성
하나의 객체가 여러가지 타입의 객체를 가질 수 있는것이 다형성이다.
public class Parent {
int pVar;
}
class Child extends Parent{
int childVar;
void childMet() {
System.out.println("자식 메서드");
}
}
class Test {
public static void main(String[] args) {
Parent parent = new Child();
}
}
Parent 참조변수가 Child 인스턴스를 받을 수 있는것이 다형성이다.
유의할점
public static void main(String[] args) {
Parent parent = new Child();
// parent.childMet();
// parent.childVar = 10;
}
하지만 Parent 참조변수는 자신의 클래스에 있는 필드와 메소드만 사용할 수 있으며
자식클래스의 필드와 메소드는 사용 불가능하다. [Child 인스턴스가 자동으로 Parent로 형변환 되기 때문이다.]
하지만 오버라이드 된 메서드는 사용가능하다.
public class Cpu {
Cpu cpu; // 필드의 다형성
void overrideMe() {
System.out.println("오버라이드 전");
}
}
class Intel extends Cpu {
@Override
void overrideMe() {
System.out.println("오버라이드 후");
}
}
class test33 {
public static void main(String[] args) {
Cpu cpu = new Intel();
cpu.overrideMe();
}
}
강제 형변환(casting)
public static void main(String[] args) {
Parent parent = new Child();
Child ptoC = (Child) parent; //자식클래스의 필드나 메소드를 사용하고 싶다면 자식클래스로 강제형변환을 한다.
ptoC.childVar = 100;
ptoC.childMet();
}
자식클래스 참조변수 = (자식클래스) 부모클래스 인스턴스;
자식 타입이 부모 타입으로 자동 변환하면,
부모 타입에 선언된 필드와 메소드만 사용 가능하다는 제약사항이 따르게 되는데
만약 자식 타입에 선언된 필드와 메소드를 꼭 사용해야 한다면 강제 타입 변환을 사용하면 됩니다.
다형성 사용 - 필드,매개변수의 다형성
public class Cpu {
Cpu cpu; // 필드의 다형성
Cpu(Cpu cpu) { // 매개변수의 다형성
this.cpu = cpu;
}
void setCpu(Cpu cpu) { // 매개변수의 다형성
this.cpu = cpu;
}
}
class Intel extends Cpu {
Intel() {
super(new Intel());
}
}
class Amd extends Cpu {
Amd() {
super(new Amd());
}
}
class test33 {
public static void main(String[] args) {
Cpu cpu = new Cpu(new Intel());
cpu.setCpu(new Amd());
}
}
필드,매개변수의 타입을 부모타입으로 설정하여 모든 자식클래스의 타입들을 받을 수 있게 설계하였다.
코드의 수정이 필요하다면 자식클래스의 객체만 바꿔주면되서 코드의 수정이 간결해진다.
'자바 > 기본' 카테고리의 다른 글
try-with-resources (2) | 2024.03.19 |
---|---|
디자인 패턴 - 추상 팩토리 패턴 (1) | 2024.03.15 |
자바 - 클래스 (내부클래스-인스턴스 클래스,static 클래스) (1) | 2024.03.06 |
자바 - 배열 , 제어문 (0) | 2024.03.04 |
댓글