부모: 상위 클래스, 슈퍼클래스,
자식 : 서브클래스, 파생클래스
부모가 자식에게 상속을 해줬다 -> 언제든 쓸 수 있다. 하지만 부모 소유이다.
상속?
클래스를 계층화 하는 것을 상속이라고 한다.
상속하는 이유?
- 객체를 설계하다 보면 비슷한 클래스들끼리 중복요소가 생긴다.
ex)책이라는 클래스에 꼭 들어가야 하는 것(저자, 제목, 출판사, 페이지 )을 가진 부모 클래스가 이것을 자식에게 상속해주면 자식은 자유롭게 쓸 수 있다.
상속시 자식은 extends 라는 키워를 사용한다.
자바는 단일상속만을 지원한다. 부모를 한 명으로 두고 사용하는 것을 단일상속이라고 한다.
상속에서 private를 사용하면 상속의 의미가 퇴색된다. private인데 상속을 어떻게 해
부모의 기억공간을 자식에게 상속하고 싶다면 private을 쓰면 안된다.
그래서 자식만큼은 접근을 가능케 하는 protected를 사용한다.
public은 자식 말고 다른 것도 접근 가능하다. private은 자식마저 접근 할 수 없다. protected는 자식만 접근 할 수 있다/ 상속관계서 접근을 허용한다.
public class RempVO extends Employee {
public RempVO(){
super();
}
extends기준으로 오른쪽이 부모Employee 이고, 왼쪽이 자식RempVO이다
super(); 는 상위 클래스를 가리킬 때 사용한다. .
명시하지 않으면 컴파일러가 자동으로 추가해준다.
자식 생성 전 부모가 먼저 생성되어 있어야 하는데, super가 호출되면 자식이 아니라 부모 먼저 메모리에 생성된다.
super에 의해 new Employee()가 호출된다.
이렇게 생성 된 후, 부모와 자식이 붙어있는 형태로 메모리에 생성된다.
먼저 Employee가 생성되고 RempVO가 부모까지 확장해 부모까지 쓸 수 있게된다.
RempVO는 본인 뿐 만 아니라 부모인 Employee 공간까지 접근 할 수 있다.
//사원이라는 데이터 클래스를 담기위한 VO
public class Employee { //extends Object 이게 생략되어있음
private String name;
private String empDate;
private String dept;
private boolean marriage;
public Employee(){
super(); //상위 클래스의 생성자를 호춯 //object부터 생성
}
}
부모 Employee는 어느 사원에게나 있을 법한 상태변수를 가지고 있다.
//일반사원vo
public class RempVO extends Employee{
public RempVO(){
super();
}
}
그것을 자식이 extends에 의해 상속받고, super에 의해 부모 메모리 생성 후 자식을 생성한다. (super()는 자동 생성되기 때문에 생략해도 괜찮다.)
public class EmployeeTest {
public static void main(String[] args) {
//일반사원 한 명의 객체 생성 , 데이터 저장 후 출력
RempVO vo = new RempVO();// 상속 받은 상태
vo.name="";
}
}
부모가 private이라 상속받은 변수를 사용 할 수 없다..
이럴 때 protected를 사용한다. protected는 같은 패키지 안에서만 사용할 수 있다
집떠나면 남..
public class Employee { //extends Object 이게 생략되어있음
protected String name;
protected int age;
protected String dept;
protected boolean marriage;
부모의 상태변수를 protected로 바꾼다.
public class EmployeeTest {
public static void main(String[] args) {
//일반사원 한 명의 객체 생성 , 데이터 저장 후 출력
RempVO vo = new RempVO();// 상속 받은 상태
vo.name="rempvoname";
vo.age =10;
vo.dept ="HR";
vo.marriage =false;
}
}
vo.name, vo.age.. 이렇게 써주면 된다.
부모와 자식이 같은 패키지 안에 있어야 가능한것이다.
부모 클래스에 toString() 추가 후 vo.toString()해서 사용해보자
하지만
자식이 부모의 데이터 공간에 유효하지 않은 데이터를 넣을 수도 있다.
ex_ vo.age =234987; 해도 문제가 없다
RempVO의this는 부모의 상태변수를 가리킨다. 그래서 매개변수로 값을 받아 부모의 상태정보에 값을 넣는다. 이게 일종의 초기화가 될 수 있다
하지만 여전히 자식이 부모 상태에접근해 데이터 넣기가 가능하다 -> 정보은닉이 아니다. 이상한 데이터 값을 넣어도 막지 못한다.
생성자에 의해 초기화를 해보자면
public RempVO(String name, int age,String dept, boolean marriage ){
this.name= name;
this.age = age;
this.dept =dept;
this.marriage =marriage;
//자식이 부모의 기억공간을 초기화 중이다.
}
}
자식 클래스에 생성자를 만들어 부모 기억공간을 초기화하는 중이다.
public class EmployeeInitTest {
public static void main(String[] args) {
RempVO vo = new RempVO("NAME",333,"DEV",true);
System.out.println(vo.toString());
}
}
초기화는 자기 자신이 하는 경우가 바람직하다. 상태변수의 접근 제어자도 private이 맞는 것이다
그럼 어떻게 값을 넣나?
-> 자식이 값을 받고 그 값을 부모에게 넘겨줘 대신 초기화 해주는 것이 바람직하다.
하지만 접근 제어자를 private으로 하면 this는 전부 에러가 난다.
부모한테 초기화 부탁을 해보자.
일단 부모 상태 정보 멤버변수의 접근제어를 private으로 변경한다 - 자식이 super("name",1); 사용 -부모의 생성자에서 초기화
부모 클래스에 Employee 생성자를 하나 더 생성한다.
public Employee(String name, int age, String dept, boolean marriage) {
this.name = name;
this.age = age;
this.dept = dept;
this.marriage = marriage;
}
이렇게 부모가 값을 받아 저장한다.
public RempVO(String name, int age,String dept, boolean marriage ){
super(name,age,dept,marriage);
//부모의 생성자 호출하고 값을 전달
}
자식은 super();을 사용해 호출하고 전달한다.
public class EmployeeTest {
public static void main(String[] args) {
//일반사원 한 명의 객체 생성 , 데이터 저장 후 출력
RempVO vo = new RempVO("whffu",22,"dev",true);// 상속 받은 상태
System.out.println(vo); //toString 생략
}
}
EmployeeTest서 값을 넣을 때도 vo.name -"name"; 이 아니라
객체 생성하면서 바로 넣는다 RempVo vo = new rempVo("name", 3);
'JAVA > Bootcamp 자바' 카테고리의 다른 글
Downcasting, 객체형변환 (0) | 2024.02.28 |
---|---|
Override재정의, Upcasting, 동적바인딩 (1) | 2024.02.28 |
class, object, instance (0) | 2024.02.26 |
JVM의 메모리영역, 객체 생성과 static (1) | 2024.02.26 |
Static, None Static, JVM, Stack Area (0) | 2024.02.26 |