상속
상속에 대한 이해
상속이란?
기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
•
상속해주는 클래스를 부모 클래스 라 하고 상속 받는 클래스를 자손 클래스 라 한다.
상속을 구현하는 법
새로 작성하고자 하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 키름을 키워드 extends 와 함께 써 주기만 하면 된다.
class Parent {
int age;
}
class Child extends Parent{ }
Plain Text
복사
상속 특징
•
자손 클래스는 조상 클래스의 모든 멤버를 상속받는다. (단, 생성자의 초기화 블럭은 상속되지 않는다.)
•
자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
상속을 사용 하는 이유
•
상속을 사용하면 중복되는 코드를 줄일 수 있다.
•
상속받아서 이미 존재하는 클래스의 필드와 메서드를 재사용할 수 있다.
•
공통되는 부분을 부모로 빼서 상속을 사용하면 위와 같은 이점을 가져올 수 있다.
상속에서의 생성자
•
생성자는 상속이 되지 않는다.
•
자식 클래스로 인스턴스를 생성할 때 부모 클래스의 기본 생성자를 자동으로 호출한다.
class GrandParent {
public GrandParent() {
System.out.println("GrandParent 생성자 호출");
}
}
class Parent extends GrandParent {
public Parent() {
//super(); 생략
System.out.println("Parent 생성자 호출");
}
}
class Child extends Parent {
public Child() {
//super(); 생략
System.out.println("Child 생성자 호출");
}
}
public class extendsConstructor {
public static void main(String[] args) {
Child child = new Child();
}
}
Plain Text
복사
GrandParent 생성자 호출
Parent 생성자 호출
Child 생성자 호출
Plain Text
복사
why?
•
자식 클래스 객체 안에는 부모 클래스에서 상속된 부분이 들어 있다.
부모로부터 물려받은 변수는 자식 클래스에서 초기화하는게 아니라 부모 클래스의 생성자를 통해 초기화 하는게 바람직하다.
super()
참조변수 super
•
상속받은 멤버와 자신의 멤버와 이름이 같을 때는 super 를 붙여서 구별
class Parent1 {
int x = 10;
}
class Child1 extends Parent1{
int x = 20;
void method() {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("super.x = " + super.x);
}
}
public class superVar {
public static void main(String[] args) {
Child1 child1 = new Child1();
child1.method();
}
}
Plain Text
복사
x = 20
this.x = 20
super.x = 10
Plain Text
복사
조상의 생성자 - super()
•
super() 는 부모의 생성자를 호출하는데 사용
•
클래스 자신에 선언된 변수는 자신의 생성자가 초기화를 책임지도록 작성하는 것이 좋다
class Tv{
private int size;
public Tv(int size) {
this.size = size;
}
public int getSize() {
return size;
}
}
class ColorTv extends Tv {
private int resolution;
public ColorTv(int size, int resolution) {
super(size);
this.resolution = resolution;
}
public int getResolution() {
return resolution;
}
}
public class Ex1 {
public static void main(String[] args) {
ColorTv myTv = new ColorTv(32, 1024);
System.out.println(myTv.getSize() + "인치 " + myTv.getResolution() + "컬러");
}
}
Plain Text
복사
32인치 1024컬러
Plain Text
복사
상속 예제
1번
class Tv{
private int size;
public Tv() {
}
public Tv(int size) {
this.size = size;
}
protected int getSize() {
return size;
}
}
class ColorTv extends Tv {
private int color;
public ColorTv(int size, int color) {
super(size);
this.color = color;
}
public void printProperty() {
System.out.println(super.getSize() + "인치 " + color + "컬러");
}
}
public class Ex1 {
public static void main(String[] args) {
ColorTv myTv = new ColorTv(32, 1024);
myTv.printProperty();
}
}
Plain Text
복사
2번
class Tv{
private int size;
public Tv(int size) {
this.size = size;
}
public int getSize() {
return size;
}
}
class ColorTv extends Tv {
private int resolution;
public ColorTv(int size, int resolution) {
super(size);
this.resolution = resolution;
}
public int getResolution() {
return resolution;
}
}
class IpTv extends ColorTv {
private String ip;
public IpTv(String ip, int size, int resolution) {
super(size, resolution);
this.ip = ip;
}
void printProperty() {
System.out.println("나의 IpTv는 " + ip + " 주소의 " +
super.getSize() + "인치 " + super.getResolution() + "컬러");
}
}
public class Ex1 {
public static void main(String[] args) {
IpTv ipTv = new IpTv("192.1.1.2", 32, 2048);
ipTv.printProperty();
}
}
Plain Text
복사
overriding
•
상속받은 메서드의 내용을 변경 하는 것
오버라이딩 조건
1.
접근 제어자는 부모 클래스의 메서드보다 좁은 범위로 변경 할 수 없다.
2.
부모 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
3.
선언부가 부모 클래스의 메서드와 일치해야 한다.
class Parent2{
void parentMethod() throws IOException, SQLException {
System.out.println("Parent2");
}
}
class Child2 extends Parent2 {
@Override
// 부모보다 예외 더 많이 선언하거나 범위가 더 좁은 접근 제어자 private 을 쓰면 ERROR
void parentMethod() throws IOException {
System.out.println("Child2");
}
}
public class overridingEx {
public static void main(String[] args) throws IOException {
Child2 child2 = new Child2();
child2.parentMethod();
}
}
Plain Text
복사
overloading
•
기존에 없는 새로운 메서드를 정의하는 것
•
println이 오버로딩의 대표적 예시
오버로딩 조건
1.
메서드 이름이 같아야 한다.
2.
매개변수의 개수 or 타입이 달라야 한다.
3.
return 타입은 영향이 없다.
class Parent{
void parentMethod() {
System.out.println("Hello");
}
}
class Child extends Parent {
void parentMethod(String name) {
System.out.println("Hello " + name);
}
}
public class overloadingEx {
public static void main(String[] args) {
Child child = new Child();
child.parentMethod();
child.parentMethod("JaeHyun");
}
}
Plain Text
복사
Hello
Hello JaeHyun
Plain Text
복사
다형성
다형성의 이해
다형성 이란?
•
부모 타입 참조 변수로 자손 타입 객체를 다루는 것
Parent p = new Child(); // Ok
Child c = new Parent(); // Error
Plain Text
복사
class Phone {
String phoneNum;
void sendMessage() {
System.out.println("메시지 전송");
}
}
class SmartPhone extends Phone {
void sendKakao() {
System.out.println("카카오톡 전송");
}
}
public class polyEx {
public static void main(String[] args) {
Phone phone = new SmartPhone();
Phone.sendMessage();
}
}
Plain Text
복사
자식으로 부모 인스턴스 호출 가능?
•
메모리에 올라가는 것
◦
String phoneNum
◦
sendMessage()
•
자식 참조변수로 호출할 수 있는 것
◦
String phoneNum
◦
sendMessage()
◦
sendKakao()
실제 메모리에 올라가는 것 보다 자식 참조 변수로 호출할 수 있는 것이 많기 때문에 Error
instanceof 연산자
•
참조변수의 타입과 실제 가리키는 인스턴스의 타입이 항상 같지 않으므로 형변환이 가능한지 불가능한지 확인할 수 있는 연산자
•
연산의 결과로 true or false
•
연산결과가 true 라면 참조변수가 검사한 타입으로 형변환이 가능하다는 것
class Car {
void run() {
System.out.println("run");
}
}
class FireEngine extends Car {
void water() {
System.out.println("water");
}
}
class Ambulance extends Car {
void medic() {
System.out.println("medic");
}
}
public class Instanceof {
public static void main(String[] args) {
Car car = new Ambulance();
if (car instanceof Ambulance) {
Ambulance am = (Ambulance) car;
am.medic();
}
}
}
Plain Text
복사
다형성 활용
여러 종류의 객체를 배열로 다루기
class Car {
void run() {
System.out.println("run");
}
}
class FireEngine extends Car {
void water() {
System.out.println("water");
}
}
class Ambulance extends Car {
void medic() {
System.out.println("medic");
}
}
public class Instanceof {
public static void main(String[] args) {
Car[] cars = new Car[2];
cars[0] = new FireEngine();
cars[1] = new Ambulance();
for (Car car : cars) {
if (car instanceof Ambulance) {
Ambulance am = (Ambulance) car;
am.medic();
}
else if (car instanceof FireEngine) {
FireEngine fe = (FireEngine) car;
fe.water();
}
}
}
}
Plain Text
복사