//////
Search

상속, 메서드 오버라이딩, 다형성 by 조문주

태그
2022/09/28 05:05
사람
최종 편집 일시
2022/09/28 05:08

상속

상속이란?

기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것
두 클래스를 부모와 자식으로 관계를 맺어주는 것
자식은 부모의 모든 멤버를 상속받음(생성자, 초기화 블럭 제외)
자식의 멤버 개수는 부모와 같거나 많다
class Child extends Parent { // 상속 }
Java
복사
상속해 주는 클래스 = 부모 클래스
상속 받는 클래스 = 자식 클래스

상속 문법

1.
Car - SportsCar 예제
Car.java // super class public class Car { int speed; // 속도 public void setSpeed(int speed) { // 속도 변경 메서드 this.speed = speed; }
Java
복사
SportCar.java // sub classs public class SportsCar extends Car { // Car 상속 boolean turbo; // 추가된 필드 public void setTurbo(boolean flag) { // 터보 모드 설정 메서드 => 추가된 메서드 turbo = flag;// 추가된 메소드 } }
Java
복사
public class SportsCarTest { public static void main(String[] args) { SportsCar obj = new SportsCar(); // 자식 클래스의 객체 생성 obj.speed = 10; // 부모 클래스의 필드와 메소드 사용 obj.setSpeed(60); // 부모 클래스의 필드와 메소드 사용 obj.setTurbo(true); // 자체 메소드 사용
Java
복사
1.
Car - ElectricCar 예제
public class Car { int speed; public void setSpeed(int speed) { this.speed = speed; } }
Java
복사
public class ElectricCar extends Car { int battery; public void charge(int amount) { //충전 메서드 battery += amount; } }
Java
복사
public class ElectricCarTest { public static void main(String[] args) { ElectricCar ec = new ElectricCar(); ec.speed = 10; //부모 멤버 사용 ec.setSpeed(60); //부모 멤버 사용 ec.charge(10); //추가된 메서드 사용 } }
Java
복사
2.
Car - ElectricCar 예제
public class Car { int speed; public void setSpeed(int speed) { this.speed = speed; } }
Java
복사
public class ElectricCar extends Car { int battery; public void charge(int amount) { //충전 메서드 battery += amount; } }
Java
복사
public class ElectricCarTest { public static void main(String[] args) { ElectricCar ec = new ElectricCar(); ec.speed = 10; //부모 멤버 사용 ec.setSpeed(60); //부모 멤버 사용 ec.charge(10); //추가된 메서드 사용 } }
Java
복사
공통 부분은 부모에서 관리하고 개별 부분은 자식에서 관리
부모의 변경은 자식에 영향을 미치지만 자식의 변경은 부모에 아무런 영향을 미치지 않음

예제

1) 다음 TV 클래스가 있다. class TV{ private int size; public TV(int size) { this.size = size; } protected int getSize() { return size; } } [1번] 다음 main() 메소드와 실행 결과를 참고하여 TV를 상속받은 ColorTV 클래스를 작성하라. public static void main(String[] args) { ColorTV myTV = new ColorTV(32, 1024); myTV.printProperty(); } 32인치 1024컬러
Plain Text
복사
lass TV { private int size; 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 TVTest { private int color; public static void main(String[] args) { ColorTV myTV = new ColorTV(32, 1024); myTV.printProperty(); } }
Java
복사
[2번] 다음 main() 메소드와 실행 결과를 참고하여 ColorTV를 상속받는 IPTV 클래스를 작성하라. public static void main(String[] args) { IPTV iptv = new IPTV("192.1.1.2", 32, 2048); //"192.1.1.2" 주소에 32인치, 2048컬러 iptv.printProperty(); } 나의 IPTV는 192.1.1.2 주소의 32인치 2048컬러
Plain Text
복사
class IPTV extends ColorTV { String IP; IPTV(String IP, int size, int color) { super(size, color); this.IP = IP; } public void printProperty() { System.out.print("나의 IPTV는 "+IP+" 주소의 "); super.printProperty(); } }
Java
복사

상속을 사용하는 이유

중복되는 코드를 줄이기 위함
이미 존재하는 클래스의 필드와 메소드의 재사용

상속과 생성자

예제
class A { public A() { System.out.println("A 생성자 호출"); } } class B extends A { public B() { System.out.println("B 생성자 호출"); } } class C extends B { public C() { System.out.println("C 생성자 호출"); } } public class ConstructorEx { public static void main(String[] args) { //A a = new A(); //B b = new B(); C c = new C(); } }
Java
복사
왜 자식 객체 생성시 부모 생성자까지 호출될까?
: 자식 클래스 객체 안에는 부모 클래스에서 상속된 부분이 들어 있다. 따라서 자식 클래스 안의 부모 클래스 부분을 초기화하기 위해 부모 클래스의 생성자도 호출되는 것이다.
생성자 호출 순서: (부모 클래스의 생성자) → (자식 클래스의 생성자) 순

생성자 호출: super()

명시적인 생성자 호출: super()를 호출하면 부모 클래스 생성자가 호출된다.
class A { public A() { System.out.println("A의 생성자"); } } class B extends A { public B() { super(); System.out.println("B의 생성자"); } } public class ConstructorEx { public static void main(String[] args) { B b = new B(); //super()를 호출함으로써 "A의 생성자"도 출력된다. } }
Java
복사
묵시적인 생성자 호출: 컴파일러가 부모 클래스의 기본 생성자를 자동으로 호출한다.
컴파일러가 자동으로 호출해주는 것:
class A { //public A() { //class A의 기본 생성자 //} } class B extends A { //public B() { //class B의 기본 생성자 //super(); //부모 생성자 //} } public class ConstructorEx { public static void main(String[] args) { B b = new B(); } }
Java
복사
부모 클래스 생성자 선택
부모 클래스에 생성자가 여러개인 경우 ⇒ 인수 형태에 따라 적절한 생성자가 선택된다.
ex)
class A { int x, y; public A() { System.out.println("A의 기본 생성자"); } public A(int x, int y) { this.x = x; this.y = y; System.out.println("A의 x, y를 매개변수로 받는 생성자"); } } class B extends A { int z; public B(int x, int y, int z) { super(x, y); //"A의 x, y를 매개변수로 받는 생성자"가 선택된다. this.z = z; } }
Java
복사
오류가 발생하는 경우
class A { public A() { //So, 없으면 컴파일 오류 발생 System.out.println("A의 생성자"); } public A(int a, int b) { System.out.println(a + b); } } class B extends A { public B() { super(); //매개변수가 없으므로 부모 클래스의 기본 생성자가 선택된다. System.out.println("B의 생성자"); } } public class ConstructorEx { public static void main(String[] args) { B b = new B(); } }
Java
복사
protected 키워드
부모 클래스를 상속 받은 자식 클래스가 다른 패키지에 있더라도 접근할 수 있도록 선언하는 키워드

메소드 오버라이딩

메소드 오버라이딩이란?

조상 클래스로부터 상속받은 메소드의 내용을 변경하는 것
오버라이딩 된 메소드를 인스턴스 외부에서 호출하는 방법은 없다. 그러나 인스턴스 내부에서는 키워드 super를 이용해 호출 가능
메소드 오버로딩과의 차이
메소드 오버로딩 : 새로운 메소드를 정의하는 것 (new)
메소드 오버라이딩 : 상속받은 메소드의 내용을 변경하는 것 (change, modify)
// 메소드 오버라이딩 예제 class Cake { //부모클래스 public void yummy() { System.out.println("Yummy Cake"); } } @override class CheeseCake extends Cake { //cheeseCake 클래스 : 자식 클래스 public void yummy() { // chesseCake의 yummy 메소드가 Cake의 yummy 메소드를 오버라이딩 System.out.println("Yummy Cheese Cake"); } } public static void main(String[] args) { Cake c1 = new CheeseCake(); CheeseCake c2 = new CheeseCake(); c1.yummy(); c2.yummy(); }
Java
복사

요약 : 기억해야 할 세 가지!

1.
부모 = 자식
2.
오버라이딩은 자식 것으로
3.
기본적으로는 자식 = 부모 허용하지 않음

오버라이딩 vs 오버로딩

오버라이딩: 자식클래스가 부모클래스의 메소드를 자신의 필요에 맞추어 재정의하는 것으로 함수 바디부분만 달라진다.
오버로딩: 같은 이름의 메서드 여러개를 정의하고 매기변수의 유형과 개수를 다르게 하는 것이다.

예제

Exployee를 상속받는 Manager와 Programmer의 월급을 출력하기
Plain Text
복사
class Employee{ private int salary; public Employee() { salary = 3000000; //기본급 } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } } class Manager extends Employee{ public Manager() { super.setSalary(super.getSalary() + 2000000); } @Override public int getSalary() { return super.getSalary(); } } class Programer extends Employee{ public Programer() { super.setSalary(super.getSalary() + 3000000); } @Override public int getSalary() { return super.getSalary(); } } public class Test { public static void main(String[] args) { Manager manager = new Manager(); System.out.println("관리자의 월급: "+manager.getSalary()); Programer programer = new Programer(); System.out.println("프로그래머의 월급: "+programer.getSalary()); } };
Java
복사

다형성

다형성이란?

객체들의 타입이 다르면 똑같은 메시지가 전달되더라도 서로 다른 동작을 하는 것.
하위 객체를 상위 클래스 변수에 대입하는 것 *upcasting
부모 클래스 변수로 자식 클래스 객체를 참조
다형성을 이용하면 훨씬 넓은 범위의 객체를 받을 수 있다.

예제

class MobilePhone { protected String number; public MobilePhone(String num) { number = num; } public void answer() { System.out.println("Hi~ from " + number); } } class SmartPhone extends MobilePhone { private String androidVer; public SmartPhone(String num, String ver) { super(num); androidVer = ver; } public void playApp() { System.out.println("App is running in " + androidVer); } } public static void main(String[] args) { SmartPhone ph1 = new SmartPhone("010-555-777", "Nougat"); MobilePhone ph2 = new SmartPhone("010-999-333", "Nougat"); ph1.answer(); ph1.playApp(); System.out.println(); ph2.answer(); // ph2.playApp(); }
Java
복사