상속 배효철 th1g@nate.com 1
목차 상속개념 클래스상속 부모생성자호출 메소드재정의 final 클래스와 final 메소드 protected 접근제한자 타입변환과다형성 추상클래스 2
상속개념 상속 (Inheritance) 이란? 현실세계 : 부모가자식에게물려주는행위 부모가자식을선택해서물려줌 객체지향프로그램 : 자식 ( 하위, 파생 ) 클래스가부모 ( 상위 ) 클래스의멤버를물려받는것 자식이부모를선택해물려받음 상속대상 : 부모의필드와메소드 3
상속개념 상속 (Inheritance) 이란? 4
상속개념 상속 (Inheritance) 이란? 5
상속개념 상속 (Inheritance) 개념의활용 상속의효과 부모클래스재사용해자식클래스빨리개발가능 반복된코드중복줄임 유지보수편리성제공 객체다형성구현가능 상속대상제한 부모클래스의 private 접근갖는필드와메소드제외 부모클래스가다른패키지에있을경우, default 접근갖는필드와메소드도제외 6
클래스상속 extends 키워드 자식클래스가상속할부모클래스를지정하는키워드 자바는단일상속 - 부모클래스나열불가 7
클래스상속 class Car { String color; int speed; void upspeed (int value) { speed = speed + value ; class Sedan extends Car { int seatnum ; int getseatnum() { return seatnum ; void downspeed (int value) { speed -= value ; class Truck extends Car { int capacity ; int getcapacity() { return capacity ; 8
클래스상속 public class test { public static void main(string[] args) { Sedan sedan1 = new Sedan() ; Truck truck1 = new Truck() ; sedan1.upspeed(300); truck1.upspeed(100); sedan1.seatnum = 5 ; truck1.capacity = 50 ; System.out.println(" 승용차속도는 " + sedan1.speed + "km, 좌석수는 " + sedan1.getseatnum() + " 개입니다 " ); System.out.println(" 트럭속도는 " + truck1.speed + "km, 적재량은 " + truck1.getcapacity() + " 톤입니다 " ); 9
부모생성자호출 자식객체생성하면부모객체도생성되는가? 부모없는자식없음 자식객체생성할때는부모객체부터생성후자식객체생성 부모생성자호출완료후자식생성자호출완료 10
부모생성자호출 명시적인부모생성자호출 부모객체생성할때, 부모생성자선택해호출 super( 매개값, ) 매개값과동일한타입, 개수, 순서맞는부모생성자호출 부모생성자없다면컴파일오류발생 반드시자식생성자의첫줄에위치 부모클래스에기본 ( 매개변수없는 ) 생성자가없다면필수작성 11
부모생성자호출 class Car { Car() { System.out.println("Car 클래스생성자!!"); class Sedan extends Car { Sedan() { System.out.println("Sedan 클래스생성자!!"); class Truck extends Car { Truck () { System.out.println("Truck 클래스생성자!!"); public class test { public static void main(string[] args) { Sedan sedan1 = new Sedan() ; Truck truck1 = new Truck() ; 12
부모생성자호출 class Car { Car() { System.out.println("Car 클래스생성자!!"); Car(String str) { System.out.println("Car 클래스생성자!! -->" + str); class Sedan extends Car { Sedan(String str) { System.out.println("Sedan 클래스생성자!! -->" + str); public class test { public static void main(string[] args) { Sedan sedan1 = new Sedan(" 추가!!") ; 13
메소드재정의 14
메소드재정의 메소드재정의 (@Override) 부모클래스로부터상속받은메소드를자식클래스에서재정의하는것 메소드재정의조건 부모클래스의메소드와동일한시그니처가져야 접근제한을더강하게오버라이딩불가 public 을 default 나 private 으로수정불가 반대로 default 는 public 으로수정가능 새로운예외 (Exception) throws 불가 15
메소드재정의 @Override 어노테이션 컴파일러에게부모클래스의메소드선언부와동일한지검사지시 정확한메소드재정의위해붙여주면 OK 메소드재정의효과 부모메소드는숨겨지는효과발생 재정의된자식메소드실행 16
메소드재정의 class Car { int speed = 0; void upspeed (int value) { speed = speed + value ; class Sedan extends Car { void upspeed (int value) { speed += value ; if (speed > 150) speed = 150 ; System.out.println(" 현재속도 ( 세단 ) : " + this.speed); 17
메소드재정의 class Truck extends Car { public class test { public static void main(string[] args) { Sedan sedan1 = new Sedan() ; Truck truck1 = new Truck() ; sedan1.upspeed(200); truck1.upspeed(200); 18
메소드재정의 부모메소드사용 (super) 메소드재정의는부모메소드를숨기는효과!! 자식클래스에서는재정의된메소드만호출 자식클래스에서수정되기전부모메소드호출 - super 사용 super 는부모객체참조 ( 참고 : this 는자신객체참조 ) 19
메소드재정의 class Truck extends Car { void upspeed (int value) { super.upspeed(value); public class test { public static void main(string[] args) { Sedan sedan1 = new Sedan() ; Truck truck1 = new Truck() ; sedan1.upspeed(200); truck1.upspeed(200); 20
final 클래스와 final 메소드 final 키워드의용도 final 필드 : 수정불가필드 final 클래스 : 부모로사용불가한클래스 final 메소드 : 자식이재정의할수없는메소드 상속할수없는 final 클래스 자식클래스만들지못하도록 final 클래스로생성 오버라이딩불가한 final 메소드 자식클래스가재정의못하도록부모클래스의메소드를 final 로생성 21
Protected 접근제한자 protected 접근제한자 상속과관련된접근제한자 같은패키지 : default와동일 다른패키지 : 자식클래스만접근허용 22
타입변환과다형성 다형성 ( 多形性, Polymorphism) 같은타입이지만실행결과가다양한객체대입 ( 이용 ) 가능한성질 부모타입에는모든자식객체가대입가능 자식타입은부모타입으로자동타입변환 효과 : 객체부품화가능 23
타입변환과다형성 자동타입변환 (Promotion) 프로그램실행도중에자동타입변환이일어나는것 24
타입변환과다형성 자동타입변환 (Promotion) 바로위의부모가아니더라도상속계층의상위면자동타입변환가능 변환후에는부모클래스멤버만접근가능 25
타입변환과다형성 필드의다형성 다형성을구현하는기술적방법 부모타입으로자동변환 재정의된메소드 ( 오버라이딩 ) void roll() { [ 재정의 ] void roll() { [ 재정의 ] void roll() { 26
타입변환과다형성 하나의배열로객체관리 27
타입변환과다형성 매개변수의다형성 매개변수가클래스타입일경우 해당클래스의객체대입이원칙이나자식객체대입하는것도허용 자동타입변환 매개변수의다형성 28
타입변환과다형성 강제타입변환 (Casting) (p.324~325) 부모타입을자식타입으로변환하는것 조건 자식타입을부모타입으로자동변환후, 다시자식타입으로변환할때 강제타입변환이필요한경우 자식타입이부모타입으로자동변환 부모타입에선언된필드와메소드만사용가능 자식타입에선언된필드와메소드를다시사용해야할경우 29
타입변환과다형성 객체타입확인 (instanceof) 부모타입이면모두자식타입으로강제타입변환할수있는것아님 ClassCastException 예외발생가능 먼저자식타입인지확인후강제타입실행해야함 30
타입변환과 class 다형성 Tire { void roll() { System.out.println(" 타이어가굴러갑니다.") ; void stop() { System.out.println(" 타이어가멈춥니다.") ; class KumhoTire extends Tire{ void roll() { System.out.println(" 금호타이어가굴러갑니다.") ; void Turbo() { System.out.println(" 금호타이어가엄청빨리굴러갑니다.") ; class HankukTire extends Tire{ void roll() { System.out.println(" 한국타이어가굴러갑니다.") ; 31
타입변환과다형성 public class test { public static void run(tire t) { t.roll(); if( t instanceof KumhoTire ) ((KumhoTire)t).Turbo(); t.stop(); public static void main(string[] args) { KumhoTire ktire = new KumhoTire() ; HankukTire htire = new HankukTire() ; 32 run(ktire) ; run(htire) ;
추상클래스 추상클래스개념 추상 (abstract) 실체들간에공통되는특성을추출한것 예1: 새, 곤충, 물고기 동물 ( 추상 ) 예2: 삼성, 현대, LG 회사 ( 추상 ) 추상클래스 (abstract class) 실체클래스들의공통되는필드와메소드정의한클래스 추상클래스는실체클래스의부모클래스역할 ( 단독객체 X) * 실체클래스 : 객체를만들어사용할수있는클래스 33
추상클래스 34
추상클래스 추상클래스의용도 실체클래스의공통된필드와메소드의이름통일할목적 실체클래스를설계자가여러사람일경우, 실체클래스마다필드와메소드가제각기다른이름을가질수있음 실체클래스를작성할때시간절약 실체클래스는추가적인필드와메소드만선언 실체클래스설계규격을만들고자할때 실체클래스가가져야할필드와메소드를추상클래스에미리정의 실체클래스는추상클래스를무조건상속받아작성 35
추상클래스 추상클래스선언 클래스선언에 abstract 키워드사용. 클래스이름앞에 abstract 키워드추가 New 연산자로객체생성하지못하고상속통해자식클래스만생성가능 36
abstract class Car { int speed = 0 ; String color ; void upspeed (int speed) { this.speed +=speed ; class Sedan extends Car{ class Truck extends Car{ public class test { public static void main(string[] args) { Car car1 = new Car() ; Sedan sedan1 = new Sedan() ; System.out.println(" 승용차인스턴스생성 ~~"); Truck truck1 = new Truck() ; System.out.println(" 트럭인스턴스생성 ~~"); 37
추상클래스 추상메소드와오버라이딩 ( 재정의 ) 메소드이름동일하지만, 실행내용이실체클래스마다다른메소드 예 : 동물은소리를낸다. 하지만실체동물들의소리는제각기다르다. 구현방법 추상클래스에는메소드의선언부만작성 ( 추상메소드 ) 실체클래스에서메소드의실행내용작성 ( 오버라이딩 (Overriding)) 38
추상메소드 39
추상클래스 40 abstract class Calculator { public abstract double add(double a, double b); public abstract double subtract(double a, double b); public abstract double average(double [] a); class GoodCalc extends Calculator { public double add(double a, double b) { return a+b; public double subtract(int a, double b) { return a - b; public double average(double [] a) { double sum = 0; for (int i = 0; i < a.length; i++) sum += a[i]; return sum/a.length; public static void main(string [] args) { Calculator c = new GoodCalc(); System.out.println(c.add(2.5,3.7)); System.out.println(c.subtract(2.5,3.7)); System.out.println(c.average(new double [] {2.5,3.7,4.1 ));
abstract class Car { int speed = 0 ; String color ; void upspeed (int speed) { this.speed +=speed ; abstract void work() ; Class Sedan extends Car{ void work() { System.out.println( 승용차가사람을태우고있습니다 ); class Truck extends Car{ void work() { System.out.println( 트럭이짐을싣고있습니다 ); public class test { public static void main(string[] args) { Sedan sedan1 = new Sedan() ; sedan1.work(); Truck truck1 = new Truck() ; truck1.work(); 41