Java는 이미 설계된 클래스를 바탕으로 새로운 클래스를 만들 수 있도록 지원한다
새로운 클래스를 만드는 행위를 클래스를 확장이라고 하며 개 클래스가 기존 클래스의 멤버를 물려받는 것을 상속이라고 한다.
슈퍼 클래스 : 바탕이 되는 클래스
서브 클래스 : 새로운 클래스
class 자동차 {
String 차량_번호;
Double 남은_연료량;
Double 연비;
}
class K5 extends 자동차 {
String 자동차_회사;
String 자동차_주인;
}
K5 클래스는 자동차 클래스를 상속한 클래스이다.
슈퍼 클래스: 자동차 클래스
서브 클래스: K5 클래스
이런 식으로 클래스 확장이 가능하다.
메소드 오버라이딩은 슈퍼 클래스와 완전히 동일한 메소드를 선언할 수 있는 기능이다.
슈퍼 클래스의 메소드으 이름 및 인수의 개수, 형이 동일해야 오버라이딩 가능
아래는 Animal 슈퍼 클래스이다.
package com.animal;
public abstract class Animal {
public String name;
public String role;
public int age;
private double height;
public Animal(String name, int age, double height, String role) {
this.name = name;
this.age = age;
this.height = height;
this.role = role;
}
public void eat() {
System.out.println(name + "먹는다");
}
}
아래는 Animal 클래스를 상속받은 Dog 클래스이다.
package com.animal;
public class Dog extends Animal{
public Dog(String name, int age, double height, String role) {
super(name, age, height, role);
}
@Override
public void eat() {
System.out.println(super.name + " 이/가 사료를 먹는다.");
}
@Override
public void snack() {
System.out.println(super.name + " 이/가 개껌을 먹는다.");
}
@Override
public void sound() {
System.out.println(super.name + " 이/가 멍멍 소리를 낸다.");
}
@Override
public void role() {
System.out.println(super.name + "은 막둥이이다.");
}
}
여기서 Dog 클래스의 eat(), snack(), sound(), role()은 슈퍼 클래스인 Animal 클래스의 eat(), snack(), sound(), role()을 오버라이딩을 한 것이다.
(이름, 자료형 똑같으나 System.out.println()하는 부분이 다름) => 오버라이딩
이번엔 상속과 오버라이딩을 사용해 클래스들을 구현해보겠다.
슈퍼 클래스: Animal
서브 클래스: Cat, Dog, Human
package com.animal;
public abstract class Animal {
public String name;
public String role;
public int age;
private double height;
public Animal(String name, int age, double height, String role) {
this.name = name;
this.age = age;
this.height = height;
this.role = role;
}
public void eat() {
System.out.println(name + "먹는다");
}
public void snack() {
System.out.println(name + "간식");
}
public void sound() {
System.out.println(name + "소리를 낸다");
}
public void role() {
System.out.println(name + "의 역할");
}
}
package com.animal;
public class Dog extends Animal{
public Dog(String name, int age, double height, String role) {
super(name, age, height, role);
}
@Override
public void eat() {
System.out.println(super.name + " 이/가 사료를 먹는다.");
}
@Override
public void snack() {
System.out.println(super.name + " 이/가 개껌을 먹는다.");
}
@Override
public void sound() {
System.out.println(super.name + " 이/가 멍멍 소리를 낸다.");
}
@Override
public void role() {
System.out.println(super.name + "은 막둥이이다.");
}
}
eat(), snack(), sound(), role()을 오버라이딩했다.
package com.animal;
public class Cat extends Animal{
public Cat(String name, int age, double height, String role) {
super(name, age, height, role);
}
@Override
public void eat() {
System.out.println(super.name + " 이/가 사료를 먹는다.");
}
@Override
public void snack() {
System.out.println(super.name + " 이/가 츄르를 먹는다.");
}
@Override
public void sound() {
System.out.println(super.name + " 이/가 야옹 소리를 낸다.");
}
@Override
public void role() {
System.out.println(super.name + "은 주인님이다.");
}
}
eat(), snack(), sound(), role()을 오버라이딩했다.
package com.animal;
public class Human extends Animal{
public Human(String name, int age, double height, String role) {
super(name, age, height, role);
}
@Override
public void eat() {
System.out.println(super.name + " 이/가 밥을 먹는다.");
}
@Override
public void snack() {
System.out.println(super.name + " 이/가 핫도그를 먹는다.");
}
@Override
public void sound() {
System.out.println(super.name + " 이/가 말을 한다.");
}
@Override
public void role() {
System.out.println(super.name + "의 직업은 " + super.role + "이다.");
}
}
eat(), snack(), sound(), role()을 오버라이딩했다.
나는 여기서 추가로 Human 클래스를 상속받은 Baby 클래스를 만들어보았다. 2차 상속인 셈이다.
package com.animal;
public class Baby extends Human {
public Baby(String name, int age, double height, String role) {
super(name, age, height, role);
}
@Override
public void eat() {
System.out.println(super.name + " 이/가 이유식을 먹는다.");
}
@Override
public void snack() {
System.out.println(super.name + " 이/가 치즈를 먹는다.");
}
@Override
public void sound() {
System.out.println(super.name + " 이/가 옹알이를 한다.");
}
@Override
public void role() {
System.out.println(super.name + "은 직업이 없다.");
}
}
이렇게 클래스들을 생성하고 Main에서 객체를 생성하여 어떻게 결과가 출력이 되는지 확인해보겠다.
package com.animal;
public class Main {
public static void main(String[] args) {
Human human1 = new Human("erica", 25, 163.5, "백수" );
Cat cat1 = new Cat("쫀떡", 5, 30, "주인");
Dog dog1 = new Dog("노을", 3, 30, "강아지");
Baby baby1 = new Baby("태하", 1, 70, "귀염둥이");
human1.eat();
cat1.eat();
dog1.eat();
baby1.eat();
System.out.println("-------------------");
human1.snack();
cat1.snack();
dog1.snack();
baby1.snack();
System.out.println("-------------------");
human1.sound();
cat1.sound();
dog1.sound();
baby1.sound();
System.out.println("-------------------");
human1.role();
cat1.role();
dog1.role();
baby1.role();
}
}
각 클래스별 객체를 생성자를 사용해서 생성을 해보고, 오버라이딩한 메소드를 호출해보았다.

이렇게 오버라이딩한 내용까지 잘 출력이 되었다.
자바에서 상속은 피할 수 없다고 생각을 한다. 상속의 개념에 대해서 깊게 공부해보고 활용해보며 자바에 대한 이해도를 높여보자.