학습한 내용을 정리한 포스팅입니다. 참고 문헌 내용이 직역 되어 어색한 문장이 있을 수 있습니다. 틀린 내용이 있다면 지적해주시면 감사하겠습니다. 🙇🏻♀️
기존의 클래스를 재사용해 새로운 클래스를 작성하는 것을 상속이라고 한다. 상속을 사용하면 공통된 코드들을 관리할 수 있기 때문에 코드의 추가, 변경에 용이하다.
이러한 특징은 코드의 재사용성을 높이고 코드의 중복을 제거해 프로그램의 생산성과 유지보수에 크게 기여한다
자바에서는 extends 키워드로 상속을 할 수 있다.
예시
class Parent {
int age;
}
class Child extends Parent {
void speak() {
System.out.println("왱알왱알");
}
}
위의 예시에서 상속해 주는 클래스인 Parent는 부모 클래스, 상속을 받는 Child 클래스는 자손 클래스라고 한다. Parent 클래스가 갖고 있는 age라는 멤버변수는 자손 클래스가 상속 받으면서 자동으로 age라는 멤버변수를 가지게 된다. 하지만 반대로 Child 클래스가 speak()라는 메서드를 갖고 있다고해서 부모클래스인 Parent에게 영향이 가지는 않는다.
이런 특징을 갖고 있기에 부모 클래스만 변경해도 모든 자식 클래스에 영향을 줄 수 있어 상속관계를 적절히 맺어 활용한다면 각 클래스의 코드를 줄일 수 있고 관리가 용이해진다.
자식 클래스에서 부모 클래스로부터 상속받은 멤버를 참조할 때 사용되는 참조변수이다. 멤버 변수와 지역 변수의 이름이 같을 때 this
키워드를 사용하듯이 상속받은 멤버와 자신의 멤버의 이름이 같을 땐 super
를 붙여서 구별할 수 있다.
조상의 멤버와 자신의 멤버를 구별하는데 사용된다는 점을 제외하고는 super와 this는 근본적으로 같다. 모든 인스턴스 메서드에는 자신이 속한 인스턴스의 주소가 지역변수로 저장되는데 이것이 참조변수인 this와 super의 값이 된다. - 자바의 정석
조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 한다.
오버라이딩이 성립하기 위해서는 몇 가지 조건이 있는데
자손 클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 반환타입이 같아야 한다.
또한 접근제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없고 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at run time, rather than compile time.
다이나믹 메소드 디스패치는 컴파일 시가 아닌 런타임시에 오버라이딩 된 메소드들을 불러오는 메커니즘이다.
그래서 만약 슈퍼클래스가 서브클래스에 의해 오버라이딩 된 메소드를 가지고 있으면 슈퍼클래스 레퍼런스 변수에 따라 각각 다른 객체들이 불러질 때 메소드의 다른 버전들이 실행된다. 아래의 예시를 보면 쉽게 이해할 수 있다.
예시
class A
{
void m1()
{
System.out.println("Inside A's m1 method");
}
}
class B extends A
{
// overriding m1()
void m1()
{
System.out.println("Inside B's m1 method");
}
}
class C extends A
{
// overriding m1()
void m1()
{
System.out.println("Inside C's m1 method");
}
}
// Driver class
class Dispatch
{
public static void main(String args[])
{
// object of type A
A a = new A();
// object of type B
B b = new B();
// object of type C
C c = new C();
// obtain a reference of type A
A ref;
// ref refers to an A object
ref = a;
// calling A's version of m1()
ref.m1();
// now ref refers to a B object
ref = b;
// calling B's version of m1()
ref.m1();
// now ref refers to a C object
ref = c;
// calling C's version of m1()
ref.m1();
}
}
추상클래스는 미완성 설계도라고 비유된다. 여기서 미완성 설계도라는 말은 클래스가 가지고 있는 메서드가 미완성이라는 말이다. 다시 풀어 말하면 미완성 메서드를 가지고 있는 클래스는 추상 클래스이다.
추상 클래스로는 인스턴스를 생성할 수 없기 때문에 상속을 통해서 자식 클래스에 의해 완성 될 수 있다.
추상 클래스는 abstract
키워드를 붙이면 된다. 추상 클래스는 미완성 메서드를 가지고 있다는 것을 제외하면 일반 클래스와 같다.(생성자를 갖고 있고 멤버변수, 메서드도 가질 수 있다)
abstract class 클래스명 {
//중략
}
여러 클래스에 공통적으로 사용될 수 있는 부분을 뽑아서 추상 클래스로 만들고 상속해서 사용할 수도 있다.
final은 우리가 흔히 알고 있는 ‘마지막의’ 라는 의미 외에도 ‘변경 될 수 없는’ 의미를 가지고 있다. 자바에서의 final은 거의 모든 곳에 사용할 수 있는데 변수에 사용하게 되면 값을 변경 할 수 없는 상수가 되고 메서드에 사용하면 오버라이딩을 할 수 없게 된다. 클래스에 사용하면 자식 클래스를 가질 수 없다.
final 키워드가 필드에서 사용될 때
final 키워드가 클래스에서 사용될 때
final 키워드가 메서드에서 사용될 때
Class
Object
is the root of the class hierarchy. Every class hasObject
as a superclass. All objects, including arrays, implement the methods of this class.
Object 클래스는 모든 클래스의 조상 클래스이다. 다른 클래스로부터 상속 받지 않는 클래스들은 자동적으로 Object 클래스로부터 상속받는다.
예시
class Car {
//중략
}
위와 같이 Car라는 다른 클래스를 상속 받지 않은 클래스가 있다고 했을 때, 위의 코드를 컴파일 하면 컴파일러는 아래와 같이 objcet 클래스를 상속 받도록 한다.
class TV extends Object {
//중략
}
모든 클래스들은 Object클래스의 멤버들을 상속 받기 때문에 Object 클래스에 정의된 멤버들을 사용할 수 있다.
Object 클래스에 정의 되어 있는 11가지 메서드는 아래와 같다.