8. 확장클래스및인터페이스...
TRANSCRIPT
JAVA 프로그래밍
8. 확장 클래스 및 인터페이스
한 동 일
2/62
학습 목표
To learn about inheritance
To understand how to inherit and overridesuperclass methods
To be able to invoke superclass constructors
To learn about protected and package access control
To learn about interfaces
To be able to convert between class and interface references
3/62
학습 목표
To learn how to implement helper classes as inner classes
To understand how inner classes access variables from the surrounding scope
To implement event listeners for timer events
4/62
확장 클래스(extended class)
기존 클래스
확장 클래스
superclass(base class)
subclass(derived class)
추가정보
확장 클래스의 개념
상속(Inheritance)
superclass의 모든 속성이 subclass로 전달되는 기능
클래스의 재사용성을 증가 시킨다.
5/62
상속의 예
person
student faculity staff
undergrad graduate
상위(super) 클래스
하위(sub) 클래스
6/62
확장 클래스
확장 클래스 정의 형태
확장 클래스의 예 :
class SubClassName extends SuperClassName {// 필드 선언// 메소드 정의
}
class SuperClass {int a;void methodA {
// ...}
}
class SubClass extends SuperClass {int b;void methodB {
// ... }
}
7/62
확장 클래스
확장 클래스의 실제 예 :
Example:public class SavingsAccount extends BankAccount {
public SavingsAccount(double rate) { interestRate = rate;
}
public void addInterest() { double interest = getBalance() * interestRate / 100; deposit(interest);
} private double interestRate;
}
Purpose:To define a new class that inherits from an existing class, and define the methods and instance fields that are added in the new class.
8/62
확장 클래스 단일 상속(single inheritance)
오직 한 개의 슈퍼클래스만 가질 수 있다.
C++ : 다중 상속(multiple inheritance) 지원
Object 클래스
모든 클래스의 슈퍼클래스
객체에 적용할 수 있는 기본 메소드가 정의되어 있음
Object
SuperClass
SubClass
슈퍼클래스를 명시하지 않으면기본적으로 슈퍼클래스는 Object
9/62
확장 클래스의 메소드 메소드 재정의(method overriding)
슈퍼클래스에 정의된 메소드의 의미를 서브클래스에서변경
슈퍼클래스의 메소드를 상속(inherit)
명시적으로 재정의 하지 않을 경우 자동으로 상속
새로운 메소드의 추가
슈퍼클래스에서 정의되지 않은 메소드를 새로 추가하여 사용
10/62
메소드 중복
메소드 중복(method overloading)
메소드 이름은 같은데 매개 변수의 개수와 형이 다른 경우
메소드가 중복된 경우, 호출 시 구별은 컴파일러가 행함.
시그니처(signature)
메소드를 구별하는데 쓰이는 정보
메소드의 이름
매개 변수의 개수
매개 변수의 형
void methodOver(int i) { /* . . . */ } // 첫 번째 형태void methodOver(int i, int j) { /* . . . */ } // 두 번째 형태
11/62
메소드 재정의 메소드 재정의(method overriding)
슈퍼클래스에 정의된 메소드의 의미를 서브클래스에서변경
매개변수 개수와 형이 같음 --- 같은 메소드
서브 클래스의 메소드로 대체
메소드 재정의를 할 수 없는 경우
정적(static) 메소드
최종(final) 메소드
최종 클래스 내에 있는 모든 메소드는 묵시적으로 최종 메소드
12/62
SchoolFamily
상속
메소
드 오
버로
드
메소
드 오
버라
이드
idname
SchoolFamily(int id)
SchoolFamily(int id, String name)
public void register(int id, String name)
상속
Student
lesson,studentnum,total,average
Student(int studentnum, int kor, int eng, int math);
total();
average();
public void register(int id, String name) {
this.id = id; this.name = name;
System.out.println("수강과목의 수는 ? ");
...
}
Teacher
course
Teacher(int course, int id) {
super(id);
}
Teacher(int course, int id, String name) {
super(id, name);
}
메소드 중복과 재정의 예
13/62
슈퍼 클래스의 메소드 사용 확장클래스에서 재정의된 경우 슈퍼 클래스에서 정의된메소드를 부르고 싶어도 확장클래스의 메소드가 자동적으로 불려짐
슈퍼 클래스 메소드를 사용할 경우 : super 이용
super.methodName(parameters)
Example:public void deposit(double amount){transactionCount++;super.deposit(amount);
}
Purpose:To call a method of the superclass instead of the method of the current class
14/62
확장 클래스의 구성자
형태와 의미는 모두 클래스 구성자와 같다.
단, 슈퍼클래스를 초기화하기 위해서는 먼저 슈퍼클래스
구성자를 호출한다.
super(), super(param1, param2, …)
슈퍼클래스의 구성자를 명시적으로 호출
확장 클래스 구성자의 첫문장에 와야 함
명시적으로 호출하지 않으면, 기본 생성자가 컴파일러에
의해 자동적으로 호출
15/62
확장 클래스의 필드
다른 이름
그대로 상속된다.
동일한 이름
숨겨진다. super --- 숨겨진 슈퍼클래스에 있는 필드를 참조할 때 사용. 사용 시 주의할 것
class SuperClass {int a = 1;int b = 1;
}class SubClass extends SuperClass {
int a = 2;int b = super.a;// . . .
}
super.asuper.b
ab
16/62
확장 클래스의 필드
비공개 필드(private)의 접근
서브클래스는 슈퍼클래스의 비공개 필드를 직접 접근불가능
서브클래스는 슈퍼클래스의 비공개 필드를 상속받아 보유하고 있지만 접근은 불가능
슈퍼클래스의 비공개 필드 접근 방법
슈퍼클래스의 공개메소드 이용
public void deposit(double amount){transactionCount++;super.deposit(amount);// balance = balance + amount;
} // balance는 private 이므로 직접 접근 불가
17/62
속성 변수의 접근 한정자(복습) 접근 한정자, 접근 명세(access specifier)
다른 클래스에서 필드의 접근 허용 정도를 나타내는 부분
public, protected, private
private int i; // privateint j;protected int k; // protectedpublic int sum; // public
접근 한정자접근 한정자 클래스클래스 서브 클래스서브 클래스 같은 패키지같은 패키지 모든 클래스모든 클래스
private[ ]protectedpublic
private[ ]protectedpublic
OO XX XX XX
선언 예
OO
OO
OO
XX
OO
OO
OO
OO
OO
XX
XX
OO
18/62
클래스 타입 변환 서브 클래스의 참조는 슈퍼 클래스 참조로 변환 가능
모든 참조는 Object 타입으로 변환 가능
SavingsAccount collegeFund = new SavingsAccount(10); BankAccount anAccount = collegeFund; Object anObject = collegeFund;
19/62
클래스 타입 변환
슈퍼 클래스 참조로 변환 시 참조 객체에 대해 모르는부분 발생
참조를 변환하는 경우
슈퍼 클래스만 알고 서브 클래스를 모르는 코드의재사용을 위해
참조가 가리키는 객체는 모든 정보를 보유
그러나 변환된 참조는 모든 정보를 알지 못함
anAccount.deposit(1000); // OK anAccount.addInterest(); // No--not a method of the class to which anAccount belongs
20/62
클래스 타입 변환
슈퍼 클래스의 참조를 서브 클래스 참조로 변환 시
반드시 캐스팅 사용
잘못된 참조로 변환 시 예외 발생 – 주의 요망
안전한 처리 방법 : instanceof 연산자 사용
instanceof 연산자 : 객체가 특정 타입에 속하는지를판단
BankAccount anAccount = (BankAccount) anObject;
if (anObject instanceof BankAccount) { BankAccount anAccount = (BankAccount) anObject; . . .
}
21/62
instanceof 연산자
연산자의 왼쪽에 있는 객체가 오른쪽에 있는 객체형의 인스턴스일 경우에 참값, 아닐 경우 거짓값을 반환
형태 :
o instanceof C가 참값을 반환할 조건
객체 o를 생성한 클래스 C’가 C이거나 C의 하위 클래스
C가 인터페이스일 경우 C’는 C를 구현
C가 T’형의 배열이고 o가 T형의 배열일 경우, T는 T’의하위 인터페이스이거나 하위 클래스, 또는 T’와 T가 같은 자료형
객체 instanceof 객체형
22/62
추상 클래스(abstract class)
추상 메소드(abstract method)를 갖고 있는 클래스
추상 메소드 :
실질적인 구현을 갖지 않고 메소드 선언만 있는 경우
선언 방법
abstract class AbstractClass {public abstract void methodA();void methodB() {
// ...}
}
23/62
추상 클래스(abstract class)Wolf aWolf = new Wolf();
Wolf 객체
Wolf
aWolfHippo 객체
Animal
aHippoAnimal 객체
Animal
anim
?
Animal aHippo = new Hippo();
Animal anim = new Animal();?
24/62
추상 클래스(abstract class)
Animal
Lion Hippo
TigerDog
Cat
Wolf
FelineCanine
추상
Polygon
TriangleSquare
RectangleCircle
추상
추상 추상Polygon의면적은?
25/62
추상 클래스(abstract class)
구현되지 않고, 단지 외형만을 제공
추상 클래스는 객체를 가질 수 없음
다른 외부 클래스에서 메소드를 사용할 때 일관성 있게 다루기 위한 방법을 제공
다른 클래스에 의해 상속 후 사용 가능
서브클래스에서 모든 추상 메소드를 구현한 후에 객체생성 가능
추상 메소드를 서브클래스에서 구현할 때 접근 한정자는 항상 일치
26/62
내부 클래스(Inner class)
클래스의 내부에서 정의된 클래스
클래스 내부에서 사용하고자 하는 객체형을 정의할수 있는 방법을 제공
클래스의 참조 범위를 제한하여 클래스의 이름 충돌 문제를 해결
정보 은닉화(information hiding)
class OuterClass {// ...class InnerClass {
// ...}
}
27/62
내부 클래스 클래스 내부나 메소드 내부에 존재 가능
지역 변수의 영역 정의에 의해서 내부 클래스를 포함하는 영역의 지역 변수를 접근 가능 단, 내부 클래스 주변의 지역 변수는 final로 선언되어야 내부
클래스 내에서 접근 가능
class OuterClassName { method signature {
. . . class InnerClassName {
// methods // fields
} . . .
} . . .
}
class OuterClassName { // methods // fieldsclass InnerClassName {
// methods // fields
} . . .
}
28/62
내부 클래스(Inner class) 이름 참조
OuterClass 내부 : InnerClass 단순명을 사용
OuterClass 외부 : OuterClass.InnerClass
접근 수정자
public, private, protected
static 존재 유무에 따라 정적/비정적 내부 클래스로 구분
내포 클래스(Nested Class) 라고도 함
public static void main(String[] args) {OuterClass outObj = new OuterClass();OuterClass.InnerClass inObj = outObj.new InnerClass();
}
29/62
정적 내부 클래스 정적 내부 클래스
지정어 static을 사용하여 정의
정적 변수 사용 가능
내부 클래스를 포함하는 영역의 정적 변수 접근 가능
객체 생성 없이 참조
class OuterClass {// ...static class InnerClass {
static int staticVariable;// ...
}}
OuterClass.InnerClass
OuterClass.InnerClass inObj = new OuterClass.InnerClass();
30/62
비정적 내부 클래스
비정적 내부 클래스
static으로 선언되지 않은 내부 클래스
정적 변수 사용 불가
객체를 생성한 후 멤버 접근
class OuterClass {// ...class InnerClass {
// ...}
}
31/62
내부 클래스
자바 컴파일러자바 소스클래스이름.class
외부클래스이름$내부클래스이름.class
class Outer {class Inner1 {
class Inner2 { // … }// ...
}// ...
}
Outer.classOuter$Inner1.classOuter$Inner1$Inner2.class
컴파일 시 모든 클래스에 대해 *.class 파일을 생성
명칭의 형태: 외부클래스이름$내부클래스이름
32/62
인터페이스(Interface)란?
사용자 접속을 기술하는 방법으로 메소드들을 선언하
고 필요한 상수들을 정의한 프로그래밍 단위
상수와 구현되지 않은 메소드들만을 갖고 있는 순수
한 설계의 표현
다중상속(multiple inheritance)문제 해결
단일 상속(single inheritance) --- 클래스
33/62
Animal
Lion Hippo
TigerDog
Cat
Wolf
FelineCanine
Pet
다중 상속
34/62
다중 상속(multiple inheritance)의 문제점
죽음의 다이아몬드DigitalRecorder
int i
burn()
CDBurner
burn()
DVDBurner
burn()
ComboBurner
burn()
자바에서는 다중 상속을 허용하지 않습니다.
다중 상속의 문제
35/62
Animal
Lion Hippo
TigerDog
Cat
Wolf
FelineCanin
e
Pet
Robot
Agent RoboDog
인터페이스
다중 상속 문제의 해결
36/62
인터페이스 선언
선언 형태
사용 예
[public] interface InterfaceName [extends ListOfSuperInterfaces] // constant definitions// method declarations
}
interface BaseColors {int RED = 1;int GREEN = 2;int BLUE = 4;
void setColor(int color);int getColor();
}
37/62
인터페이스 선언
인터페이스의 필드
내부적으로 상수를 의미하는 static, final의 속성
선언된 모든 필드는 반드시 초기화
구현된 class나 객체를 통해 접근
실체 필드는 가질 수 없음
interface BaseColors {int RED = 1;int GREEN = RED + 1;int BLUE = GREEN + 2;
void setColor(int color);int getColor();
}
38/62
인터페이스 선언
인터페이스의 메소드
추상(abstract) 속성
내부적으로 추상 메소드가 됨
인터페이스의 모든 메소드를 구현하지 않는 클래스는추상 클래스로 선언
내부적으로 모두 public 메소드
static이 올 수 없음
생성자를 갖지 않음
39/62
인터페이스 선언
일단, 인터페이스가 선언되면 인터페이스를 구현하는클래스가 있어야 한다. 인터페이스는 객체를 가질 수없다.
class ClassName implements InterfaceName {// 인터페이스에서 정의된 메소드의 구현
}
40/62
인터페이스 확장
확장 형태
interface RainbowColors extends BaseColors {int YELLOW = 3;int ORANGE = 5;int INDIGO = 6;int VIOLET = 7;void printColor(int color);
}
[public] interface InterfaceName extends ListOfSuperInterfaces { // constant definitions// method declarations
}
확장 예
41/62
인터페이스 확장
인터페이스의 다중 상속
슈퍼인터페이스2
슈퍼인터페이스1 슈퍼인터페이스n
서브인터페이스
...
42/62
인터페이스 확장
다중 상속시 동일한 이름의 상수를 상속
단순 명은 ambiguous하기 때문에 에러
RainbowColors.YELLOW, PrintColors.YELLOW
interface ManyColors extends RainbowColors, PrintColors {int VERMILION = 3;int CHARTUSE = RED + 90;
}
• 다중 상속 예
interface RainbowColors {int YELLOW = 1;// }
interface PrintColors {int YELLOW = 2;// }
43/62
인터페이스 확장
메소드 상속
overloading, overriding
그러나, 시그니처가 같고 복귀형이 다르면 에러
interface ActionColors extends BaseColors {void setColor(int color) ; void setColor(int red, int green, int blue) ; // overloading// Color getColor();
}
// overriding
// 에러
interface BaseColors {// ...void setColor(int color);int getColor();
}`메소드 상속 예
44/62
인터페이스 구현
클래스를 통하여 구현된 후 객체를 가짐
구현 형태
[modifier] class ClassName implements InterfaceName {// fields// methods// 인터페이스 구현
}
public, final, abstract
45/62
인터페이스 구현
class Color implements BaseColors {// fieldspublic void setColor(int color) {
// …}public int getColor() {
// …}
}
interface BaseColors {int RED = 1;int GREEN = RED + 1;int BLUE = GREEN + 2;
void setColor(int color);int getColor();
}
구현 예
46/62
인터페이스 구현
인터페이스에 있는 모든 메소드들을 구현하지 않으면그 클래스는 추상 클래스가 된다.
abstract class SetColor implements BaseColors {// fieldspublic void setColor(int color) {
// …}
}
getColor(); 에대한 구현이없을 경우
47/62
인터페이스 구현
클래스 확장과 동시에 인터페이스 구현
다이아몬드 상속(diamond inheritance)
class ClassName extends SuperClass implements ListOfInterfaces {// fields// methods
}
interface W { }interface X extends W { }class Y implements W { }class Z extends Y implements X { }
Z
Y
W
X
48/62
인터페이스 vs. 추상 클래스
인터페이스
다중 상속을 지원
메소드 선언만 가능 --- 메소드를 정의할 수 없다.
추상 클래스
단일 상속
메소드의 부분적인 구현이 가능
49/62
클래스/인터페이스 타입 변환
클래스 타입에서 인터페이스 타입으로의 전환
클래스가 인터페이스 타입을 구현 시 가능
public class BankAccount implements Measurable { // Other BankAccount methods public double getMeasure() {
// Method implementation }
}
BankAccount account = new BankAccount(10000);Measurable x = account; // OK// x 라는 참조 변수가 참조하는 객체가 getMeasure라는 메소드// 를 보유하고 있다는 사실만 알 수 있음
50/62
클래스/인터페이스 타입 변환
관계없는 타입 사이의 전환은 불가능
인터페이스 타입에서 클래스 타입으로의 전환
반드시 캐스트를 사용해야 함
인터페이스의 참조가 실제로는 객체 참조일 경우만 가능
Measurable x = new Rectangle(5, 10, 20, 30); // ERROR
BankAccount account = new BankAccount(10000);Measurable x = account; // 인 경우. . . BankAccount otherAccount = (BankAccount) x; // OK
51/62
타이머 이벤트 처리
javax.swing.Timer 클래스 : 균일한 시간 간격의 이벤트 발생
객체를 규칙적인 간격으로 갱신할 때 유용
타이머는 일정한 간격의 이벤트 발생
이벤트 발생 시 ActionLister에게 통보됨
ActionListener 인터페이스의 구현 필요
public interface ActionListener {void actionPerformed(ActionEvent event);
}
52/62
타이머 이벤트 처리 ActionListener 인터페이스의 구현 예
class MyListener implements ActionListener {void actionPerformed(ActionEvent event){// This action will be executed at each timer event//Place listener action here
}}
53/62
타이머 이벤트 처리 타이머 이벤트 처리 순서
ActionListener 인터페이스를 구현하는 클래스 정의
청취자 객체 구성
타이머 구성자에게 전달
타이머 가동
프로그램을 살려 놓기 위해 대화 상자를 디스플레이
// ActionListener 구현 : 앞페이지 참고
MyListener listener = new MyListener(); // 객체 구성Timer t = new Timer(interval, listener); // Timer 구성자t.start(); // 타이머 가동
JOptionPane.showMessageDialog(null, “Quit?”);
54/62
첨부된 Instance 폴더 내의 Instance.java 파일을 이해하고 수행 이전에 결과를 예측해 보라. 이후 결과를 확인해보라. 원하는 결과가 나오지 않았다면 이유를 확인하라.
필요 시 자바 API의 Vector 클래스를 참고하라.
[실습0] – Instanceof 연산자
55/62
첨부된 Overloading 폴더 내의 SubClass.java와OverloadingTest.java를 보고 실행 결과를 예상하라. 예상한 결과와 다르다면 왜 그런지 파악하라.
SubClass.java의 function들을 분류하라. Overriding과 Overloading
Overloading의 종류
SubClass.java의 주석을 풀고 실행하라. 원하는 결과가 나오는가? 나오지 않는다면 왜 그런지 파악하라.
[실습1] – Overloading/Overriding
56/62
첨부된 Extends 폴더 내의 Subtractor.java 코드 등을이해하고 CalculatorTest.java를 실행하여 Adder class와의 상속관계에 대해 파악하라. left와 right 변수를 protected로 선언한 이유는 무엇인가?
left와 right 변수를 단순히 private로 선언하면 그 증상은?
left와 right 변수를 private로 선언하고 코드가 동작하도록 재설계를 하라. 힌트 : getLeft()와 같은 공개 인터페이스 사용
Subtractor class를 상속하고 곱하기와 나누기를 할 수있게 Calculator class를 구현하고 테스트하라.
[실습2] – Class의 확장
57/62
첨부된 Abstract 폴더 내의 DrawTest.java 코드는 사각형, 원, 삼각형 그리고 집 모양을 그리는 코드의 테스트파일이다. 여러 번 실행해보고 어떻게 동작하는지 파악하라. 그 후 DrawComponent.java 코드를 통해서 동작을 이해하라.
Drawable.java 코드를 보고 DrawRectangle/Circle/ Triangle/House 코드가 각각 어떻게 상속을 사용하였는지 확인하라.
4장에서 구현한 Car.java 코드를 활용하여 Drawable의상속을 받게 하고 5개(사각형, 원, 삼각형, 집, 자동차)의모양을 랜덤하게 그리도록 코드를 수정하라.
[실습3] – Abstract Class
58/62
첨부된 Interface 폴더 내의 Calculator.java는 calculate라는 추상 메소드를 가진 추상 클래스이다. Adder, Subtractor, Multiflier, Divider가 오버라이딩 하고 있는
것을 확인하라.
CalculatorTest.java 코드를 통해 원하는 대로 동작하는지 확인하라.
클래스 확장을 인터페이스 구현으로 바꿔보라. Abstract Class와 Interface의 차이점에 유의할것.
[실습4] - Interface
59/62
첨부된 Multiple 폴더 내의 Dog.java 코드는 Animal과Pet을 상속받는 클래스이다. DogTest.java 코드를 검토해보고 결과를 예측한 후 실행하라. 원하는 결과가 나오지 않았다면 왜 그런지 생각해보라.
interface를 이용하여 다중 상속을 받을 수 있게 코드들을 수정하라.
있으니까 실습코드 만들긴 했지만 다중상속은 웬만하면 쓰지 말자 -
[실습5] – 다중 상속
60/62
첨부된 TimerTester는 1초(1000ms)마다 현재 시간을출력하는 프로그램이다. 타이머와 ActionListener의 관계를 중심으로 이해하라.
시간을 10초 출력하면 더 이상 출력하지 않게 수정하라.
[실습6] – Timer event
61/62
첨부된 Car 폴더 내의 클래스들은 움직이는 자동차를 출력하는 프로그램이다. Car.java 코드의 경우 4강에서 구현한 자동차 그림에 위치 정보
를 얻는 메소드가 추가되어 있으며 이를 이해하라.
CarMoverComponent.java 코드의 경우 0.01 초마다 새로운 위치에 자동차를 그리는 동작을 수행하며 이를 이해하라.
자동차가 프레임 윈도우 바깥으로 빠져 나가지 않도록코드를 수정하라. 힌트 1 : 프레임의 왼쪽 끝이나 오른쪽 끝, 위, 아래로 나갈 경우
진행 방향을 변경
힌트 2 : Component(혹은 JComponent) 클래스에서 정의된getWidth(), getHeight() 메소드 사용 권장
[실습7] – Animation
62/62
Reading Assignment
9강 강의자료(이벤트 처리) 읽어 올 것.