상속이란?
상속이란 기존의 클래스를 재사용하여 새로운 클래스를 만드는 것으로 객체지향 프로그래밍에서 중요한 특징 중 하나입니다. 상속을 해주는 클래스를 부모 클래스
나 상위 클래스
라고 하고 상속받는 클래스를 자식 클래스
, 하위 클래스
라고 합니다.
상속의 특징
- 코드의 재사용성을 높이고 중복 코드를 줄여 생산성이 좋아집니다.
- 자식 클래스는 부모클래스의 모든 멤버를 상속받는다.
- 생성자와 초기화블럭은 상속되지 않으며 멤버만 상속된다.
- 다중 상속을 지원하지 않는다.
public class Parent {
String name;
int age;
public Parent(String name, int age) {
this.name = name;
this.age = age;
}
//getter setter 생략
public void aboutMe(){
System.out.println("내 이름은 "+name+"이고 "+age+"살 이다.");
}
}
public class Child extends Parent{
public Child(String name, int age) {
super(name, age);
}
public void play(){
System.out.println("게임 플레이");
}
}
두 클래스를 벤다이어그램과 그림으로 표현해보면 다음과 같다.
super
super
부모 클래스로부터 상속받은 멤버를 자식 클래스에서 참조하는 데 사용하는 참조 변수입니다. 상속받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 경우 super로 구분할 수 있으며 this 또한 사용 가능하다.
public class Child extends Parent{
public Child(String name, int age) {
super(name, age);
}
@Override
public void aboutMe() {
super.aboutMe();
System.out.println("super.age= "+super.age);
System.out.println("this.age= "+this.age);
}
}
public class Test {
public static void main(String[] args) {
Parent parent = new Parent("길동",40);
parent.aboutMe();
Child child = new Child("철수",23);
child.aboutMe();
}
}
출력
내 이름은 길동이고 40살이다.
내 이름은 철수이고 23살이다.
super.age= 23
this.age= 23
super 메소드
this()가 같은 클래스의 다른 생성자를 호출할 때 사용된다면 super()는 부모 클래스의 생성자를 호출할 때 사용됩니다.
public class Parent {
String name;
int age;
public Parent(String name, int age) {
System.out.println("parent constructor");
this.name = name;
this.age = age;
}
}
public class Child extends Parent{
public Child(String name, int age) {
super(name, age);
System.out.println("child constructor");
}
}
public class Test {
public static void main(String[] args) {
Parent parent = new Parent("길동",40);
Child child = new Child("철수",23);
}
}
출력
parent constructor
parent constructor //child클래스 생성자의 super에 의한 호출
child constructor
메소드 오버라이딩
상속 관계에서 부모 클래스의 메소드를 자식 클래스에서 변경하는 것을 의미한다. 이때 메소드의 동작만들 재정의 하는것으로 선언부는 기존 메소드와 동일해야 하며 부모 클래스의 메소드의 접근 제어자보다 더 좁은 범위로는 변경할 수 없습니다.
public class Parent {
public void aboutMe(){
System.out.println("부모의 aboutMe()메소드");
}
}
public class Child extends Parent{
@Override
public void aboutMe() {
System.out.println("자식의 aboutMe()메소드");
}
}
다이나믹 메소드 디스패치
디스패치는 어떤 메소드를 호출할 것인가를 결정하여 그것을 실행하는 과정으로 동적 디스패치와 정적 디스패치가 있습니다. 동적 디스패치(dynamic dispatch)는 오버라이딩된 메소드를 호출할 때 어떤 메소드를 호출할지 결정을 런타임에 결정하는 것을 말하며 정적 디스패치는 컴파일 시점에 결정하는 것을 말합니다.
추상클래스
하나 이상의 추상 메소드를 포함하는 클래스를 추상 클래스라고 하며, 직접 인스턴스를 생성할 수 없고 상속을 통해서 자식 클래스를 통해서만 만들 수 있는 클래스입니다..
추상 클래스를 선언하는 방법
abstract
키워드를 붙여주면 됩니다.
abstract class 클래스이름{
//...
}
abstract public class Shop {
abstract void sell();
}
public class Restaurant extends Shop{
@Override
void sell() {
System.out.println("음식을 팔다");
}
}
public class Bookstore extends Shop{
@Override
void sell() {
System.out.println("책을 팔다");
}
}
public class Test {
public static void main(String[] args) {
Bookstore bookstore = new Bookstore();
Restaurant restaurant = new Restaurant();
bookstore.sell();
restaurant.sell();
}
}
출력
책을 팔다
음식을 팔다
추상 클래스를 사용함으로써 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 강제할 수 있습니다.
final
자바에서 final은 변경될 수 없다
는 의미로 사용되고 있으며 클래스, 메서드, 변수에 사용 가능합니다.
- 클래스에 사용하면 다른 클래스가 상속받을 수 없게 됩니다.
- 메서드에 사용하면 오버라이딩을 할 수 없게 됩니다.
- 멤버변수, 지역변수에 사용하면 상수가 됩니다.
final class Book {
final int PRICE;
Book(int price) {
PRICE = price;
}
final int getPrice() {
return PRICE;
}
}
변수에 final이 붙으면 상수여서 일반적으로 선언과 초기화를 동시에 하지만 생성자에서 초기화되도록 사용할 수 있습니다.
Object 클래스
모든 클래스의 최상위에 있는 클래스로 상속받지 않은 모든 클래스는 자동적으로 Object클래스를 상속받게 되어 있다.
- clone(): 객체 자신의 복사본을 반환한다.
- equals(Objcet obj): 객체 자신과 obj가 같은 객체인지 알려준다.
- finalize() 객체가 소멸할 때 GC에의해 자동적으로 호출된다.
- getClass(): 객체 자신의 클래스 정보를 담고 있는 Class 인스턴스를 반환한다.
- hashCode(): 객체 자신의 해시코드를 반환한다.
참고 문서
Java의 정석 - 남궁 성
http://www.tcpschool.com/java/intro
'프로그래밍 > Java' 카테고리의 다른 글
패키지 (0) | 2021.01.02 |
---|---|
데이터타입, 변수, 배열 (0) | 2020.12.31 |
JVM이란? (0) | 2020.12.22 |
클래스 (0) | 2020.12.18 |
java8 - time (0) | 2020.03.10 |