JAVA 공부중

중복 줄어들고, 편리한 확장이 가능함.
상속된 상태에서 자식클래스를 호출하면 메모리 구조가 자식 객체 안에 부모와 자식 둘 다 존재한다.
상속관계에서 객체를 생성하면 내부에는 부모와 자식 모두 생성됨.
상속관계의 객체를 호출할 때 대상 타입을 정해야함. 이때 호출자의 타입을 통해 대상 타입을 찾는다.
( 자식 타입으로 객체를 호출 후 메서드 실행 시 자식 타입에서 해당 메서드가 있는지 확인 후 없으면 부모 타입에서 해당 메서드를 찾는다. 부모에도 없으면 그 부모로 계속 올라가면서 찾는데 없으면 컴파일 오류 발생.)
메서드 오버라이딩 조건
package extends1.access.parent;
public class Parent {
public int publicValue;
protected int protectedValue;
int defaultValue;
private int privateValue;
public void publicMethod() {
System.out.println("Parent.publicMethod");
}
protected void protectedMethod() {
System.out.println("Parent.protectedMethod");
}
void defaultMethod() {
System.out.println("Parent.defaultMethod");
}
private void privateMethod() {
System.out.println("Parent.privateMethod");
}
public void printParent() {
System.out.println("==Parent 메서드 안==");
System.out.println("publicValue = " + publicValue);
System.out.println("protectedValue = " + protectedValue);
System.out.println("defaultValue = " + defaultValue); //부모 메서드 안에서 접근 가능
System.out.println("privateValue = " + privateValue); //부모 메서드 안에서 접근 가능
//부모 메서드 안에서 모두 접근 가능
defaultMethod();
privateMethod();
}
}
package extends1.access.child;
import extends1.access.parent.Parent;
public class Child extends Parent {
public void call() {
publicValue = 1;
protectedValue = 1; //상속 관계 or 같은 패키지
//defaultValue = 1; //다른 패키지 접근 불가, 컴파일 오류
//privateValue = 1; //접근 불가, 컴파일 오류
publicMethod();
protectedMethod(); //상속 관계 or 같은 패키지
//defaultMethod(); //다른 패키지 접근 불가, 컴파일 오류
//privateMethod(); //접근 불가, 컴파일 오류
printParent();//이건 컴파일 오류 안남. public이고, 부모클래스로 들어가서 다른 메서드를 실행한것이므로 오류 안남.
}
}
부모와 자식의 필드명이 같거나 메서드 오버라이딩 되어있으면 자식에서 부모의 필드, 메서드를 호출할 수 없음 -> super를 이용해서 부모를 참조할 수 있음.
package extends1.super1;
public class Parent {
public String value = "parent";
public void hello() {
System.out.println("Parent.hello");
}
}
package extends1.super1;
public class Child extends Parent {
public String value = "child";
@Override
public void hello() {
System.out.println("Child.hello");
}
public void call() {
System.out.println("this value = " + this.value); //this 생략 가능 System.out.println("super value = " + super.value);
this.hello(); //this 생략 가능 super.hello();
}
}
package extends1.super2;
public class ClassA {
public ClassA() {
System.out.println("ClassA 생성자");
}
}
package extends1.super2;
public class ClassB extends ClassA {
public ClassB(int a) {
super(); //기본 생성자 생략 가능
System.out.println("ClassB 생성자 a=" + a);
}
public ClassB(int a, int b) {
super(); //기본 생성자 생략 가능
System.out.println("ClassB 생성자 a=" + a + " b=" + b);
}
}
package extends1.super2;
public class ClassC extends ClassB {
public ClassC() {
super(10, 20);
System.out.println("ClassC 생성자");
}
}
package extends1.super2;
public class Super2Main {
public static void main(String[] args) {
ClassC classC = new ClassC();
// 호출 하면 super를 타고 타고 올라가서 최상위 부모클래스부터 결과가 출력됨.
}
}
코드를 변경하여 아래같이 this를 이용하더라도 결국 super를 타고 한번은 super를 호출해야함.
package extends1.super2;
public class ClassB extends ClassA {
public ClassB(int a) {
this(a, 0); //기본 생성자 생략 가능
System.out.println("ClassB 생성자 a=" + a);
}
public ClassB(int a, int b) {
super(); //기본 생성자 생략 가능
System.out.println("ClassB 생성자 a=" + a + " b=" + b);
}
}
final 클래스 : 상속 불가 ( 자식 클래스한테 상속 안시켜줌)
final 메서드 : 오버라이드 불가 ( 자식 클래스한테 오버라이드 안시켜줌)