[Java] 객체지향 (5) 상속

lkc9898·2022년 5월 16일

Java

목록 보기
15/25
post-thumbnail

상속이란

객체지향 프로그래밍에서 상속이란 부모(상위) 클래스의 멤버를 자식(하위) 클래스에 물려주어 자식 클래스가 갖고 있는 것처럼 사용할 수 있다.

상속의 장점

  • 이해 용이 : 개별 클래스를 상속 관계로 묶음으로써 클래스 간의 최계화된 전체 구조를 파악하기 쉽다.

  • 코드 재사용성 : 데이터와 메서드의 오버로딩을 피하고 기존 클래스에 있는 것을 재사용할 수 있다.

  • 확장 용이 : 새로운 클래스, 데이터, 메서드를 추가하기 쉽다.

  • 유지보수 : 데이터와 메서드를 변경할 때 상위에 있는 것만 수정하여 전체적으로 일관성을 유지할 수 있다.

상속 구현

class 하위 클래스 extends 상위 클래스{
}

코드 예시

package main.java;

class Person {
	String name;
    int age;

            void learn() {
            System.out.println("공부를 한다.");
            };
            void walk() {
            System.out.println("걷다.");
            };
            void eat() {
            System.out.println("먹다.");
            };
}

class Programmer extends Person { // Person 클래스로부터 상속
    String companyName;

    void coding() {
        System.out.println("코딩을 한다.");
    };
}

class Dancer extends Person {
    String groupName;

    void dancing() {
        System.out.println("춤을 춘다.");
    };
}

class Singer extends Person {
    String bandName;

    void singing() {
        System.out.println("노래를 한다.");
    };
    void platGuitar() {
        System.out.println("기타를 칩니다.");
    };
}

public class HelloJava {
    public static void main(String[] args) {
        Person p = new Person(); // Person 객체 생성
        p.name = "김코딩";
        p.age = 25;
        p.learn();
        p.eat();
        p.walk();
        System.out.println(p.name);

        Programmer pg = new Programmer();
        pg.name = "박코딩";
        pg.age = 26;
        pg.learn();
        pg.coding();
        System.out.println(pg.name);
    }
}
/*
공부를 한다.
먹다.
걷다.
김코딩
공부를 한다.
코딩을 한다.
박코딩
*/

Person 클래스로부터 Programmer, Dancer, Singer 클래스가 확장되어 Person 클래스에 있는 속성과 기능들을 사용할 수 있다.

상속이 제한되는 경우

  • 다중 상속 불가능
  • 부모 클래스에서 private 접근 제한을 갖는 필드와 메서드
  • 부모 클래스와 자식 클래스가 다른 패키지에 존재하며, default 접근 제한을 갖는 필드와 메서드

super, super()

공통적으로 모두 상위 클래스의 존재를 상정하며 상속 관계를 전제로 한다. 그러나 super 키워드는 상위 클래스의 객체, super()는 상위 클래스의 생성자를 의미한다.

super 키워드 코드 예시

public class Super {
	public static void main(String[] args) {
    	Lower l = new Lower();
        l.callNum();
    }
}

class Upper {
	int count = 20; // super.count
}

class Lower extends Upper {
	int count = 15; // this.count
}

	void callNum() {
    	System.out.println("count = " + count);
        System.out.println("this.count = " + this.count);
        System.out.println("super.count = " + super.count);
    }
}
//출력
count = 15
this.count = 15
super.count = 20

Lower 클래스는 Upper 클래스로부터 count를 상속받는데, 자신의 인스턴스 변수 count와 이름이 같아 둘을 구분할 방법이 필요하다. 이럴 때 같은 이름의 변수를 구분하기 위한 방법이 super키워드 이다. 상위 클래스의 멤버와 자신의 멤버를 구별하는 데 사용된다는 점을 제외하면 thissuper는 기본적으로 같은 것이다.

super() 코드 예시

public class Test {
	public static void main(String[] args) {
    	Student s = new Student;
    }
}

class Human {
	Human() {
    	System.out.println("휴먼 클래스 생성자");
   	}
}

class Student extends Human { // Human 클래스로부터 상속
	Student() {
    	super(); // Human 클래스의 생성자 호출
        System.out.println("학생 클래스 생성자");
    }
}
//출력
휴먼 클래스 생성자
학생 클래스 생성자

Human 클래스를 확장하여 Student 클래스를 생성하고, Student 생성자를 통해 상위 클래스 Human 클래스의 생성자를 호출하고 있다. super()메서드 또한 this()와 마찬가지로 생성자 안에서만 사용가능하고, 반드시 첫 줄에 와야 한다.

예시에서 super()메서드는 Student 클래스 내부에서 호출되고 있고 상위 클래스 Human의 생성자를 호출하고 있다. 따라서 출력값으로 "휴먼 클래스 생성자"와 "학생 클래스 생성자"가 순차적으로 출력된다.

모든 생성자의 첫 줄에는 반드시 this()또는 super()가 선언되어야 한다. 만약 super()가 없는 경우에는 컴파일러가 생성자의 첫 줄에 자동으로 super()를 삽입하는데 이 때 상위클래스에 기본생성자가 없다면 에러가 발생하게 된다.

0개의 댓글