[자바JAVA]클래스 : 상속, 메서드 오버라이딩, super()
상속 정의
상속은 객체간의 관계를 표현하는 것.
상속을 왜 사용할까?
프로그램에서 상속은 기존 클래스의 멤버변수와 메서드
을 다른 클래스에서 재사용하기 위한 것이다.
- 상속의 관계에서 물려주는 클래스 : 슈퍼클래스 = 조상클래스 = 모부클래스 = 상위클래스
- 상속의 관계에서 물려받는 클래스 : 서브클래스 = 자손클래스 = 자식클래스 = 하위클래스
상속 사용방법은 아래와 같다. extends 슈퍼클래스이름
으로 작성해주면된다.
1 | class 서브클래스이름 extends 슈퍼클래스이름 |
상속 특징
- 상속의 장점
- 서브클래스는 멤버변수와 메서드를 자신의 것처럼 사용할 수 있기 때문에 코드 절감 효과.
- 슈퍼클래스의 코드를 변경하면 모든 서브 클래스들에게도 적용되므로 유지보수성 향상.
- 상속의 특징 : 단일 상속만 가능
- 프로그램복잡도를 줄이기 위해서 JAVA는 다중상속을 지원하지않는다.
- 상속을 여러 슈퍼클래스에서 받을 수 없다.
상속범위
- 상속대상 : 멤버변수, 메서드
- 상속제외대상 : 생성자, 초기화블록
- 생성자는 상속하지않고 super()를 통해 호출한다. 명시적으로 super()를 이용해서 다른 생성자를 호출하는 코드가 없다면 컴파일러는 언제나 슈퍼클래스의 기본 생성자를 호출하는 super()를 생성해 첫 행에 삽입하게 된다. 결론적으로 최상위의 객체인 Object까지 모든 조상객체가 다 만들어지는 구조가 된다.
Object 라이브러리
- Object는 자바에서 아주 중요한 클래스이며 최상위클래스이다.
- Object 클래스는 모든 클래스의 조상 클래스로 만약 클래스 선언부에
extends Object
생략 가능하다.
메서드 오버라이딩(Method overriding)
- 슈퍼클래스에서 정의된 기능을 서브 클래스에 적합하게 수정해서 재정의하는 것.
- 서브클래스의 메서드 오버라이딩을 하면 슈퍼클래스의 메서드를 은닉하고 재정의한다.
- 은닉한 슈퍼클래스의 메서드에 접근할수있을까?
- YES!어떻게?
super.메서드명();
하면된다
메서드 오버라이딩시 똑같아야 하는 것
- 메서드의 이름은 슈퍼클래스의 메서드 이름과 같아야한다.
- 매개변수의 개수, 타입, 순서는 슈퍼클래스의 메서드와 같아야한다.
- 리턴타입은 슈퍼 클래스의 메서드와 같아야한다.
메서드 오버라이딩시 달라도 되는 것
- 메서드 오버라이딩시 달라도 되는 것
- 접근지정자 : public > protected > 기본접근지정자(디폴트) > private
- 하지만 접근지정자가 작아지면 안된다.
- 메서드오버로딩과 용어헷갈리지않도록 주의!
- 오버로딩(Overloading) : 같은 이름의 메서드 여러개를 가지면서 매개변수의 유형과 개수가 다르도록 하는 기술
- 오버라이딩(Overriding) : 상속관계일때 사용하며 같은 이름의 메서드를 가진다. 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용
아래는 Person 클래스이다.
1 | public class Person{ |
아래는 spider 클래스이다.
1 | public class Spider { |
이제 오버라이딩해 볼 SpiderMan2 클래스이다.
SpiderMan2는 Person클래스를 상속하고 있다.
1 | public class SpiderMan2 extends Person{ |
애노테이션(Annotation)
- @Override
- 컴파일러등을 위한 주석으로 ‘이 메서드는 재정의한 메서드이니까 메서드 오버라이딩 규칙에 맞지 않으면 오류를 발생시켜라’라는 정보를 컴파일러에게 전달한다.
- 애노테이션 생략가능.
super키워드
- 생성자를 만들면 항상 super()로 먼저 슈퍼클래스를 실행한 뒤에 서브클래스를 실행한다.
- 하나의 파일안에 여러 class를 둘 수 있지만 이럴땐 두가지 규칙이 있다.
- 파일명과 동일한 class에만
public
을 붙일 수 있다. - 파일명과 동일한 class에만 메인메서드를 넣을 수 있다.
- 파일명과 동일한 class에만
- 보통 실무에서는 하나의 파일에는 하나의 class만 만든다. 구분하기 편하기때문에.
- super()는 두가지 기능을 한다.
- 조상멤버변수와 메서드를 참조.
- 조상의 생성자를 호출.
조상클래스의 생성자를 호출하기 위해 super()가 사용된다.명시적으로 super()를 이용해서 다른 생성자를 호출하는 코드가 없다면 컴파일러는 언제나 슈퍼클래스의 기본 생성자를 호출하는 super()를 생성해 첫 행헤 삽입하게 된다.
이는 결론적으로 최상위의 객체인 Object까지 모든 조상객체가 다 만들어지는 구조가 된다.
this와 super의 차이점
super()와 this()는 둘다 반드시 첫번째 문장에 와야한다.
따라서 둘이 함께 쓰지 못한다.
둘 중 하나만 쓸 수 있다.
- this가 현재 객체를 참조(나자신)
- super는 조상 객체를 참조(부모객체)
super예시 : this와 super의 차이점
super()와 this()는 모두 참조변수이다.
아래는 this와 super의 차이점을 설명해주는 super키워드를 사용한 예시이다.
Child는 두개의 멤버변수를 가진다 Parent클래스의 x와 Child클래스의 x.
1 | class Parent{ |
super예시 : 순서
아래 코드의 출력값의 순서는 어떻게 될까?
- 출력값의 순서
- main클래스에 따라 MyStudent 클래스를 먼저 실행하는데 extends되어있다 -> MyStydent생성자안에 super()가 생략되어있다.
- super()인 Student클래스가 먼저 실행되고 난 후
- MyStudent생성자의 println이 실행된다.
- 파라미터가 있는 생성자를 쓰게 된다면 super()가 에러나지않도록 항상 디폴트생성자를 기재해야한다!
1 | class Student{ |
- 혹시 아래 코드처럼 super()를 밑에 작성해도 같은 결과가 나올까?
1 | public class MyStudent extends Student{ |
아랫줄에 작성하면 에러Constructor call must be the first statement in a constructor
가 발생한다.
super()는 항상 생성자 구현부의 첫번째줄에 있어야한다.
Student 생성자의 생략된 super()는 Object를 상속받고있다.
모든 클래스는 Object를 상속받는다.