일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- public static final
- 얕은 복사
- extends
- 내부클래스
- has-a
- pycharm
- 자바
- 셔뱅
- Up Casting
- Wrapper class
- Stream
- access modifier
- 깊은 복사
- generic programming
- 엔드포인트
- lambda
- constructor
- 스트림
- singletone
- finalize
- parameter group
- Java
- node.js
- shebang
- arraycopy
- Inbound
- identityHashCode
- down casting
- dbeaver
- 파이참
- Today
- Total
٩(๑•̀o•́๑)و
20200304 본문
클래스에서 상속(inheritance)의 의미
- 새로운 클래스를 정의할 때 이미 구현된 클래스를 상속받아서 속성이나 기능이 확장되는 클래스를 구현함 -> 객체지향언어의 특징
- A라는 클래스보다 기능이 조금 더 확장된 유사한 클래스를 정의할 경우 A를 상속받아서 구현하면됨
- 코드의 재사용성 향상. 단 이때, 기존에 있던 클래스와 유사하되 조금더 확장된 클래스일 경우 사용. 이질적인 클래스간에는 상속을 사용해선 안됨
- 상속하는 클래스 : 상위클래스=parent class = base class = super class
- 상속받는 클래스 : 하위클래스=child class = derived class = subclass
- 클래스 정의시 extends 키워드 사용
- 자바에서 extends 뒤에는 딱 1개의 클래스명만 적을 수 있다. 즉 single inheritance만을 허용. (다중상속 허용하지 않음)
- 다이어그램에서는 하위->상위 방향으로 화살표
- 상위 클래스는 하위 클래스보다 일반적인 개념과 기능을 가짐. 하위 클래스는 상위 클래스보다 구체적인 개념과 기능을 가짐
- 하위 클래스에서 상위 클래스의 멤버변수에 직접 접근이 가능하려면 상위 클래스에서 protected 혹은 public으로 정의되어야함
하위 클래스가 생성되는 과정
- 하위 클래스가 생성될 때 상위 클래스가 먼저 생성됨
- 상위 클래스의 생성자가 호출되고 하위 클래스의 생성자가 호출됨
- 하위 클래스의 생성자에서는 무조건 상위 클래스의 생성자가 먼저 호출되어야함.
- 하위 클래스에서 상위클래스의 생성자를 호출하는 코드가 없는 경우 컴파일러는 상위 클래스 기본 생성자를 호출하기 위한 super()를 추가
- super는 상위 클래스의 메모리 위치(참조값)을 가지고있음 (cf. this는 자기자신의 메모리를 의미). this()로 다른 생성자를 호출하듯 super()를 통하여 상위 클래스의 디폴트 생성자를 호출할 수 있다.
- super()로 호출되는 생성자는 상위 클래스의 기본 생성자임
- 만약 상위 클래스의 기본 생성자가 없는 경우(매개 변수가 있는 생성자만 존재하는 경우. 이 경우에는 컴파일러가 기본생성자를 추가하지 않음) 하위 클래스에서 명시적으로 상위 클래스의 매개변수가 있는 생성자를 호출해야함
- 상위클래스에 기본생성자가 명시적으로 존재하거나 컴파일러에 의해 추가될 수 있는 경우에는 문제가 되지 않음.
- 이렇게 해야 하위 클래스만 생성하여도 상위 클래스에서 상속받은 모든 것들을 사용할 수 있음. 상위클래스의 속성을 사용할 수 있다는 의미는 상위 클래스의 속성이 힙메모리에 생성되어있다는 의미이기때문.
상속에서의 메모리 상태
- 상위 클래스의 인스턴스가 먼저 생성되고, 하위 클래스의 인스턴스가 생성됨.
- 하위 클래스의 생성자 호출-> 가장 먼저 super()에 의한 상위 클래스 생성자 호출->상위 클래스의 인스턴스 즉 상속되어지는 멤버변수들이 힙메모리에 생성 -> 하위클래스에만 존재하는 멤버변수들이 추가로 생성됨
- 하위클래스에서 super가 가리키는 위치는 상위 클래스의 인스턴스들이 메모리 위치값.
상위 클래스로의 묵시적(암시적) 형 변환(업캐스팅)
- 상위클래스type 변수 = new 하위클래스type();
- 상위 클래스type으로 변수를 선언하고 하위 클래스 인스턴스를 생성할 수 있음.
- 하위 클래스는 상위 클래스의 타입을 내포하고 있으므로(상속받았기때문), 상위 클래스로 묵시적 형변환이 가능함.
- 상속관계에서 모든 하위 클래스는 상위 클래스로의 묵시적 형 변환이 됨.(특별히 뭔가를 해주지않아도 자동으로 변환됨)
- 하위 클래스의 타입은 상위 클래스의 변수 타입으로 자동 형변환이 된다 = 업캐스팅
- 그 역은 성립하지 않음. 하위클래스 = new 상위클래스()는 성립할 수 없음. 하위클래스가 상위 클래스보다 더 확장된 개념이기때문
- 상위클래스type 변수 = new 하위클래스type(); 을 통하여 하위클래스의 생성자를 호출 -> 상위클래스의 인스턴스, 하위클래스의 인스턴스는 모두 생성이 되었으나, 상위클래스type변수가 접근할 수 있는 변수나 매개변수는 차이가 있다. 상위클래스type 변수는 상위클래스의 변수, 메서드에만 접근이 가능하다.(상위클래스 type이기때문) 하위클래스에서 확장된 변수, 메서드에는 접근이 불가.
오버라이딩(overriding)
- 상위 클래스에 정의된 메서드의 구현 내용이 하위 클래스에서 구현할 내용과 맞지 않는 경우 하위 클래스에서 동일한 이름의 메서드를 재정의 할 수 있음. 선언부는 동일하되 바디의 구현부가 다름
- 재정의하려는 메서드의 선언부를 동일하게 하여 하위클래스에서 바디를 다시 정의해주면됨. 이때 선언부 위에 Override annotation(@Override)를 붙여줘야함. 컴파일러에게 오버라이딩됨(재정의된 메서드)을 알려줌
- @Override를 쓴 후 상위 클래스에 선언된 선언부와 다른 메서드를 정의할 경우 에러발생
Annotation : 컴파일러에게 특정한 정보를 제공해주는 역할.
Annotation | description |
@Override |
재정의된 메서드라는 정보 제공 |
@FunctionalInterface |
함수형 인터페이스라는 정보 제공 |
@Deprecated |
이후 버전에서 사용되지 않을 수 있는 변수, 메서드에 사용됨 |
@SuppressWarnings |
특정 경고가 나타나지 않도록함. (ex. @SuppressWarnings(“deprecation”) : @Deprecated가 나타나지 않도록함) |
형 변환과 오버라이딩 메서드 호출
-> 상위클래스 var = new 하위클래스(); var.method1();
위 코드에서 method1() 은? (재정의되었다고 가정하에)
-> 자바에서는 항상 인스턴스(하위클래스)의 메서드가 호출됨.
==> 가상함수.
-> 자바는 기본적으로 모든 메서드가 가상메서드!
가상메서드(virtual method)
- 메서드의 이름과 메서드 주소를 가진 가상 메서드 테이블에서 호출될 메서드의 주소를 참조함
- 메서드보다 함수가 더 큰 개념. 메서드는 객제 지향 언어에서 멤버함수를 의미.
- 메서드의 이름은 컴파일되면 그 자체로 주소가됨. 따라서 같은 이름의 메서드는 존재하지 않음. (메서드의 이름이 같음은 같은 주소라는 의미이기때문)
- 오버로딩된 메서드들은 컴파일이될 때 매개변수의 타입에 따라 메서드명이 조금씩 달라진다
- 메서드에 대해 맵핑되는 주소값이 따로있음. 메서드가 수행하는 코드의 위치를 갖고있어야하기때문.(해당 위치로 제어가 넘어가야함) 이 주소를 갖고있는 맵핑테이블이 있는데 이게 바로 가상 메서드 테이블.
- 하위클래스에서 오버라이딩된 메소드는 상위클래스의 메소드와 다른 주소를 갖게됨
- 하위클래스에서 오버라이딩되지 않은 메서드는 상위클래스의 메서드와 동일한 주소를 가진다.
- 따라서 재정의된 메서드는 맵핑되는 주소가 각각있다.
- 실질적으로 호출되는 메서드는 타입에 기반한 것이 아닌 생성된 인스턴스에 기반하여 호출되는 것이 기본!!
==> 각 메서드들의 맵핑되는 주소를 관리하는 가상함수 테이블이 있고 여기의 어드레스 맵핑에 의하여 호출이 되기때문에 발생하는 현상
==> 상위클래스 var = new 하위클래스(); var.method1();
의 예제에서는
- method1이 재정의가 된 경우 : 위클래스에 의하여 생성된 인스턴스이기때문에 재정의된 method1이 호출된다.
- method1이 재정의가 되지 않은 경우 : 상위클래스에 정의된 method1이 호출된다.