상속
상속이란?
•
기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것
•
두 클래스를 부모와 자식으로 관계를 맺어주는 것
•
자식은 부모의 모든 멤버를 상속받음(생성자, 초기화 블럭 제외)
•
자식의 멤버 개수는 부모와 같거나 많다
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
복사