///////
Search

상속, 오버라이딩, 오버로딩, 다형성

날짜
2022/09/26
태그
자바

상속

상속에 대한 이해

상속이란?

기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
상속해주는 클래스를 부모 클래스 라 하고 상속 받는 클래스를 자손 클래스 라 한다.

상속을 구현하는 법

새로 작성하고자 하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 키름을 키워드 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
복사