* 본 게시물은 이지스퍼블리싱 [Do it! 점프 투 자바] 서평단 미션 수행 및 학습 목적으로 작성하였습니다.
모든 내용, 디자인, 이미지, 편집 구성의 저작권은 이지스퍼블리싱(주)와 지은이에게 있으며
학습 목적으로 내용을 재구성하여 작성했음을 밝힙니다. 문제시 삭제하도록 하겠습니다.
상속
자바에는 자식 클래스가 부모 클래스의 기능을 그대로 물려받을 수 있는 상속(inheritance) 기능이 있다.
class Animal {
String name;
void setName(String name) {
this.name = name;
}
}
class Dog extends Animal { // Animal 클래스 상속
}
public class Sample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.setName("poppy"); // [setName 메서드를 사용하는 이유] 아래 설명 참고
System.out.println(dog.name);
}
}
Dog 클래스에서 Animal 클래스를 상속하기 위해 extends 키워드를 사용했다.
setName 메서드를 사용해 name 변수에 'poppy'라는 문자열을 설정하여 그 값을 출력했다.
dog.setName("poppy");
Dog 클래스에 객체 변수인 name과 setName 메서드를 만들지 않아도
Animal 클래스를 상속했기 때문에 예제에서 보듯이 그대로 사용 가능하다.
setName 메서드를 사용하는 이유
- 데이터 은닉 (Data Encapsulation)
- 데이터 은닉은 객체 내부의 데이터나 상태를 외부에서 직접 접근하지 못하도록 보호하는 개념이다. 클래스 내의 데이터는 주로 private 접근 제어자를 사용하여 외부에서 접근할 수 없게 하고, 데이터에 접근하려면 메서드를 통해야 한다. 이것은 클래스의 내부 구현을 외부에 감추고 객체를 안전하게 사용할 수 있게 한다. - 캡슐화 (Encapsulation)
- 캡슐화는 데이터와 해당 데이터를 조작하는 메서드를 하나로 묶는 것을 의미한다. 즉, 데이터와 데이터를 다루는 메서드를 함께 묶어서 객체를 형성한다는 의미인데, 이렇게 하면 데이터와 관련된 모든 동작을 객체 내에서 관리할 수 있으며, 객체를 사용하는 코드에서는 객체의 메서드를 호출하여 데이터를 조작할 수 있다.
setName 메서드를 사용하면 ① 클래스 내부의 name 변수에 대한 접근을 외부로부터 제어할 수 있으며, ② 데이터를 안전하게 설정할 수 있다. 또한 나중에 클래스 내부 구현을 변경할 때 ③ 변경 내용을 setName 메서드 내부에 캡슐화할 수 있어서, 외부 코드에 영향을 덜 주면서 유지 보수가 쉬워집니다.
간단히 말해서, setName 메서드를 사용하면 데이터를 안전하게 다룰 수 있고, 클래스의 내부 구현을 숨길 수 있으며, 코드의 유지 보수성을 높일 수 있습니다.
Dog 클래스는 Animal 클래스를 상속했기 때문에 Animal 클래스보다 하위 개념이라고 할 수 있다.
그러므로 '개(Dog)는 동물(Animal)이다' 라고도 표현할 수 있다.
자바는 이런 관계를 IS-A 관계라고 표현한다.
Dog is a Animal (개는 동물이다)
Animal dog = new Dog(); // Dog is Animal
Dog dog = new Animal(); // 컴파일 오류 발생
IS-A 관계 (상속 관계) 경우 자식 클래스의 객체는 부모 클래스의 자료형인 것처럼 사용할 수 있다.
메서드 오버라이딩 (Overriding)
Animal, Dog, HouseDog 클래스를 정의하고
HouseDog 객체를 생성한 다음 | HouseDog houseDog = new HouseDog(); |
setName 메서드로 이름을 지정한 뒤 | houseDog.setName("happy"); |
sleep 메서드를 호출해 | houseDog.sleep(); |
"happy zzz in house"를 출력한다.
빨간 테두리로 표시된 두 클래스 중에 호출되는 것은 HouseDog 클래스의 sleep 메서드이다.
부모 클래스의 메서드를 자식 클래스가 동일한 형태로 또다시 구현하는 행위를
메서드 오버라이딩 (method overriding) 이라고 한다.
말 그대로 '메서드 덮어쓰기' 라고 할 수 있다.
부모님으로부터 가게(클래스)를 물려받아 새로운 메뉴(메서드)를 추가하거나 비유하는 것으로
객체 지향 프로그래밍에서 상속과 다형성을 구현하는 메서드 오버라이딩을 설명할 수 있다.
아니면 오버라이딩이니까 오토바이를 자식에게 물려준다고 이해하면 어떨까..요 원래 이렇게 해야 기억에 잘 남는다
- 부모 클래스 (상위 클래스): 부모님으로부터 가게를 물려받은 클래스로 일반적인 동작, 메뉴를 가지고 있을 수 있다.
- 자식 클래스 (하위 클래스): 자식이 부모로부터 가게를 물려받은 후, 새로운 메뉴를 추가하거나 기존 메뉴를 변경할 수 있는 클래스. 이 클래스는 부모 클래스의 메서드를 오버라이딩하여 새로운 동작을 제공할 수 있다.
- 메서드 오버라이딩 (Method Overriding): 자식 클래스에서 부모 클래스로부터 상속받은 메서드의 내용을 변경하거나 확장하는 것으로, 자식 클래스에서 새로운 구현을 제공하고 부모 클래스의 동작을 재정의한다.
- 새로운 기능 추가: 자식 클래스는 부모 클래스에서 상속받은 메서드를 확장하여 새로운 기능을 추가할 수 있다.
새로운 메뉴 항목을 메뉴에 추가하는 것과 유사하다고 볼 수 있다. - 동작 변경: 자식 클래스는 부모 클래스에서 상속받은 메서드를 오버라이딩하여 동작을 변경할 수 있다.
메뉴 항목의 조리 방법을 변경하는 것과 유사하다.
메서드 오버로딩 (method overloading)
이상한 오토바이 사진까지 가져오면서(?) 오버라이딩을 설명했다면
같은 이름의 메소드를 중복하여 정의하는 메서드 오버로딩 (Overloading) 차례가 왔다.
자바에서는 원래 한 클래스 내에 같은 이름의 메서드를 둘 이상 가질 수 없지만,
매개변수의 개수나 타입을 다르게 하면 하나의 이름으로 메서드를 작성할 수 있다.
생소하다고 생각이 들면 메서드 오버로딩의 가장 대표적인 예시인 println() 메서드를 생각해보자.
class Dog extends Animal {
void sleep() {
System.out.println(this.name + " zzz");
}
}
class HouseDog extends Dog {
void sleep() {
System.out.println(this.name + " zzz in house");
}
}
이미 sleep이라는 메서드가 있지만 동일한 이름의 메서드를 또 생성할 수 있다.
단, 메서드의 입력 항목이 다를 경우에만 가능하다.
void sleep(int hour) {
System.out.println(this.name+" zzz in house for " + hour + " hours");
}
새로 만든 sleep 메서드는 입력 항목으로 hour라는 int 자료형이 추가됐다.
class Calculator {
int add(int a, int b) { // int
return a + b;
}
double add(double a, double b) { // double
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
int result1 = calculator.add(5, 10); // int 타입 매개변수 호출
double result2 = calculator.add(3.5, 2.7); // double 타입 매개변수 호출
System.out.println("Result 1: " + result1);
System.out.println("Result 2: " + result2);
}
}
Calculator 클래스는 add 메서드를 오버로딩하고 있다.
동일한 메서드 이름을 사용해 서로 다른 데이터 유형을 처리하는 예시이다.
메서드 오버로딩 특징 |
|
[ 정상 ]
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
하나는 int, 다른 하나는 double 매개변수를 받고 있어 오버로딩이 정상적으로 동작한다.
[ 오류 ]
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(int a, int b) {
return (double)(a + b);
}
}
add 메서드가 정의되어 있지만, 매개변수의 타입이 int로 같은 것을 볼 수 있다.
return 타입(반환 유형)만 다를 뿐이어서 컴파일 오류가 발생한다.
method add(int,int) is already defined in class Calculator
동일한시그니처(매개변수의 타입과 개수)를 가진 메서드가 이미 클래스에 정의되어 있다는
메시지가 표시된다.
메서드 오버로딩 장점 |
|
'활동 > 독서' 카테고리의 다른 글
[Do it! 점프 투 자바] 06.자바의 입출력 (InputStreamReader / BufferedReader / Scanner 클래스) (0) | 2023.09.11 |
---|---|
[Do it! 점프 투 자바] 06. 자바의 입출력 (Stream이란? / throws IOException / InputStream in = System.in; ) (0) | 2023.09.08 |
[Do it! 점프 투 자바] 05. 객체 지향 프로그래밍 (객체 변수) (0) | 2023.08.28 |
[Do it! 점프 투 자바] 04. 제어문 이해하기 (while / for문과 for each문) (0) | 2023.08.24 |
[Do it! 점프 투 자바] 03.자바의 기초 - 자료형 (형 변환과 final) (0) | 2023.08.23 |