
class 서브클래스 extends 슈퍼클래스 { ... }
super(파라미터) 이용// 묵시적 슈퍼클래스 생성자 선택
class A{
public A(){ ... } //기본생성자
public A(int x) { ... } //생성자
}
class B extends A {
public B() { ... }
public B(int x) { ... } //슈퍼클래스의 기본생성자 호출
}
public class Example {
public static void main(String[] args) {
B b;
b = new B(5); // B(int x)생성자 호출 -> A()기본생성자 호출
}
}
// 명시적 슈퍼클래스 생성자 선택
class A{
public A(){ ... }
public A(int x) { ... }
}
class B extends A {
public B() { ... }
public B(int x) {
super(x);
...
}
}
public class Example {
public static void main(String[] args) {
B b;
b = new B(5); // B(int x)생성자 호출 -> A(int x)생성자 호출
}
}
: 서브클래스의 레퍼런스를 슈퍼클래스 레퍼런스에 대입하는 것
슈퍼클래스명 클래스변수 = new 서브클래스명(); : 업캐스팅클래스변수 instanceof 클래스명class A {
int a1; //A의 멤버필드
public int a2(){ ... } //A의 멤버메소드
}
class B extends A {
int b1; //A의 멤버필드
public int b2() { ... } //B의 멤버메소드
}
A a = new B(); //업캐스팅
a.a1 = 값;
a.a2();
//a.b1 = 값; //컴파일 오류
//a.b2(); //컴파일 오류
a instanceof A //true
a instanceof B //true => new B() 객체는 A타입이면서, 동시에 B타입
: 슈퍼클래스 레퍼런스를 서브클래스 레퍼런스에 대입
서브클래스명 클래스변수 = (서브클래스명)업캐스팅된변수; : 다운캐스팅A a = new B(); //업캐스팅
B b = (B)a; //다운캐스팅(강제 타입 변환)
b.a1 = 값;
b.a2();
b.b1 = 값; //오류 발생x
b.b2(); //오류 발생x
: 슈퍼클래스 메소드의 원형(메소드명, 인자 타입, 인자 개수, 리턴 타입)과 동일하게 서브클래스에서 메소드를 재정의(중복 작성)하는 것
class A {
void f() { Sys.out.println("A의 f()"); } //A의 멤버메소드
}
class B extends A {
void f() { Sys.out.println("B의 f()"); } //B의 멤버메소드(A의 f()를 오버라이딩)
}
A v1 = new A();
v1.f(); //A의 f()
B v2 = new B();
v2.f(); //B의 f()
A v3 = new B();
v3.f(); //B의 f() => A의 f()를 호출해도, 동적바인딩되어 오버라이딩 된 메소드인 B의 f()가 실행
super.슈퍼클래스의멤버 : 슈퍼클래스의 멤버에 접근class A {
protected String a1;
public void f1() {
f2();
}
public void f2() {
System.out.println(a1);
}
}
public class B extends A {
protected String a1;
public void f2() {
a1 = "Sub";
super.a1 = "Super";
super.f2();
System.out.println(a1);
}
public static void main(String [] args) {
A v = new B(); //업캐스팅
v.f1(); //클래스A의 f1()메소드 실행
// -> 오버라이딩으로 f2()함수는 클래스B의 f2()메소드 실행(동적바인딩)
// -> 클래스B의 a1필드에 "Sub"대입, 클래스A의 a1필드에 "Super"대입
// -> 클래스A의 f2()메소드 실행(정적바인딩)하여 클래스A의 a1필드 출력
// -> 클래스B의 a1필드 출력
//결과 : Super \n Sub
}
}
| 메소드 오버로딩 | 메소드 오버라이딩 | |
|---|---|---|
| 선언 | 동일 클래스 또는 상속관계에서 동일한 메소드명 중복 작성 | 서브클래스에서 슈퍼클래스에 있는 메소드와 동일한 메소드명 재작성 |
| 목적 | 사용의 편리성 향상 | 서브클래스에서 새로운 기능의 메소드 재정의 |
| 조건 | 메소드명 동일, 인자 개수/타입 달라야함 | 메소드명, 인자 타입/개수, 리턴타입 등 모두 동일! |
| 바인딩 | 정적 바인딩(컴파일 시 중복된 메소드 중 호출메소드 결정) | 동적 바인딩(실행 시간에 오버라이딩된 메소드 찾아 호출) |
//예시
abstract class Caculator { //추상클래스
public abstract int cal(int a, int b); //추상메서드(원형만 작성)
}
//추상메서드를 구현한 서브클래스들
class AddCalc extends Caculator {
@Override //오버라이딩 표시를 해줌으로써 시간복잡성 줄일 수 있음
public int cal(int a, int b) { return a+b; }
}
class SubCalc extends Caculator {
@Override
public int cal(int a, int b) { return a-b; }
}
class AvgCalc extends Caculator {
@Override
public int cal(int a, int b) { return (a+b)/2; }
}
public class GoodCalc {
public static void main(String[] args){
//Calculator c = new Calculator(); //추상클래스는 인스턴스 생성 불가
AddCalc a = new AddCalc();
System.out.println(a.cal(2,3));
SubCalc s = new SubCalc();
System.out.println(s.cal(2,3));
AvgCalc g = new AvgCalc();
System.out.println(g.cal(2,3));
}
}
[접근제어자] interface 인터페이스명 { … } : 인터페이스 선언interface I {
[public static final] int 변수명 = 상수값; //상수 필드
[public abstract] 리턴타입 추상메소드명(); //추상 메소드
[public] default 리턴타입 디폴트메소드명() { 메소드코드 }; //디폴트 메소드
private 리턴타입 프라이빗메소드명() { 메소드코드 }; //프라이빗 메소드
[public|private] static 리턴타입 스태틱메소드명() { 메소드코드 }; //스태틱 메소드
}인터페이스명 인터페이스변수; : 인터페이스의 레퍼런스 변수 선언인터페이스변수 = new 인터페이스명();interface I1 { void a1(); }
interface I2 { void a2(); }
interface I3 extends I1,I2 { void a3(); } //인터페이스I1,I2에 추상메서드 추가한 인터페이스I3여러 인터페이스 동시 구현 가능(class 클래스명 implements 인터페이스명1,인터페이스명2,…{})
추상메소드는 반드시 구현
디폴트 메소드는 자동 상속 (따로 구현 안해도 됨! 충돌 시 오버라이딩 사용!)
인터페이스 내의 메소드 외에 추가로 메소드 작성 가능
class A implements I3 { //클래스A는 인터페이스 I1,I2,I3을 모두 구현
//인터페이스의 모든 추상 메소드 구현
public void a1() { System.out.println("첫번째 인터페이스"); }
public void a2() { System.out.println("두번째 인터페이스"); }
public void a3() { System.out.println("세번째 인터페이스"); }
//새로운 메소드 추가 가능
public void a4() { System.out.println("클래스의 멤버메소드"); }
}
I3 레퍼런스 = new A(); //업캐스팅 가능
interface I { ... }
class A { ... }
class B extends A implements I { ... }