Inheritance (상속)
What is the Inheritance?
어떤 학생에 대한 속성을 담고 있는 클래스가 있다고 생각해보자. 학생A 에 대해 정의할 때 속성에 관한 메서드를 다시 처음부터 다 작성해야 할까? 아니다. 자바의 경우 다른 클래스로부터 속성들을 상속 받을 수 있다.
상속에 대한 용어정리
Parent class, superclass, base class
다른 클래스가 상속받은 클래스를 의미한다.
Child class, subclass, derived class
다른 클래스에서 상속받은 클래스를 의미한다. 어디에서 상속받았는지를 알려주기 위해 extends [클래스명] 을 적어줘야 한다.
subclass 와 superclass 의 관계 = “is -a” relationship
subclass 의 객체는 superclass 의 멤버이지만, superclass 의 객체는 subclass 의 객체일 필요는 없다.
Inheriting the Constructor
부모 클래스의 영역과 메서드를 상속받는다는 것은, 부모 클래스의 생성자도 상속받는다는 것을 의미한다. 이렇게 상속받은 생성자는 super() 메서드를 이용해서 수정할 수 있다. super() 메서드는 두가지의 열할을 할 수 있다.생성자가 자식 클래스 생성자 내에서 마치 부모 생성자처럼 작동할 수 있게 만들어준다.
super() 메서드를 사용하지 않고 부모 클래스 생성자 재정의 하기
상속받은 생성자를 super() 메서드를 이용하여 원하는대로 수정하여 사용하는 방법도 있지만 자식 클래스에 대한 새 생성자를 만들어 부모 클래스 생성자를 완전히 재정의 할 수도 있다. 아래의 예시를 보고 전자와 후자의 차이를 이해해보자
[예시 코드]
// Parent class
class Animal {
String sound;
Animal(String snd) {
this.sound = snd;
}
}
// Child class
class Dog extends Animal {
// super() method can act like the parent constructor inside the child class constructor.
Dog() {
super("woof");
}
// alternatively, we can override the constructor completely by defining a new constructor.
Dog() {
this.sound = "woof";
}
}
Java
복사
Parent Class Aspect Modifiers
자식 클래스가 부모 클래스 의 멤버에 접근하도록 하고 싶다면 protected 와 final 키워드를 사용하면 된다.
protected
하위 클래스가 상위 클래스의 자체 패키지 안에 있는 파일 이나 또다른 패키지 안에 있는 이 클래스의 하위 클래스에 접근할 수 있도록 유지한다.
final
상위 클래스 메서드의 접근제한자 앞에 final을 추가하면 하위 클래스가 해당 메서드를 수정할 수 없도록 한다. 변경이 불가능하다.
[예시 코드]
class Student {
protected double gpa;
// any child class of Student can access gpa
final protected boolean isStudent() {
return true;
}
// any child class of Student cannot modify isStudent()
}
Java
복사
멤버란?
클래스(오브젝트)의 변수와 메서드 등을 말한다.
접근 제한자의 종류
Modifier | Class | Package | Child Class | Global |
public | ||||
protected | ||||
no modifier | ||||
private |
Polymorphism
What is Polymorphism?
자바는 다형성의 객체지향 프로그래밍 원리를 포함한다. 다형성이란 하나의 객체가 여러가지 타입을 가질 수 있는것을 의미한다. 때문에 자식 클래스가 자신의 기능을 포함하여 부모 클래스의 정보와 행동을 공유할 수 있다. 이를 통해 구문이 단순해지는 장점이 있다.
Method Overiiding
Java 에서는 자식 클래스의 부모 클래스 메서드를 쉽게 재정의 할 수 있다. 이는 자식 클래스 메서드가 부모 클래스 메서드와 같은 이름을 가지지만 다른 동작을 수행하길 원할 때 유용하다. 만약 재정의를 하고 싶다면 자식 클래스 메서드와 부모 클래스 메서드가 아래 3가지를 똑같이 가지고 있어야 한다.
(1) 메서드 이름 (2) 반환 타입 (3) 매개변수의 수와 타입
이때 자식 클래스 메서드 위에 @Override 키워드를 포함해야 하며, 자식 클래스 옆에 extends 키워드와 부모 클래스를 같이 나타내야 한다. (이는 부모 클래스의 메서드를 재정의하려는 컴파일러를 나타내는 것이다.)
[예시 코드]
// Parent class
class Animal {
public void eating() {
System.out.println("The animal is eating.");
}
}
// Child class
class Dog extends Animal {
// Dog's eating method overrides Animal's eating method
@Override
public void eating() {
System.out.println("The dog is eating.");
}
}
Java
복사
super 키워드를 사용하여 부모 클래스 호출하기
super 키워드를 사용하여 상위 클래스의 생성자를 호출 하는 것 뿐만 아니라 부모 클래스의 메서드를 호출할 수도 있다. 자식 클래스에서 재정의된 메서드 대신 같은 이름의 부모 클래스를 사용하고 싶다면 super.[메서드명] 을 이용하여 호출할 수 있다.
[예시 코드]
public void checkBalances() {
// calls method from CheckingAccount (child class)
printBalance();
// calls method from BankAccount (parent class)
super.printBalance();
}
Java
복사
Child Classes in Arrays and ArrayLists
다형성은 부모 클래스를 공유하고있는 다른 클래스의 인스턴스를 배열이나 배열리스트로 둘 수 있게 해준다. 예를 들어 Animal 이라는 부모 클래스가 있고, 자식 클래스로는 Cat, Dog 그리고 Pig 가 있다면, 각 동물의 인스턴스로 배열을 생성할 수 있고 그 리스트를 통해 같은 행동을 수행하게 만들 수 있다. 아래 코드를 보자.
[예시 코드]
// Animal parent class with child classes Cat, Dog, and Pig.
Animal cat1, dog1, pig1;
cat1 = new Cat();
dog1 = new Dog();
pig1 = new Pig();
// Set up an array with instances of each animal
Animal[] animals = {cat1, dog1, pig1};
// Iterate through the list of animals and perform the same action with each
for (Animal animal : animals) {
animal.sound();
}
Java
복사
Child Classes in Method Parameters
파라미터를 포함하고 있는 메서드를 호출 할 때, argument 는 반드시 파라미터의 타입과 같아야 한다. 하지만 다형성에 의해 argument 를 더 유연하게 사용할 수 있다. 만약 메서드 파라미터로 상위 클래스를 참조한다면 하위 클래스의 argument 를 사용하여 메서드를 호출 할 수 있다.
[예제 코드]
다음은 Monster 클래스를 참조하고 있는 ScaryStory 라는 클래스이다.
class ScaryStory {
Monster monster;
String setting;
public ScaryStory(Monster antagonist, String place) {
monster = antagonist;
setting = place;
}
public void tellStory(){
System.out.println("Once upon a time, " + monster.name + " was at " + setting + " looking to scare some mortals.");
}
public static void main(String[] args) {
Monster dracula;
dracula = new Vampire("Dracula");
ScaryStory countDracula = new ScaryStory(dracula, "Dracula Castle");
countDracula.tellStory();
}
}
Java
복사
main() 메서드를 보면 생성자가 Monster 클래스의 객체(dracula)를 참조했지만, argument 로는 Vampire 클래스를 참조했다. 이는 Vampire 가 Monster 클래스의 하위 클래스 이기 때문에 가능하다.