" 자바의 상속에 대해 학습하세요. "
상속(Inheritance): 부모 클래스에 만들어진 필드, 메소드를 자식 클래스가 물려받는 것.
동일한 특성을 재정의할 필요가 없어 자식 클래스를 구현할 때 간결해져 클래스간 계층구조를 분류하고 관리하기 쉬워지는 효과가 있다.
public class Person { ... }
public class Student extends Person {
// Person을 상속받는 클래스 Student 선언
}
public class StudentWorker extends Student {
// Student를 상속받는 클래스 StudentWorker 선언
}
// 다음과 같이 다중상속을 구현하려 하면 컴파일 에러가 생김
public class ToniKroos extends Professor, Player { ... }
super 키워드: 서브 클래스가 슈퍼 클래스에 접근이 가능하게함. 슈퍼 클래스의 참조 변수라고 생각하면 됨
class Shape {
protected String name;
public void paint() {
draw();
}
public void draw() {
System.out.println(name);
}
}
public class Circle extends Shape {
protected String name;
@Override
public void draw() {
name = "Circle";
super.name = "Shape"; // super 키워드를 통해 정적 바인딩으로 처리됨
super.draw(); // super 키워드를 통해 정적 바인딩으로 처리됨
System.out.println(name);
}
public static void main(String[] args) {
Shape b = new Circle();
b.paint();
}
}
// 실행 결과
// Shape
// Circle
super()
: 서브 클래스에서 명시적으로 슈퍼 클래스의 생성자를 선택하여 호출한다.class A {
public A() {
System.out.println("생성자A");
}
public A(int x) {
System.out.println("매개변수생성자A" + x);
}
}
class B extends A {
public B() {
System.out.println("생성자B");
}
public B(int x) {
super(x); // 첫 줄에 와야 함
System.out.println("매개변수생성자B" + x);
}
}
public class ConstructorEx {
public static void main(String[] args) {
B b;
b = new B(5);
}
}
// 실행 결과
// 매개변수생성자A5
// 매개변수생성자B5
(이전 포스팅 내용을 참고하세요)
<Java> 클래스
컴파일 타임에는 알 수 없는 메소드의 의존성을 런타임에 늦게 바인딩 하는 것. 동적 바인딩과 같은 의미이다. 다음과 같이 실행할 메소드를 런타임에 결정하고 오버라이딩된 메소드가 항상 호출되는 것을 말한다.
📌 메소드 오버로딩: 컴파일 타임 다형성 실현 vs 메소드 오버라이딩: 런타임 다형성 실현
class Shape {
protected String name;
public void paint() {
draw();
}
public void draw() {
System.out.println("Shape");
}
}
public class Circle extends Shape {
@Override
public void draw() {
System.out.println("Circle");
}
public static void main(String[] args) {
Shape b = new Circle();
b.paint(); // Shape 클래스의 paint()를 찾아가 내부의 draw()를 동적바인딩을 통해
// Circle 클래스의 draw()를 호출한다.
}
}
// 더블 디스패치, visitor 패턴에 관한 내용도 따로 구글링해서 읽어 볼 필요가 있다.
// 이 분의 글을 읽어보면 도움이 됩니다. 다이나믹 메소드 디스패치
선언되어 있으나 구현되어 있지 않은 메소드를 추상 메소드라 하고, abstract로 선언한다. 추상 메소드는 서브 클래스에서 오버라이딩하여 구현해야 한다.
추상 클래스는 2가지 종류가 있는데 이와 같은 추상 메소드를 하나라도 가진 클래스 또는 추상 메소드가 하나도 없지만 abstract로 선언된 클래스로 나뉜다.
// 추상 메소드를 포함하는 추상 클래스
abstract class Shape { // 추상 클래스 선언
public Shape() { }
public void paint() { draw() }
abstract public void draw(); // 추상 메소드
}
// 추상 메소드가 없는 추상 클래스
abstract class Component { // 추상 클래스 선언
String name;
public void load(String name) {
this.name = name;
}
}
설계와 구현 분리
- 설계: 슈퍼 클래스(추상 클래스)
개념 정의(인터페이스의 역할)
추상 메소드 선언: 서브 클래스마다 다른 구현이 필요한 경우- 구현: 각 서브 클래스에서 구체적 행위 구현(다형성 실현)
추상 메소드 구현: 서브 클래스 마다 목적에 맞게 서로 다르게 구현
계층적 상속 관계를 갖는 클래스 구조를 만들 때
// final 클래스 상속 불가
final class FinalClass { ... }
class SubClass extends FinalClass { ... } // 컴파일 오류
// final 메소드 오버라이딩 불가
public class SuperClass {
protected final int finalMethod() { ... }
}
class SubClass extends SuperClass {
protected int finalMethod() { ... } // 컴파일 오류
}
// 상수 선언
public class FinalFieldClass {
final double PI = 3.14; // 상수 정의, 이 때 초기 값을 반드시 설정해야 함.
}
자바의 최상위 클래스이다.
따로 어디서 상속받지 않더라도 Object는 모든 클래스의 최상위 클래스이므로 특정 클래스를 생성하면 그 클래스에는 자동으로 object의 기본 메소드가 포함되어있다.
주요 메소드는 다음과 같다.