- 객체 지향의 상속
- 부모 클래스에 만들어진 필드, 메소드를 자식 클래스가 물려받음
- 상속을 통해 간결한 자식 클래스 작성
- 동일한 특성을 재정의할 필요가 없어 자식 클래스가 간결해짐
- 객체 지향에서 상속의 강점
- 멤버의 중복 작성이 불필요 -> 클래스의 간결화
- 클래스들의 계층적 분류 -> 클래스 관리 용이
- 클래스 재사용과 확장 용이, 새로운 클래스의 작성 속도 빠름 -> 소프트 웨어의 생산성 향상
- Java에서의 상속 선언
public class Person{}//부모클래스(Super Class)
public class Student extends Person{}//Person의 자식클래스(Sub Class)
public class StudentWorkers extends Student{}//Student의 자식 클래스(Sub class)
- 클래스 상속
//클래스 상속 예시
class Point{
private int x,y ;// x,y는 Point 클래스의 set(), showPoint()에서만 접근 가능
public void set(int x, int y){
this.x = x;
this.y = y;
}
public void showPoint(){//점의 좌표 출력
System.out.print("(" + x + ", " + y + ")");
}
}
class ColorPoint extends Point{
private String color;//점의 색
public void setColor(String color){
this.color = color;
}
public void showColorPoint(){
System.out.print(color);
showPoint();//서브클래스에서 슈퍼클래스 메소드 호출
}
}
public class ColorPoint example{
public static void main(String []args){
Point p = new Point();//Point 객체 생성
p.set(1,2);//Point 클래스의 set호출
p.showPoint();//출력 :(1, 2)
ColorPoint cp = new ColorPoint(); // ColorPoint 객체 생성
cp.set(3,4);// ColorPoint의 set호출
cp.setColor("red");// ColorPoint의 setColor호출
cp.showColorPoint();//출력 :red(3, 4)
}
}
- 인스턴스(객체) p 생성 -> 레퍼런스 p는 Point 객체 가리킴
- 인스턴스(객체) cp 생성 -> 레퍼런스 cp는 ColorPoint 객체 가리킴
p |
int x -> 1 int y -> 2 void set() void showPoint() |
cp |
int x -> 3 x,y는 point 클래스 int y -> 4 내부에서만 접근 가능(private) void set() void showPoint() |
String color -> red void setColor void showColorPoint() |
- Java 상속의 특징
- 클래스의 다중 상속 지원 X
- 상속 횟수 무제한
- 상속의 최상위 조상 클래스는 java.lang.Object 클래스
- 모든 클래스는 자동으로 java.lang.Object를 상속받음
- 자바 컴파일러에 의해 자동으로 이루어짐
- java.lang.Object 클래스
- 필드는 없음
- 11개의 메소드만 존재
주요 메소드 | 설명 |
clone() | 객체 자신의 복제본 반환 (Cloneable 인터페이스를 반드시 implement) |
equals(Object obj) | 객체 자신의 참조값과 obj의 참조값이 같은지 비교 |
toString | 클래스명+@+해시코드(16진수) 반환 |
notify() notifyAll() |
이 객체를 사용하려고 대기중인 쓰레드중 하나 혹은 모두 재개 |
finalize() | 이 객체에 대한 참조가 더 없다고 판단되면 가비지 컬렉터가 호출 |
getClass() | Class 인스턴스를 반환 |
hashCode() | 객체 자신의 해시코드 반환 |
wait(long timeout) | 쓰레드를 지정한 시간동안 기다리게 함 |
- 상속과 접근 지정자
- 상속관계에서 주의할 접근 지정자 : private, protcted
슈퍼 클래스의 접근 지정자 | 접근 가능 범위 |
private | 슈퍼 클래스의 private 멤버는 다른 모든 클래스에 접근 불허 클래스 내의 멤버들에게만 접근 허용 |
디폴트 | 동일 패키지 내 모든 클래스에 접근 허용 |
public | 다른 모든 클래스에 접근 허용 |
protected | 동일 패키지 내의 모든 클래스에 접근 허용 다른 패키지에 있어도 해당 클래스의 서브 클래스에 접근 허용 |
class Person{
private int weight;
int height;
protected int age;
public String name;
public void setWeight(int weight){ this.weight = weight; }
}
class Me extends Person(){
public void set(){
age = 23;// 슈퍼클래스의 protected멤버 접근 가능(다른 패키지여도!)
name = "김수환";// 슈퍼클래스의 public멤버 접근 가능
//weight = 65; -> !컴파일 오류! 슈퍼클래스의 private 접근 불가
height = 169;// 슈퍼클래스의 디폴트 멤버 접근 가능(같은 패키지일 때만)
setWeight(65);// private멤버는 set함수로 간접 접근
}
}
- new에 의해 서브 클래스의 객체가 생성될 때
- 호출 순서 : 서브 클래스 생성자 -> 슈퍼 클래스 생성자
- 생성 순서 : 슈퍼 클래스 생성자 -> 서브 클래스 생성자
class Grandpa{
public Grandpa(){}//4.Grandpa 생성자 생성
}
class Papa extends Grandpa{
public Papa(){}//3.Grandpa 생성자 호출 5.Papa 생성자 생성
}
class Son extends Papa{
public Son(){}//2.Papa 생성자 호출 6.Son 생성자 생성
}
public class ConstructorOrder{
public static void main(String[] args){
Son sonny = new Son();//1.Son 생성자 호출
}
}
- 상속 관계에서의 생성자
- 슈퍼 클래스와 서브 클래스 각각 여러 생성자 작성 가능
- 서브 클래스 생성자 작성 원칙
- 서브 클래스 생성자에서 슈퍼 클래스 생성자 하나 선택
- super()메소드 이용 -> 슈퍼클래스 생성자
- this()메소드 <- 자기 자신의 다른 생성자
- 서브 클래스에서 슈퍼 클래스 생성자를 선택하지 않는 경우
- 컴파일러가 자동으로 슈퍼 클래스의 기본 생성자 선택
- 서브 클래스 생성자에서 슈퍼 클래스 생성자 하나 선택
class Papa(){
public Papa(){}//3.Papa 생성자 생성
public Papa(int x){}
}
class Son(){
public Son(int x){}//2.Papa()생성자(기본 생성자) 호출 4.Son 생성자 생성
}
public class example(){
public static void(String[] args){
Son sonny = new Son(5); //1.Son(int)생성자 호출
}
}
- 슈퍼 클래스에 기본 생성자가 없어 오류난 경우
class Papa(){
//!컴파일 오류! 기본 생성자 없음
public Papa(int x){}
}
class Son(){
public Son(){};//2.Papa()생성자(기본 생성자) 호출 4.Son 생성자 생성
}
public class example(){
public static void(String[] args){
Son sonny = new Son(); //1.Son 기본 생성자 호출
}
}
ㄴ> 컴파일러에 의해 "Implicit super constructor Papa() is undefined. Must explicitly invoke another constructor"
오류 발생
- super()를 이용한 명시적 선택
- super(parameter);
- 반드시 서브클래스 생성자 코드의 제일 첫라인에 와야함
class Papa(){ public Papa(){}3.Papa 생성자 생성 public Papa(int x){} } class Son(){ public Son(){} public Son(int x){//2.Papa()생성자(기본 생성자) 호출 4.Son 생성자 생성 super(x);//반드시 첫줄에 와야함 } } public class example(){ public static void(String[] args){ Son sonny = new Son(5); //1.Son(int)생성자 호출 } }
'JAVA' 카테고리의 다른 글
[Java.3-3] 메소드 오버라이딩 (0) | 2022.04.16 |
---|---|
[Java.3-2] 업캐스팅과 다운캐스팅 (0) | 2022.04.16 |
[Java.2-5] static 과 final (0) | 2022.04.15 |
[Java.2-4] 접근 지정자 (0) | 2022.04.15 |
[Java.2-3] 객체 소멸과 가비지 (0) | 2022.04.15 |