Week6(상속)
Last updated
Was this helpful?
Last updated
Was this helpful?
부모 클래스에서 만들어진 필드와 메소드를 자식 클래스가 물려받아서 사용가능 하게 되는 것이다.
객체지향적으로는 부모의 특성을 자식이 물려받는 것
상속을 통해서 코드의 중복을 제거하고 클래스를 간결하게 구현할 수 있게 된다.
장점
클래스의 간결화 - 멤버의 중복 작성 불필요
클래스 관리 용이 - 클래스들의 계층적 분류
소프트웨어의 생산성 향상 - 클래스 재사용과 확장 용이
위 그림을 보게되면 student클래스와 teacher클래스는 person이라는 클래스를 상속했기 때문에 body라는 변수, eat()함수, walk()함수를 공통적으로 사용할 수 있다.
person이라는 함수를 따로 선언하고 상속받지 않았다면 student클래스와 teacher클래스에서 따로 공통된 변수와 메소드를 선언해줘야하고 이는 새로운 사람타입의 클래스를 생성할 때도 따로 새로운 함수에서 선언해줘야하는 불편함이 있다. => 코드 중복을 제거하고 코드를 간결하게 구현가능, 클래스의 재사용이 쉬워지고 클래스의 확장 또한 용이해진다.
자바 상속의 특징
자바에서는 클래스의 다중 상속을 지원하지 않는다.
클래스를 여러 개 상속받는 다중 상속을 지원하지 않는다.
상속의키워드인 extends뒤에는 단 하나의 클래스명을 지정할 수 있다.
자바에서는 상속의 횟수에 제한을 두지 않는다.
자바에서 계층 구조의 최상위에 java.lang.Object 클래스가 있다.
자바에서 모든 클래스는 Object클래스를 자동으로 상속받도록 컴파일된다.
만약 클래스2이 클래스1를 상속받는다고 했을때 컴파일시 클래스1을 상속받은 다음 컴파일이 끝나면 Object을 상속받는다.
Object 클래스는 유일하게 슈퍼클래스를 가지지 않는 클래스이다.
만약 오버라이딩을 한 뒤, 해당 메소드를 호출하게되면 오버라이딩한 메소드가 불리워지게 된다 => 밑에서 다시 자세하게 알아본다
위의 경우, 부모클래스의 원형 메소드를 호출할 때 사용하는 키워드가 super이게 된다.
super키워드를 이용한다면 정적 바인딩을 통해서 슈퍼 클래스의 멤버에 접근할 수 있게 된다.
super.멤버 / super.메소드
this vs super
this와 super는 모두 레퍼런스로써
this로는 현재 객체의 모든 멤버에 접근하게 되고, this.객체 내의 멤버
이렇게 사용한다.
super는 현재 객체 내에 있는 슈퍼 클래스 멤버를 접근하게 되고, super.객체내의 슈퍼클래스의 멤버
이렇게 사용한다.
+++super()에 대해서+++
부모클래스에서 접근지정자를 지정해서 자식에서 접근을 제한할 수 있다.
(접근 지정자 : 저번주에도 정리를 해봤다.)
public : 클래스내부, 동일패키지, 하위클래스, 그 밖의 영역에서 사용가능 / 상속받은 클래스들이 사용가능
protected : 클래스내부, 동일패키지, 하위클래스에서 사용가능 / 상속받은 클래스들이 사용이 가능하다
default : 따로 지정해주지 않는 경우이고 클래스내부, 동일패키지에서 사용가능
private : 클래스 내부에서만 사용가능 / 상속받은 자식클래스가 부모클래스를 사용할 수 없다
=>부모클래스에서 protected, public으로 지정한 변수, 메소드를 자식이 사용할 수 있다.
자식 클래스의 생성자에서 부모 클래스의 생성자를 명시적으로 선택해줘야한다.
여기서 사용하는게 super() 함수이다
super()는 부모 클래스의 생성자를 호출하는 코드이다
괄호안에 인자를 넣어서(super(10)) 슈퍼클래스의 생성자를 호출할 수도 있음
중요 : super()는 반드시 생성자의 첫 라인 에서만 사용되어야 한다.
부모 클래스와 자식 클래스의 메소드 사이에서 발생하는 관계로서, 부모 클래스에 선언된 메소드와 같은 이름, 같은 리턴 타입, 같은 매개 변수 리스트를 갖는 메소드를 자식 클래스에서 재작성하는 것이다
간단히는 부모 클래스의 메소드 무시하기 / 덮어쓰기
같은 이름으로 다른 내용을 구현한다는 점에서 이는 객체 지향의 다형성을 만족시켜준다.
제약 사항
부모 클래스의 메소드와 똑같이 작성해야한다.
메소드의 이름, 동일한 매개변수 타입과 갯수, 동일한 리턴 타입을 가져야한다.
부모 클래스 메소드의 접근지정자보다 접근의 범위를 좁힐 수 없다
public, protected, defult, private순서로 범위가 나뉘다.
만약 protected일 경우, 오버라이딩하는 자식 클래스에서는 public이나 protected으로만 오버라이딩 할 수 있다.
*참고 : static이나 private 또는 final로 선언된 메소드는 자식 클래스에서 오버라이딩할 수 없다.
동적 바인딩(dynamic binding) : 오버라이딩된 메소드 호출
실행할 메소드를 컴파일 단계에서 결정하지 않고 런타임시 결정하는 것을 의미함
=> 어떤 경우에서든 자바에서 오버라이딩 된 메소드가 있다면 동적 바인딩을 통해 오버라이딩된 메소드가 무조건 실행된다.
Method Dispatch : 어떤 메소드를 호출할지 결정하여 실제로 실행시키는 과정
종류로써는 dynamic, static타입이 존재한다
만약 컴파일 시, 호출할 메소드를 알 수 있다면 static / 런타임 시 호출할 메소드를 알 수 있다면 dynamic
Static Dispatch
Dynamic Dispatch
토비님 강의 : https://www.youtube.com/watch?v=s-tXAHub6vg
다이나믹 메소드 디스패치는 인터페이스를 이용해 참조함으로서 호출되는 메소드가 동적으로 결정되는 것을 의미함
인터페이스를 타입으로 메소드를 호출하고, 컴파일러는 타입에 대한 정보를 알고 있음으로 런타임시에 호출 객체를 확인해서 해당 객체의 메소드를 호출한다.
런타임에 참조되는 객체의 타입에 의존해 호출될 메소드를 결정하게 된다.
추상 클래스는 상속에서 부모 클래스로써 사용된다.
추상 메소드 : 선언은 되어있으나 코드가 구현되어있지 않은, 틀만 있는 메소드 / abstract 키워드를 사용
추상 클래스는 객체(인스턴스)를 생성할 수 없음 - 객체를 생성할 목적으로 만든 클래스가 아님
추상 클래스를 단순히 상속받는 자식 클래스는 추상클래스가 된다
추상 클래스를 이용하게되면 응용프로그램의 설계와 구현을 분리해서 사용할 수 있고 추상 클래스는 계층적 상속 관계를 가지는 클래스의 구조를 만들 때 적합하다.
클래스 : final이 클래스 이름 앞에 사용되면 클래스를 상속받을 수 없음을 말한다.
메소드 : 메소드 앞에 final 속성이 붙으면 해당 메소드는 더 이상 오버라이딩 할 수 없음을 뜻한다
변수/상수 : 상수를 정의할 때 final 키워드를 덧붙여서 상수를 정의한다
final로 상수 필드를 정의할 때는 선언 시에 초기값을 지정해줘야 한다.
한 번 정의되면 값을 변경할 수 없다.
static final => 프로그램 전체에서 공유하여 사용할 수 있는 상수
java.lang은 자바 프로그램에서 가장 많이 사용되는 패키지로써 자바 프로그램 내에서 import 없이 자동으로 포함된다.
여기서 Object패키지는 java.lang 패키지 내의 최상위 클래스이다 = 모든 자바 클래스는 Object 클래스로부터 상속받는 개념
필드를 가지지 않으며 총 11개의 메소드만으로 구성되어있음
자주 사용되는 메소드
toString()
기본 동작 : 객체의 해쉬코드를 출력
override의 목적 : 객체의 정보를 문자열 형태로 표현하고자 할 때
=> String 객체를 출력하게 되면 String 객체가 저장하고 있는 문자열이 출력되는데 이것의 이유는 String 클래스가 toString()을 override하고 있기 때문이다
=> 즉 toString()은 어떤 객체의 정보를 문자열 형태로 표현해야 할 떄 호출하는 메소드임
equals()
기본 동작 : '==' 연산 후 결과값 리턴
override의 목적 : 물리적으로 다른 메모리에 위치하는 객체여도 논리적으로 동일함을 구현하기 위해
equals을 사용해서 두 객체의 동일함을 논리적으로 override할 수 있다.
hashCode()
기본 동작 : JVM이 부여한 코드 값, 인스턴스가 저장된 가상머신의 주소를 10진수로 반환
override의 목적 : 두 개의 서로 다른 메모리에 위치한 객체가 동일성을 갖기 위해
해시코드 : JVM이 인스턴스를 생성할 때 메모리 주소를 변환해서 부여하는 코드이다. 실제 메모리 주소값과는 다른 값이며 실제 메모리 주소는 System.identityHashCode으로 확인 가능
자바에서의 동일성
equals()의 리턴값이 true
hashCode()의 리턴값이 동일함
=>그래서 일반적으로 equals()와 hashCode()는 같이 override함