Java week6
6주차
자바 상속의 특징
super 키워드
메소드 오버라이딩
다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
추상 클래스
final 키워드
Object 클래스
자바 상속의 특징
- 부모(상위) 클래스의 멤버를 자식(하위)클래스가 활용할 수 있다는 특징이 있다.
- 단, 패키지가 다르거나 private 접근 제한의 경우에는 상속받아 활용할 수 없다.
부모 클래스의 수정으로 상속받아 사용하는 모든 자식 클래스를 수정하는 효과를 가져옴
단 하나의 클래스만 상속(extends)할 수 있다.
- 메모리 관점에서는 new 연산자로 힙 영역에
부모클래스가 먼저 생성
되고,자식클래스가 생성
되어 참조 주소를 리턴한다
예제
- ElectricCar는 필드를 선언허지 않았는데 부모 클래스 Car로부터 물려받아서 사용할 수 있다.
public class ElectricCar extends Car {
public ElectricCar() {
}
public ElectricCar(String name, String color) {
super(name, color);
}
public ElectricCar(String company, String name, String color) {
super(company, name, color);
}
}
super 키워드
- (1)모든 객체는 클래스의 생성자를 호출해야 한다. 부모 객체를 생성하기 위해서 부모 생성자를 호출하는 방법이다.
super(매개값, ...)
는 매개값의 타입과 일치하는 무보 생성자를 호출한다- 앞서 알아본 기본 생성자는 선언하지 않아도 컴파일러가 자동으로 추가하듯이
super()
도 자동생성된다.- 단, 부모의 기본 생성자가 존재하지 않으면 안된다.
** 부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자가 있다면?
- 자식 생성자에서 반드시 부모 생성자 호출을 위해서 자식 생성자 첫 줄에
super(매개값, ...)
이 위치해야 한다.
- 자식 생성자에서 반드시 부모 생성자 호출을 위해서 자식 생성자 첫 줄에
예제
public class ElectricCar extends Car {
public String etc;
public ElectricCar(String company, String name, String color, String etc) {
super(company, name, color); //반드시 첫 줄에 부모 생성자를 호출
this.etc = etc;
} }
- (2) super 키워드를 붙여서 부모의 메소드를 호출 할 수 있다.
메소드 오버라이딩(overriding)
- 상속 관계에서 부모 클래스에 정의된 메소드의 사용이 자식 클래스에서 부적절할 때, 수정해서 사용하는 것을 말한다.
규칙
- 부모의 메소드와 동일한 리턴타입, 메소드 이름, 매개 변수 리스트를 가져야함
- 접근 제한자를 더 타이트하게 오버라이딩 할 수 없다(public -> private 불가)
- 새로운 예외를 throws할 수 없음
public class Calculator {
double areaCircle(double r) {
return 3.14159 * r * r;
}
}
// 가능
public class MathCalculator extends Calculator {
@Override
double areaCircle(double r) {
return Math.PI * r * r;
}
}
// 불가능X (매개변수의 변경)
public class MathCalculator extends Calculator {
@Override
double areaCircle(double r, int a) {
return super.areaCircle(r);
}
}
다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 다이나믹(런타임)에 오버라이딩 된 메서드가 실행
class Animal {
public void move() {
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Dogs can walk and run");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move(); // runs the method in Animal class
b.move(); // runs the method in Dog class
}
}
//OutPut
Animals can move
Dogs can walk and run
- 컴파일에는 참조 유형에 대해 검사가 수행됩니다. 그러나 런타임에서 JVM은 개체 유형을 계산하고 특정 개체에 속한 메서드를 실행합니다.
- 따라서 위의 예에서는 Animal class가 method move를 가지고 있기 때문에 프로그램이 제대로 컴파일될 것이다. 런타임에 해당 개체에 대한 메서드를 실행합니다.
참고: https://www.tutorialspoint.com/Dynamic-method-dispatch-or-Runtime-polymorphism-in-Java
추상 클래스
- 실체가 없는 껍데기 클래스로 부모 클래스 역할을 한다.
- 사용하는 실체 클래스가 공통적으로 가져야 할 필드와 메소드를 정의해 놓은 클래스.
- 실체 클래스들의 공통된 필드와 메소드 이름을 통일 목적
- 실체 클래스를 작성할 시간을 절약
- 결론적으로 선언된 특정 기능을 확장해 나가는데 목적이 있다고 생각함
예제
public abstract class Phone {
//필드
//생성자
//메소드
}
- 추상 메소드와 오버라이딩
public abstract class Animal {
public abstract void sound(); // 추상메소드
}
public class Dog extends Animal {
@Override
public abstract void sound() {
System.Out.pringln("멍멍");
}
}
final 키워드
- final(class)
- 상속을 통해서 활용되는 것을 불허
- final(method)
- 메소드 오버라이딩하는 것을 불허
Object 클래스
- extends로 다른 클래스를 상속하지 않으면 암시적으로 java.lang.Object 클래스를 상속하게 됨
- 즉, 최상위 부모 클래스이다.
- Object 클래스는 필드는 존재하지 않고, 메소드들로 구성되어 있다. 모든 클래스에서 해당 메소드를 사용할 수 있다.
Object의 method
- equals()
- ”==” 연산자와 동일한 결과를 리턴한다. 논리적인 동등함을 비교하는데 메모리 주소비교가 아니라, 객체가 저장하는 데이터의 동일성을 비교한다.
- hashCode()
- 객체를 식별하는 하나의 정수의 값으로 메모리 번지를 이용해서 해시코드를 만들어 리턴하므로 객체마다 다른 값을 가지고 있다.
- HashSet, HashMap, Hashtable 등이 이를 이용해서 동긍한지 비교하게 된다.
- toString()
- 기본적으로 “클래스명@16진수해시코드”의 문자정보를 리턴한다.
- 메소드를 재정의 해서 유용하게 사용하기도 한다.
- clone(): 얕은 복제
- 필드의 값만 복사해서 객체를 복제하는 것.
- primitive 타입의 경우에는 값이 복사가되고, 참조 타입의 경우에는 객체의 번지가 복사가 된다.
- deep clone
- 참조하고 있는 객체도 복제하는 것. Object의 clone() 메소드를 재정의해서 참조 객체를 복제하는 코드를 작성해야 함 (p470)