
안녕하세요:) 오늘은 김영한 강사님의
실전 자바 기본편 강의 요약 정리 3편입니다!
목차
09. 상속
10. 다형성
09. 상속
상속관계
상속은 객체 지향 프로그래밍의 핵심 요소 중 하나!
기존 클래스의 필드와 메서드를 새로운 클래스에서 재사용하게 해준다. 기존 클래스의 속성과 기능을 그대로 물려받는 것!
+ extends 키워드 사용 +대상은 하나만 선택 가능
용어
● 부모 클래스(슈퍼 클래스): 상속을 통해 자신의 필드와 메서드를 다른 클래스에 제공하는 클래스
● 자식 클래스 (서브 클래스): 부모 클래스로부터 필드와 메서드를 상속받는 클래스
코드로 살펴보자
public class Car {
public void move() {
System.out.println("차를 이동합니다.");
}
}
public class ElectricCar extends Car {
public void charge() {
System.out.println("충전합니다.");
}
}
public class GasCar extends Car {
public void fillUp() {
System.out.println("기름을 주유합니다.");
}
}
public class CarMain {
public static void main(String[] args) {
ElectricCar electricCar = new ElectricCar();
electricCar.move();
electricCar.charge();
GasCar gasCar = new GasCar();
gasCar.move();
gasCar.fillUp();
}
}
/* 실행결과
차를 이동합니다.
충전합니다.
차를 이동합니다.
기름을 주유합니다.*/
위 코드에서 전기차와 가솔린차가 Car 를 상속 받은 덕분에 electricCar.move() , gasCar.move() 를 사용할 수 있다.
자바는 다중 상속을 지원하지 않아 extend 대상은 하나만 선택할 수 있다. → 단일 상속
상속과 메모리 구조
● 상속 관계의 객체를 생성하면 그 내부에는 부모와 자식이 모두 생성된다.
● 상속 관계의 객체를 호출할 때, 대상 타입을 정해야 한다. 이때 호출자의 타입을 통해 대상 타입을 찾는다.
● 현재 타입에서 기능을 찾지 못하면 상위 부모 타입으로 기능을 찾아서 실행한다.
+상속은 기능 추가와 클래스 확장에 용이
상속과 메서드 오버라이딩
메서드 오버라이딩(Overriding)은 부모에게서 상속 받은 기능을 자식이 재정의 하는 것이다.
메서드 이름은 같지만 새로운 기능을 사용하고 싶을 때 사용한다!
가령, move()에 기본적으로 "차를 이동합니다." 로 되어 있지만 전기차의 경우 "전기차를 빠르게 이동합니다"라고 하고 싶다면 메서드 오버라이딩을 아래와 같이 쓸 수 있다.
public class ElectricCar extends Car {
@Override
public void move() {
System.out.println("전기차를 빠르게 이동합니다.");
}
public void charge() {
System.out.println("충전합니다.");
}
}
이때 @ 이 붙은 부분을 애노테이션이라 부르고 프로그램이 읽을 수 있는 특별한 주석이라고 생각하면 된다.
이전에 메서드 오버로드를 배운 적이 있다. 차이를 알아보자
오버로딩(Overloading)과 오버라이딩(Overriding)
● 메서드 오버로딩: 메서드 이름이 같고 매개변수(파라미터)가 다른 메서드를 여러개 정의하는 것 (같은 이름의 메서드를 여러개 정의했다는 의미)
● 메서드 오버라이딩: 메서드 오버라이딩은 하위 클래스에서 상위 클래스의 메서드를 재정의하는 과정(메서드 재정의)
오버라이딩 조건
● 메서드 이름 =
● 매개변수(파라미터) 타입, 순서, 개수 =
● 접근제어자 제한: 하위 클래스가 상위클래스의 접근제어자보다 제한적이면 안됨
● static, final, private 키워드가 붙은 메서드는 오버라이딩 X
(static은 클래스 레벨에서 작동하므로 인스턴스 레벨에서 사용하는 오버라이딩 의미x, final은 재정의 금지, private은 해당 클래스에서만 사용 가능)
● 생성자는 오버라이딩 불가능
● 예외: 오버라이딩 메서드는 상위 클래스의 메서드보다 더 많은 체크 예외를 throws 로 선언할 수 없다.
하지만 더 적거나 같은 수의 예외, 또는 하위 타입의 예외는 선언할 수 있다.
super - 부모참조
오버라이딩을 하였거나 (부모, 자식 클래스 속)필드의 이름이 동일할때 부모 클래스 기능을 사용하고 싶다면?
: super 를 사용! e.g. super.value
super - 생성자
상속 관계의 인스턴스를 생성하면 메모리 내부에는 자식과 부모 클래스가 각각 다 만들어진다
따라서! 자식 클래스의 생성자에서 부모 클래스의 생성자를 반드시 호출해야 한다.(규칙)
상속 관계에서 부모의 생성자를 호출할 때는 super(...) 를 사용하면 된다.
ClassA(최상위클래스)
public class ClassA {
public ClassA() {
System.out.println("ClassA 생성자");
}
}
ClassB
public class ClassB extends ClassA {
public ClassB(int a) {
this(a, 0); //기본 생성자 생략 가능
System.out.println("ClassB 생성자 a=" + a);
}
public ClassB(int a, int b) {
super(); //기본 생성자 생략 가능
System.out.println("ClassB 생성자 a=" + a + " b=" + b);
}
}
ClassC
public class ClassC extends ClassB {
public ClassC() {
super(10, 20);
System.out.println("ClassC 생성자");
}
}
Super2Main
public class Super2Main {
public static void main(String[] args) {
//ClassC classC = new ClassC();
ClassB classB = new ClassB(100);
}
}
/*실행결과
ClassA 생성자
ClassB 생성자 a=10 b=20
ClassC 생성자
*/
정리
● 상속 관계의 생성자 호출은 부모에서 자식 순서로 실행된다. (부모의 데이터를 먼저 초기화→ 자식 데이터 초기화)
● 자식 클래스의 생성자 첫줄에 반드시 super(...) 를 호출해야 한다. (기본 생성자 생략가능)
+코드의 첫줄에 this(...) 를 사용하더라도 반드시 한번은 super(...) 를 호출해야 한다.
10. 다형성
객체 지향 프로그래밍의 대표적인 특징은 캡슐화, 상속, 다형성이다.
프로그래밍에서 다형성은 한 객체가 여러 타입의 객체로 취급될 수 있는 능력을 의미한다!
다형성을 이해하기 위해서는 2가지 핵심 이론을 알아야 한다.
● 다형적 참조
● 메서드 오버라이딩
다형적 참조
지금까지는 항상 같은 타입에 참조를 대입하여 한 가지 형태만 참조할 수 있었다. But,
Parent parent = new Parent()
Child child = new Child()
부모는 자식을 담을 수 있다
Parent 타입의 변수는 자신을 물론, 자식 타입까지 참조할 수 있다.(손자가 있다면 손자도)
Parent poly = new Parent()
Parent poly = new Child() //부모 타입의 변수가 자식 인스턴스를 참조
Parent poly = new Grandson()
코드로 확인해보면
Parent
public class Parent {
public void parentMethod() {
System.out.println("Parent.parentMethod");
}
}
Child
public class Child extends Parent {
public void childMethod() {
System.out.println("Child.childMethod");
}
}
Polymain
public class PolyMain {
public static void main(String[] args) {
//부모 변수가 부모 인스턴스 참조
System.out.println("Parent -> Parent");
Parent parent = new Parent();
parent.parentMethod();
//자식 변수가 자식 인스턴스 참조
System.out.println("Child -> Child");
Child child = new Child();
child.parentMethod();
child.childMethod();
//부모 변수가 자식 인스턴스 참조(다형적 참조)
System.out.println("Parent -> Child");
Parent poly = new Child();
poly.parentMethod();
//Child child1 = new Parent(); //자식은 부모를 담을 수 없다.
//자식의 기능은 호출할 수 없다. 컴파일 오류 발생
//poly.childMethod();
}
}
/*실행결과
Parent -> Parent
Parent.parentMethod
Child -> Child
Parent.parentMethod
Child.childMethod
Parent -> Child
Parent.parentMethod
*/
다형적 참조의 한계는 위의 그림처럼 부모는 자식의 메서드를 호출할 수 없다는 점이다.
호출자인 poly 는 Parent 타입이다. 따라서 Parent 클래스부터 시작해서 필요한 기능을 찾는데 상속 관계는 자식 방향으로 찾아 내려갈 수는 없기 때문에 오류가 발생한다.
Parent poly = new Child()
이렇게 참조한 상태에서 Child 속 childMethod()를 호출하려면 어떻게 해야할까?
>> 캐스팅 필요!
다형성과 캐스팅
다운캐스팅: 자식 타입으로 변경
Parent poly = new Child()
Child child = (Child) poly //Parent poly
괄호에 타입을 지정하면 참조 대상을 특정 타입으로 변경할 수 있다.
캐스팅: 특정타입으로 변경하는 것 ("cast"는 금속이나 다른 물질을 녹여서 특정한 형태나 모양으로 만드는
과정을 의미)
위는 (Child) 를 사용해서 일시적으로 자식 타입인 Child 타입으로 변경하여 child.childMethod() 를 호출할 수 있게 되었다!
오늘도 자바의 중요한 개념들에 대해
정리해보는 시간을 가져보았습니다:)
앞으로도 열심히 기록하겠습니다
모두 화이팅🙌

'자바' 카테고리의 다른 글
[자바의 정석] 변수, 배열, 객체 지향 파트 요약 정리 (챕터2, 5, 6 정리) (0) | 2025.03.16 |
---|---|
자바 실전개념편 2(접근 제어자~final) (0) | 2024.05.26 |
자바 실전개념편 1(클래스와 데이터 ~ 생성자) (0) | 2024.05.19 |
자바 입문하기_기본 개념 (변수~메소드) (0) | 2024.05.05 |