명품 JAVA Programming 1 제 5 장상속과다형성
상속 (inheritance) 2 상속 상위클래스의특성 ( 필드, 메소드 ) 을하위클래스에물려주는것 슈퍼클래스 (superclass) 특성을물려주는상위클래스 서브클래스 (subclass) 특성을물려받는하위클래스 슈퍼클래스에자신만의특성 ( 필드, 메소드 ) 추가 슈퍼클래스의특성 ( 메소드 ) 을수정 구체적으로오버라이딩이라고부름 슈퍼클래스에서하위클래스로갈수록구체적 예 ) 폰 -> 모바일폰 -> 뮤직폰 상속을통해간결한서브클래스작성 동일한특성을재정의할필요가없어서브클래스가간결해짐
상속관계예 3 class Phone 전화걸기전화받기 상속 class MobilePhone 무선기지국연결배터리충전하기상속 구체화 class MusicPhone 음악다운받기음악재생하기
상속의필요성 상속이없는경우중복된멤버를가진 4 개의클래스 상속을이용한경우중복이제거되고간결해진클래스구조 4
클래스상속과객체 5 상속선언 public class Person {... public class Student extends Person { // Person 을상속받는클래스 Student 선언... public class StudentWorker extends Student { // Student 를상속받는 StudentWorker 선언... 자바상속의특징 클래스다중상속지원하지않음 다수개의클래스를상속받지못함 상속횟수무제한 상속의최상위조상클래스는 java.lang.object 클래스 모든클래스는자동으로 java.lang.object 를상속받음
6 예제 5-1 : 클래스상속만들어보기 (x,y) 의한점을표현하는 Point 클래스와이를상속받아컬러점을표현하는 ColorPoint 클래스를만들어보자. class Point { public class ColorPoint extends Point { int x, y; // 한점을구성하는 x, y 좌표 // Point를상속받은 ColorPoint 선언 void set(int x, int y) { String color; // 점의색 this.x = x; this.y = y; void setcolor(string color) { this.color = color; void showpoint() { // 점의좌표출력 System.out.println("(" + x + "," + y + ")"); void showcolorpoint() { // 컬러점의좌표출력 System.out.print(color); showpoint(); // Point 클래스의 showpoint() 호출 public static void main(string i [] args) ){ ColorPoint cp = new ColorPoint(); cp.set(3,4); // Point 클래스의 set() 메소드호출 cp.setcolor("red"); // 색지정 cp.showcolorpoint(); // 컬러점의좌표출력 red(3,4)
자바의클래스계층구조 7 자바에서는모든클래스는반드시 java.lang.object 클래스를자동으로상속받는다.
서브클래스의객체와멤버사용 8 서브클래스의객체와멤버접근 서브클래스의객체에는슈퍼클래스멤버포함 슈퍼클래스의 private 멤버는상속되지만서브클래스에서직접접근불가 슈퍼클래스의 private 멤버는슈퍼클래스의 public/protected 메소드를통해접근
9 슈퍼클래스와서브클래스의객체관계
서브클래스의객체멤버접근 10 10 20
상속과접근지정자 11 자바의접근지정자 4 가지 public, protected, 디폴트, private 상속관계에서주의할접근지정자는 private 와 protected 슈퍼클래스의 private 멤버 슈퍼클래스의 private 멤버는다른모든클래스에접근불허 슈퍼클래스의 protected 멤버 같은패키지내의모든클래스접근허용 동일패키지여부와상관없이서클래에서슈퍼클래의 동일패키지여부와상관없이서브클래스에서슈퍼클래스의 protected 멤버접근가능
12 슈퍼클래스멤버의접근지정자
13 슈퍼클래스와서브클래스가같은패키지에있는경우
14 슈퍼클래스와서브클래스가서로다른패키지에있는경우
예제 5-2: 상속관계에있는클래스간멤버접근 15 클래스 Person을아래와같은멤버필드를갖도록선언하고클래스 Student는클래스 Person 을상속받아각멤버필드에값을저장하시오. 이예제에서 Person 클래스의 private 필드인 weight는 Student 클래스에서는접근이불가능하여슈퍼클래스인 Person의 get, set 메소드를통해서만조작이가능하다. int age; public String name; protected int height; private int weight; class Person { public class Student extends Person { int age; void set() { public String name; age = 30; protected int height; name = " 홍길동 "; private int weight; height = 175; public void setweight(int weight) { setweight(99); this.weight = weight; public int getweight() { return weight; public static void main(string[] args) { Student s = new Student(); s.set();
서브클래스 / 슈퍼클래스의생성자호출과실행 16 new 에의해서브클래스의객체가생성될때 슈퍼클래스생성자와서브클래스생성자모두실행됨호출순서 서브클래스의생성자가먼저호출, 서브클래스의생성자는실행전슈퍼클래스생성자호출실행순서 슈퍼클래스의생성자가먼저실행된후서브클래스의생성자실행
17 슈퍼클래스와서브클래스의생성자간의호출및실행관계 예상실행결과는? 생성자 A 생성자 B 생성자 C
서브클래스와슈퍼클래스의생성자짝맞추기 18 슈퍼클래스와서브클래스 각각여러개의생성자작성가능 슈퍼클래스와서브클래스의생성자사이의짝맞추기 서브클래스와슈퍼클래스의생성자조합 4 가지 서브클래스에서슈퍼클래스의생성자를선택하지않는경우 컴파일러가자동으로슈퍼클래스의기본생성자선택 서브클래스개발자가슈퍼클래스의생성자를명시적으로선택하는경우 super() 키워드를이용하여선택
슈퍼클래스의기본생성자자동호출 서브클래스의기본생성자경우 19 서브클래스의생성자가슈퍼클래스의생성자를선택하지않은경우 서브클래스의생성자가기본생성자인경우, 컴파일러는자동으로슈퍼클래스의기본생성자와짝을맺음 생성자 A 생성자 B
슈퍼클래스에기본생성자가없어오류난경우 20 컴파일러가 public B() 에대한짝을찾을수없음 컴파일러에의해 Implicit super constructor A() is undefined. Must explicitly invoke another constructor 오류발생
슈퍼클래스의기본생성자자동호출 서브클래스의매개변수를가진생성자경우 21 서브클래스의생성자가슈퍼클래스의생성자를선택하지않은경우 생성자 A 매개변수생성자 B
super() 를이용하여슈퍼클래스생성자선택 22 super() 서브클래스에서명시적으로슈퍼클래스의생성자를선택호출할때사용 사용방식 super(parameter); 인자를이용하여슈퍼클래스의적당한생성자호출 반드시서브클래스생성자코드의제일첫라인에와야함
super() 를이용한사례 23 super(); 라고하면 A() 호출 매개변수생성자 A5 매개변수생성자 B5
객체의타입변환 24 업캐스팅 (upcasting) 프로그램에서이루어지는자동타입변환 서브클래스의레퍼런스값을슈퍼클래스레퍼런스에대입 슈퍼클래스레퍼런스가서브클래스객체를가리키게되는현상 객체내에있는모든멤버를접근할수없고슈퍼클래스의멤버만접근가능 class Person { class Student extends Person {... Student s = new Student(); Person p = s; // 업캐스팅, 자동타입변환
업캐스팅사례 class Person { String name; String id; public Person(String name) { this.name = name; class Student extends Person { String grade; String department; public Student(String name) { super(name); public class UpcastingEx { public static void main(string[] args) { Person p; Student s = new Student(" 이재문 "); p = s; // 업캐스팅발생 System.out.println(p.name); // 오류없음 25 pgrade= p.grade "A"; A; // 컴파일오류 p.department = "Com"; // 컴파일오류 이재문
객체의타입변환 26 다운캐스팅 (downcasting) 슈퍼클래스레퍼런스를서브클래스레퍼런스에대입 업캐스팅된것을다시원래대로되돌리는것 명시적으로타입지정 class Person { class Student extends Person {... Student s = (Student)p; // 다운캐스팅, 강제타입변환
27 다운캐스팅사례
instanceof 연산자와객체의타입구별 28 업캐스팅된레퍼런스로는객체의진짜타입을구분하기어려움 슈퍼클래스는여러서브클래스에상속되기때문 슈퍼클래스레퍼런스로서브클래스객체를가리킬수있음 instanceof 연산자 instanceof 연산자 레퍼런스가가리키는객체의진짜타입식별 사용법 객체레퍼런스 instanceof 클래스타입 연산의결과 : true/false 의불린값
29 업캐스팅된객체의실제타입은무엇?
30 instanceof 사용예
예제 5-3 : instanceof 를이용한객체구별 31 instanceof 를이용하여객체의타입을구별하는예를만들어보자. class Person { class Student extends Person { class Researcher extends Person { class Professor extends Researcher { public class InstanceofExample { public static void main(string[] args) { Person jee= new Student(); Person kim = new Professor(); Person lee = new Researcher(); if (jee instanceof Student) // jee 는 Student 타입이므로 true System.out.println("jee는 Student 타입 "); if ( jee instanceof Researcher) // jee는 Researcher 타입이아니므로 false System.out.println("jee는 Researcher 타입 "); if (kim instanceof Student) // kim은 Student 타입이아니므로 false System.out.println( println("kim 은 Student 타입 "); if (kim instanceof Professor) // kim은 Professor 타입이므로 true System.out.println("kim은 Professor 타입 "); if (kim instanceof Researcher) // kim은 Researcher 타입이기도하므로 true System.out.println("kim은 Researcher 타입 "); if (kim instanceof Person) // kim은 Person 타입이기도하므로 true System.out.println("kim은 Person 타입 "); if (lee instanceof Professor) // lee는 Professor 타입이아니므로 false jee는 Student 타입 System.out.println("lee는 Professor 타입 "); kim 은 Professor 타입 if ("java" (j instanceof String) // "java" 는 String 타입의인스턴스이므로 true kim은 Researcher 타입 System.out.println("\"java\" 는 String 타입 "); kim은 Person 타입 "java" 는 String 타입
메소드오버라이딩 32 메소드오버라이딩 (Method Overriding) 슈퍼클래스의메소드를서브클래스에서재정의 슈퍼클래스의메소드이름, 메소드인자타입및개수, 리턴타입등모든 것동일하게작성 이중하나라도다르면메소드오버라이딩실패 메소드무시하기 로번역되기도함 동적바인딩발생 서브클래스에오버라이딩된메소드가무조건실행되도록동적바인딩됨 동적바인딩발생 메소드 2() 오버라이딩
33 메소드오버라이딩사례
34 서브클래스객체와오버라이딩된메소드호출
예제 5-4 : 메소드오버라이딩만들기 35 class DObject { public DObject next; public DObject() { next = null; public void draw() { System.out.println("DObject draw"); class Line extends DObject { public void draw() { // 메소드오버라이딩 System.out.println("Line"); class Rect extends DObject { public void draw() { // 메소드오버라이딩 System.out.println("Rect"); DObject draw class Circle extends DObject { Line public void draw() { // 메소드오버라이딩 Line System.out.println("Circle"); Line Rect Circle public class MethodOverringEx { public static void main(string[] args) { DObject obj = new DObject(); Line line = new Line(); DObject p = new Line(); DObject r = line; obj.draw(); // DObject.draw() 메소드실행. "DObject draw" 출력 line.draw(); // Line.draw() 메소드실행. "Line" 출력 p.draw(); // 오버라이딩된메소드 Line.draw() 실행, "Line" 출력 r.draw(); // 오버라이딩된메소드 Line.draw() 실행, "Line" 출력 DObject rect = new Rect(); DObject circle = new Circle(); rect.draw(); // 오버라이딩된메소드 Rect.draw() 실행, "Rect" 출력 circle.draw(); // 오버라이딩된메소드 Circle.draw() 실행, "Circle" 출력
예제실행과정 36
37 메소드오버라이딩조건 1. 반드시슈퍼클래스메소드와동일한이름, 동일한호출인자, 반환타입을가져야한다. 2. 오버라이딩된메소드의접근지정자는슈퍼클래스의메소드의접근지정자보다좁아질수없다. public > protected > private 순으로지정범위가좁아진다. 3. 반환타입만다르면오류 4. static, private, 또는 final 메소드는오버라이딩될수없다. class Person { String name; String phone; static int ID; public void setname(string s) { name = s; public String getphone() { return phone; public static int getid() { return ID; class Professor extends Person { protected void setname(string s) { // 2번조건위배 public String getphone() { // 1 번조건성공 return phone; public void getphone(){ // 3번조건위배 public int getid() { // 4번조건위배
public static void main(string [] args) { DObject start, n, obj; 오버라이딩활용 // 링크드리스트로도형생성하여연결하기 start = new Line(); //Line 객체연결 n = start; obj = new Rect(); n.next = obj; //Rect 객체연결 n = obj; obj = new Line(); // Line 객체연결 n.next = obj; n = obj; obj = new Circle(); // Circle 객체연결 n.next = obj; // 모든도형출력하기 while(start!= null) { start.draw(); start = start.next; Line Rect Line Circle 38
동적바인딩 class SuperObject { protected t String name; 오버라이딩메소드가항상호출된다. public void paint() { draw(); 동적바인딩 public class SuperObject { public void draw() { protected String name; System.out.println("Super Object"); public void paint() { draw(); public class SubObject extends SuperObject { public void draw() { public void draw() { System.out.println("Super Object"); System.out.println("Sub Object"); public static void main(string i [] args) ){ public static ti void main(string i [] args) ){ SuperObject a = new SuperObject(); SuperObject b = new SubObject(); a.paint(); b.paint(); Super Object Sub Object 39
super 키워드 40 super는슈퍼클래스의멤버를접근할때사용되는레퍼런스 서브클래스에서만사용 슈퍼클래스의메소드호출시사용 컴파일러는 super 호출을정적바인딩으로처리 class SuperObject { protected String name; public void paint() { draw(); public void draw() { System.out.println(name); public class SubObject extends SuperObject { protected t String name; public void draw() { name = "Sub"; super.name = "Super"; super.draw(); System.out.println(name); public static void main(string [] args) { SuperObject b = new SubObject(); b.paint(); Super Sub
예제 5-5 : 메소드오버라이딩 41 41 Person 을상속받는 Professor 라는새로운클래스를만들고 Professor 클래스에서 getphone() 메소드를재정의하라. 그리고이메소드에서슈퍼클래스의메소드를호출하도록작성하라. class Person { String phone; public void setphone(string phone) { this.phone = phone; public String getphone() { return phone; super.getphone() 은아래 p.getphone() 과달리동적바인딩이일어나지않는다. class Professor extends Person { public String getphone() { return "Professor : " + super.getphone(); public class Overriding { public static void main(string[] args) { Professor a = new Professor(); a.setphone("011-123-1234"); System.out.println(a.getPhone()); Person p = a; System.out.println(p.getPhone()); Professor : 011-123-1234 Professor : 011-123-1234 동적바인딩에의해 Professor 의 getphone() 호출.
42 오버라이딩 vs. 오버로딩
추상메소드와추상클래스 43 추상메소드 (abstract method) 선언되어있으나구현되어있지않은메소드 abstract 키워드로선언 ex) public abstract int getvalue(); 추상메소드는서브클래스에서오버라이딩하여구현 추상클래스 (abstract class) 1. 추상메소드를하나라도가진클래스 클래스앞에반드시 abstract 라고선언해야함 2. 추상메소드가하나도없지만클래스앞에 abstract로선언한경우 추상클래스 abstract class DObject { public DObject next; 추상메소드 public DObject() { next = null; abstract public void draw() ;
2 가지종류의추상클래스사례 44 // 추상메소드를가진추상클래스 abstract class DObject { // 추상클래스선언 public DObject next; public DObject() { next = null; abstract public void draw(); // 추상메소드선언 // 추상메소드없는추상클래스 abstract class Person { // 추상클래스선언 public String name; public Person(String name) { this.name = name; public String getname() { return name;
추상클래스의인스턴스생성불가 45 abstract class DObject {// 추상클래스선언 public DObject next; public DObject() { next = null; abstract public void draw(); // 추상메소드선언 public class AbstractError { public static void main(string [] args) ){ DObject obj; obj = new DObject(); // 컴파일오류, 추상클래스 DObject의인스턴스를생성할수없다. obj.draw(); // 컴파일오류
추상클래스의상속 46 추상클래스의상속 2 가지경우 추상클래스의단순상속 추상클래스를상속받아, 추상메소드를구현하지않으면서브클래스도추상클래스됨 서브클래스도 abstract로선언해야함 abstract class DObject { // 추상클래스 public DObject next; public DObject() { next = null; abstract public void draw(); // 추상메소드 abstract class Line extends DObject { // draw() 를구현하지않았기때문에추상클래스 public String tostring() { return "Line"; 추상클래스구현상속 서브클래스에서슈퍼클래스의추상메소드구현 ( 오버라이딩 ) 서브클래스는추상클래스아님
47 추상클래스의구현및활용예 class DObject { public DObject next; public DObject() { next = null; public void draw() { System.out.println( DObject draw ); abstract class DObject { public DObject next; 추상클래스로수정 public DObject() { next = null; abstract public void draw(); class Line extends DObject { public void draw() { System.out.println( Line ); class Rect extends DObject { public void draw() { System.out.println( Rect ); class Circle extends DObject { public void draw() { System.out.println( Circle ); 추상클래스를상속받아추상메소드 draw() 를구현한클래스
추상클래스의용도 48 설계와구현분리 서브클래스마다목적에맞게추상메소드를다르게구현 다형성실현 슈퍼클래스에서는개념정의 서브클래스마다다른구현이필요한메소드는추상메소드로선언 각서브클래스에서구체적행위구현 계층적상속관계를갖는클래스구조를만들때
예제 5-6 : 추상클래스의구현 49 다음의추상클래스 Calculator 를상속받는 GoodCalc 클래스를독자임의로작성하라. abstract class Calculator { public abstract bt tint add(int a, int b); public abstract int subtract(int a, int b); public abstract double average(int[] a);
예제 5-6 정답 50 class GoodCalc extends Calculator { public int add(int a, int b) { return a+b; public int subtract(int a, int b) { return a - b; public double average(int[] 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,3)); System.out.println(c.subtract(2,3)); System.out.println(c.average(new int [] {2,3,4)); 5-1 3.0
실세계의인터페이스와인터페이스의필요성 51 정해진규격 ( 인터페이스 ) 에맞기만하면연결가능. 각회사마다구현방법은다름 정해진규격 ( 인터페이스 ) 에맞지않으면연결불가
자바의인터페이스 52 인터페이스 (interface) 모든메소드가추상메소드인클래스 인터페이스는상수와추상메소드로만구성. 변수필드선언불 인터페이스선언 interface 키워드로선언 ex) public interface SerialDriver { 인터페이스의특징 인터페이스의메소드 public abstract 타입으로생략가능 인터페이스의상수 public static final 타입으로생략가능 인터페이스의객체생성불가 인터페이스에대한레퍼런스변수는선언가능
자바인터페이스사례 53 public interface Clock { public static final int ONEDAY = 24; // 상수필드선언 abstract public int getminute(); abstract public int gethour(); abstract bt tvoid setminute(int t t i); abstract void sethour(int i); public interface Car { int MAXIMUM_SPEED = 260; // static final 생략... int movehandle(int degree); // abstract public 생략 int changegear(int gear); // abstract t public 생략 new Clock(); // 오류. 인터페이스의객체생성불가 new Car(); // 오류. 인터페이스의객체생성불가 Cl k l k // 인터페이스 Cl k 의레퍼런스변수선언가능 Clock clock; // 인터페이스 Clock 의레퍼런스변수선언가능 Car car; // 인터페이스 Clock 의레퍼런스변수선언가능
인터페이스의필요성 54 인터페이스를이용하여다중상속구현 자바에서클래스다중상속불가 인터페이스는명세서와같음 인터페이스만선언하고구현을분리하여, 작업자마다다양한구현을할수있음 사용자는구현의내용은모르지만, 인터페이스에선언된메소드가구현되어있기때문에호출하여사용하기만하면됨 110v 전원아울렛처럼규격에맞기만하면, 어떻게만들어졌는지알필요없이전원연결에사용하기만하면됨 구현 1 사용자 인터페이스 구현 2
인터페이스상속 55 인터페이스간에도상속가능 인터페이스를상속하여확장된인터페이스작성가능 인터페이스다중상속허용 interface MobilePhone { boolean sendcall(); boolean receivecall(); boolean sendsms(); boolean receivesms(); interface MP3 { void play(); void stop(); interface MusicPhone extends MobilePhone, MP3 { void playmp3ringtone();
인터페이스구현 56 인터페이스구현 implements 키워드사용 여러개의인터페이스동시구현가능 상속과구현이동시에가능 interface USBMouseInterface { void mousemove(); void mouseclick(); public class MouseDriver implements USBMouseInterface { // 인터페이스구현 void mousemove() {... void mouseclick() {... // 추가적으로다른메소드를작성할수있다. int getstatus() {... int getbutton() {...
인터페이스의다중구현 57 interface USBMouseInterface { void mousemove(); void mouseclick(); interface RollMouseInterface { void roll(); public class MouseDriver implements RollMouseInterface, USBMouseInterface { void mousemove() {... void mouseclick() {... void roll() {... // 추가적으로다른메소드를작성할수있다. int getstatus() {... int getbutton() {...
58 추상클래스와인터페이스비교