✍️ 학습할 것
- Java의 상속
- super
- 메서드 오버라이딩
- 다이나믹 메서드 디스패치 (Dynamic Method Dispatch)
- 추상 클래스
- final
- Object 클래스
📌 Java의 상속
자바의 상속을 이해하기 이전에 우선 객체 지향 프로그래밍의 가장 큰 특징인 상속에 대해서 이해해야 한다.
먼저 상속에 대해서 이해해보자.
✔️ 상속이란?
기존의 클래스를 이용해서 새로운 클래스를 만들어내는 것이다.
기존에 정의되어있던 클래스의 모든 필드와 메서드를 물려받아 코드의 재사용성을 높여준다.
기존의 클래스를 부모 클래스, 상위 클래스 등으로 부르고, 상속받은 클래스는 자식 클래스, 서브 클래스 등으로 부른다.
✔️ 자바에서 상속
- extends 뒤에 부모 클래스를 붙여서 사용한다.
- 모든 클래스의 부모 클래스는 Object 클래스이다.
- 다중 상속을 지원하지 않는다.
// Example
class Parent {
String name;
int age;
public void Print() {
System.out.println("이름 : " + name + ", 나이 : " + age);
}
}
class Child extends Parent {
Child(String name, int age) {
this.name = name;
this.age = age;
}
}
public class Inheritence {
public static void main(String[] args) {
Child child = new Child("문희조", 26);
child.Print(); // 이름 : 문희조, 나이 : 26
}
}
📌 super
자바에서는 super 키워드와 super() 메서드 두 가지가 존재한다.
✔️ super 키워드
- 자식 클래스가 부모 클래스로부터 상속받은 멤버를 참조하는 참조변수이다.
- 멤버변수와 지역변수의 이름이 같을 때 this로 구별했듯이 상속받은 변수와 구분할 때 super로 구분할 수 있다. 근본적으로 super와 this가 같다는 뜻이다.
- 메서드에서도 사용 가능하다. 오버라이딩한 경우에 super를 사용한다.
// Example
class Parent {
int age = 100;
String getAge() {
return "this.age : " + this.age;
}
}
class Child extends Parent {
int age = 10;
@Override
String getAge() {
return super.getAge() + ", super.age : " + super.age;
}
}
public class Super {
public static void main(String[] args) {
Child child = new Child();
System.out.println(child.getAge()); // this.age : 100, super.age : 100
}
}
✔️ super()
- 부모 클래스의 생성자를 호출하는 데 사용한다.
- 자식 클래스의 인스턴스를 생성하면 상속받은 모든 클래스가 합쳐진 인스턴스가 생성된다. 따라서 자식 클래스가 상속 받은 클래스의 멤버들을 사용할 수 있으므로 모든 클래스는 조상 클래스가 우선적으로 초기화돼야 한다.
class Parent {
String name;
int age;
Parent(String name, int age) {
this.name = name;
this.age = age;
}
}
class Child extends Parent {
String sex;
Child(String name, int age, String sex) {
super(name, age);
this.sex = sex;
}
}
public class Super {
public static void main(String[] args) {
Child child = new Child("문희조", 26, "male");
System.out.println("name : " + child.name + ", age : " + child.age + ", sex : " + child.sex);
// name : 문희조, age : 26, sex : male
}
}
📌 메서드 오버라이딩
부모 클래스에 정의된 메서드를 자식 클래스에서 재정의하는 것이다.
동작만 재정의하는 것이므로 선언부는 그대로 두고 내용만 변경 가능하다.
오버라이드 시 @Override 어노테이션으로 표시해준다.
// Example
class Parent {
void display() { System.out.println("부모 클래스의 display() 메소드입니다."); }
}
class Child extends Parent {
@Override
void display() { System.out.println("자식 클래스의 display() 메소드입니다."); }
}
public class Overriding {
public static void main(String[] args) {
Child child = new Child();
child.display(); // 자식 클래스의 display() 메소드입니다.
}
}
📌 다이나믹 메서드 디스패치 (Dynamic Method Dispatch)
메소드 디스패치란? 어떤 메서드를 호출할지 결정하여 실행시키는 과정을 말한다.
자바는 컴파일 시 생성할 객체 타입에 대한 클래스 정보를 보유하고 런타임에 객체를 생성한다.
따라서 오버라이딩된 메서드가 있으면 클래스 정보만 알고 있고 실질적으로 어떤 메서드를 호출할지 모른다.
어떤 시점에서 메소드를 호출할지 아는지에 따라서 정적(static)과 동적(dynamic)이 나뉜다.
✔️ Static : 컴파일 시점에서 어떤 메서드가 호출될지 명확하게 아는 경우
// Example
class Parent {
void display() { System.out.println("Parent method"); }
}
public class MethodDispatch {
public static void main(String[] args) {
new Parent().display(); // Parent method
}
}
✔️ Dynamic : 런타임 시점이 돼야 어떤 메서드가 호출될지 명확하게 아는 경우
// Example
class Parent {
void display() { System.out.println("Parent method"); }
}
class Child1 extends Parent {
@Override
void display() { System.out.println("Child1 method"); }
}
class Child2 extends Parent {
@Override
void display() { System.out.println("Child2 method"); }
}
public class MethodDispatch {
public static void main(String[] args) {
Parent parent = new Child2();
parent.display(); // Child2 method
}
}
📌 추상 클래스
추상 클래스란? 추상 메서드를 포함하는 클래스를 말한다.
추상 메서드를 포함하고 있어서 인스턴스를 생성할 수는 없지만 그 외 생성자, 필드 그리고 일반 메서드도 가질 수 있다.
✔️ 추상 메서드
- 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메서드이다.
- 일반 메서드는 구현할 수도, 안 할 수도 있지만 중요한 메서드를 추상 메서드로 구현하면 무조건적으로 구현해야 인스턴스를 생성할 수 있어서 반드시 구현하게 할 수 있다.
// Example
abstract class Aniaml {
abstract void cry();
}
class Dog extends Aniaml {
@Override
void cry() { System.out.println("Woof!"); }
}
class Cat extends Aniaml { }
public class AbstractClass {
public static void main(String[] args) {
new Dog().cry(); // Woof!
new Cat().cry(); // Error occur!!
}
}
📌 final
final 키워드는 단어 그대로 '마지막'의 의미로 딱 한 번만 할당할 때 사용한다.
거의 모든 대상에게 사용할 수 있으며 대상에 따라서 다르게 적용된다.
- 클래스 : 다른 클래스의 부모 클래스가 될 수 없다.
- 메서드 : 오버라이딩으로 재정의할 수 없다.
- 변수 : 재할당 할 수 없다.
✔️ final에 대한 오해
보통 final을 단순히 상수로 만들거나 값을 변경하지 못하게 만든다고 생각한다.
객체나 변수에 대해서 immutable하게 만든다고 생각하지만 final은 immutable하게 만드는 키워드가 아니다.
스택 오버플로우에서 참고한 내용은 다음과 같다.
final simply makes the object reference unchangeable. The object it points to is not immutable by doing this. INSTANCE can never refer to another object, but the object it refers to may change state.
앞서 정의한 대로 단순히 참조를 변경할 수 없게 만드는 것이다.
멤버 변수나 지역 변수는 상수로 만든다고 생각해도 무방하다. 반면에 객체는 참조를 재할당할 수 없지만 객체 내부 요소들에 대해서는 변경이 가능하다는 것이다.
// Example
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public void increaseAge() { this.age += 1; }
public void display() {
System.out.println("이름 : " + this.name + ", 나이 : " + this.age);
}
}
public class FinalKeyword {
public static void main(String[] args) {
final Person Hejow = new Person("문희조", 26);
Hejow.display();
Hejow.increaseAge();
Hejow.display();
Person HongGilDong = new Person("홍길동", 100);
Hejow = HongGilDong; // An Error Occur!
}
}
📌 Object 클래스
Object 클래스란? 모든 클래스의 부모 클래스로 최상위 클래스이다.
다른 클래스로부터 상속받지 않은 모든 클래스는 컴파일 시 자동으로 extends Object가 추가된다.
필드가 없고 메서드로만 구성되어 있다.
'언어 공부 > Java' 카테고리의 다른 글
[Java] Java 인터페이스 (0) | 2022.09.08 |
---|---|
[Java] Java의 패키지 (0) | 2022.09.05 |
[Java] Java의 클래스 (0) | 2022.08.17 |
[Java] Java 제어문 (0) | 2022.08.16 |
[Java] Java의 연산자 (0) | 2022.08.15 |
댓글