JAVA 프로그래밍 6장 객체지향프로그래밍의 핵심
학습목표 이 장에서는 객체지향프로그램의 가장 중요한 핵심인 코드의 재사용을 클래스의 상속을 통해 구현하고, 객체를 다양한 형태로 생성할 수 있는 다형성을 학습하고, 추상클래스, 인터페이스 내부클래스와 그 밖의 반드시 알아 두어야 하는 중요클래스들에 대해 학습한다. 목차 Section1 클래스 상속(Inheritance of class) Section2 다형성(polymorphism) Section3 추상클래스(abstract class) Section4 인터페이스(interface) Section5 static 과 final Section6 내부 클래스(inner class) Section7 중요클래스들 JAVA 프로그래밍
6장-객체지향 프로그래밍의 핵심 Section1 클래스 상속(Inheritance of class) 객체지향의 중요개념인 클래스의 상속에 대해 학습한다 . Section2 다형성(polymorphism) 유연한 객체를 생성하기 위해 다형성에 대해 학습한다 . Section3 추상클래스(abstract class) 상속을 목적으로 하는 추상클래스에 대해 학습한다. Section4 인터페이스(interface) 다중 상속을 위한 인터페이스에 대해 학습한다. static과 final키워드에 대해 학습한다. Section5 static 과 final 클래스안에 속해 있는 내부 클래스에 대해 학습한다. Section6 내부 클래스(inner class) Vector, Wrapper등 알아두어야할 중요클래스에 대해 학습한다. Section7 중요클래스들 JAVA 프로그래밍
1. 클래스 상속(Inheritance of class) (1/6) 객체지향개념의 가장 중요한 코드의 재사용을 프로그램으로 구현하는 부분이다. 새로운 클래스를 생성할 때 처음부터 새로 작성하는 것이 아니라, 기존에 정의된 클래스로부터 중복되는 부분을 물려받아서 사용할 수 있다. 이렇게 되면 우리는 새로운 클래스에서 추가되는 부분만 고심해서 프로그래밍하면 된다. 프로그램을 전체를 새로 개발한 것이 아니므로 프로그램 개발기간의 단축과, 비용의 감소를 가져올 수 있고, 이미 실 시스템에서 안정적으로 돌아가는 코드부분을 사용하시 때문에 시스템이 더 안정적이다. JAVA 프로그래밍
1. 클래스 상속(Inheritance of class) (2/6) 새로 작성해서 기존의 코드를 가져다 쓰는 클래스가 상속을 받는 클래스 서브클래스(sub class), 자식클래스(child class), 파생클래스(derived class) 기존에 이미 만들어져서 상속해주는 클래스 슈퍼클래스(super class), 베이스클래스(base class), 부모클래스(parent class) 자바 프로그램에서 상속은 extends라는 키워드를 써서 표현한다. JAVA 프로그래밍
1. 클래스 상속(Inheritance of class) (3/6) 상속은 "is a"관계로 표현된다. "Human is a Mammal." 포유류의 종류 중 사람이라는 하나의 종류로 특성화(구체화)됨을 보여준다. 그래서 상속을 클래스의 특별화(구체화)라고도 부른다. extends를 중심으로 왼쪽이 서브클래스 이고 오른쪽이 슈퍼클래스 이다 class Mammal{ //Mammal클래스 정의 void eat(){ } } class Human extends Mammal{ //Human클래스 정의 ... JAVA 프로그래밍
1. 클래스 상속(Inheritance of class) (4/6) super 레퍼런스 super 레퍼런스는 슈퍼클래스를 가리키는 레퍼런스이고 super()메소드 super()메소드는 슈퍼클래스의 생성자를 호출한다. this 레퍼런스나 super 레퍼런스는 static이 붙은 메소드에서는 사용 할 수 없다. 따라서 main()메소드에서도 이들을 사용할 수 없다. JAVA 프로그래밍
1. 클래스 상속(Inheritance of class) (5/6) 오버라이딩(overriding) (1/2) 오버라이딩은 상속관계에서 발생하는데, 슈퍼클래스에서 상속받은 메소드를 그대로 사용하는 것이 아니라, 서브클래스에 맞도록 고쳐서 사용하는 것을 말한다. 슈퍼클래스와 서브클래스에 같은 이름을 가진 메소드가 존재할 때, 슈퍼클래스의 메소드를 무시하고(override), 서브클래스의 메소드를 사용하는 것으로, 메소드를 재 정의하는 것이다. JAVA 프로그래밍
1. 클래스 상속(Inheritance of class) (6/6) 오버라이딩(overriding) (2/2) 오버라이딩시 주의점 첫 번째 슈퍼클래스의 메소드를 오버라이딩하는 서브클래스의 메소드는, 메소드의 시그니쳐는 물론 리턴 타입까지 일치해야 한다. 일치하지 않으면 오버라이딩이 되지 않는다. 두 번째 서브클래스에서 재정의 되는 메소드의 접근제어자는 슈퍼클래스의 오버라이드되는 메소드의 접근제어자 와 같거나, 덜 제한적인 접근제어자를 써야한다. JAVA 프로그래밍
2. 다형성(polymorphism) (1/2) 자바에서 클래스의 객체를 생성하는데 융통성을 부여하기 위해서 다형성이라는 매커니즘을 사용한다. '다형성'은 여러 개의 서로 다른 형식과 모양을 가진다는 의미로, 다형성을 이용하면 객체의 유형에 따라 서로 다른 작업을 수행하도록 할 수 있다. 객체는 한가지 타입에 하나의 형태만을 생성하는 고정적인 형태보다, 한가지 타입으로 여러형태를 생성할 수 있는 유동적인 형태가 프로그램을 더욱 편하게 작성하게 해준다 JAVA 프로그래밍
2. 다형성(polymorphism) (2/2) 레퍼런스가 슈퍼클래스이고 , 생성되는 객체가 서브클래스가 할당되면, 할당되는 서브클래스의 객체 타입에 따라 다양한 형태의 객체를 생성할 수 있다. JAVA 프로그래밍
3. 추상클래스(abstract class) (1/4) 메소드에서 내용을 가지고 있다는 것은 바디(body: {})를 가진 메소드를 의미한다. 클래스가 가지고 있는 메소드가 모두 바디를 가지고 있으면 구체적 클래스라 부를 수 있다. 메소드가 바디를 가지고 있지 않고 메소드의 인터페이스 부분(선언부)만 갖고 있는 메소드가 하나라도 있으면 이 클래스를 추상클래스라 부른다. 이때 바디없이 메소드의 선언부만 갖고 있는 메소드를 추상메소드라 한다. 추상메소드는 메소드의 선언부 다음에 ;(세미콜론)이 온다. JAVA 프로그래밍
3. 추상클래스(abstract class) (2/4) 추상클래스는 객체를 생성할 수 없다. 객체를 생성하려면 클래스가 가지고 있는 메소드가 모두 바디를 가지고 있어야 한다. 추상클래스는 상속을 통해서 완전해지는 것이다. 추상클래스는 선언시 abstract키워드를 써서 선언한다. public class AbstractClass{ //추상클래스가 된다. int abc(){ ... } public void test(int x); //추상메소드 } JAVA 프로그래밍
3. 추상클래스(abstract class) (3/4) 추상클래스를 상속받는 클래스는 추상클래스의 추상메소드를 모두 오버라이딩해야 한다. 오버라이딩을 하지 않으면 에러가 발생한다. 추상메소드는 그 클래스를 상속받는 클래스가 여러개여서 공통의 내용을 기술할 수 없거나 할 필요가 없는 경우 또는 어떠한 클래스에서 상속받을 지 알 수 없기 때문에 내용을 기술할 수는 없지만 반드시 작성해야 하는 메소드를 상속을 받는쪽에서 반드시 구현(implements)하도록 강제하기 위해서 사용한다. 필수적으로 작성해야 하는 메소드의 경우에 추상메소드로 선언해서 강제로 구현하도록 한다. JAVA 프로그래밍
3. 추상클래스(abstract class) (4/4) 추상메소드의 선언 메소드의 끝이 {}없이 ;(세미콜론) 으로 마무리된다. 추상클래스로부터 상속을 받는 경우 추상메소드의 바디부분을 반드시 구현해야 한다. 반드시 추상메소드는 오버라이딩해야 한다. 접근제어자 abstract 리턴타입 메소드명(매개변수리스트); JAVA 프로그래밍
4. 인터페이스(interface) (1/3) 자바는 다중상속을 지원하지 않는다. 자바에서 간접적인 다중상속을 위해 인터페이스를 제공하는데 인터페이스는 기본적으로 멤버변수와 추상메소드의 집합이다. 인터페이스는 스펙(spec)만을 기술해 놓은 것으로 인터페이스를 사용하려면 클래스에서 인터페이스를 구현하여야 한다. 즉, 클래스가 인터페이스를 구현하도록 선언하고, 인터페이스 내에 선언된 각 메소드의 코드를 클래스 정의의 일부로 작성해 넣어야 한다. 인터페이스가 가지고 있는 메소드가 모두 추상메소드이므로 인터페이스는 구현하는 클래스에서 해당 메소드를 반드시 모두 오버라이딩 해야 한다는 것이다. JAVA 프로그래밍
4. 인터페이스(interface) (2/3) 인터페이스에 들어있는 메소드는 항상 public abstract이다. 즉, public abstract를 지정하지 않아도 자동으로 이들을 갖는다. 인터페이스의 멤버변수는 항상 public static final이다. 이것도 기본값으로 정해져 있으므로 굳이 선언하지 않아도 된다. 또한 인터페이스는 public abstract의 속성을 갖는다. 인터페이스는 interface라는 키워드로 정의한다. interface Draw{ //인터페이스 선언 int x=5; //멤버변수 public abstract test(); //추상메소드 } JAVA 프로그래밍
4. 인터페이스(interface) (3/3) 인터페이스를 implements를 사용해서 일종의 상속을 구현한다. 인터페이스를 상속받을 때는 extends대신에 implements를 사용한다. 여러 개의 인터페이스를 implements받을 수 있다. 여러 개의 인터페이스를 implements받을 때는 그냥 여러 인터페이스명을 쉼표(,)를 사용해서나열하면 된다. 나열되는 인터페이스간에 같은 이름을 가진 메소드가 없어야 한다. public class A extends B implements C public class A extends B implements C,D,E JAVA 프로그래밍
5. static 과 final (1/4) final 클래스 final 메소드 JAVA 프로그래밍
5. static 과 final (2/4) final 멤버변수 따라서 final이 붙은 멤버변수는 반드시 초기화를 해야 한다. 새로이 값을 할당하면 컴파일 에러가 발생한다. 일반적으로 final이 붙은 멤버변수는 static을 같이 선언해서 쓴다. JAVA 프로그래밍
5. static 과 final (3/4) static 메소드 static 멤버변수 JAVA 프로그래밍
5. static 과 final (4/4) static 초기화 블럭(static initial block) 클래스에서 static키워드를 사용해서, 초기화 블럭으로 사용할 수 있다. static초기화 블럭은 클래스가 초기화될 때 수행되고, main()메소드보다 먼저 수행된다. JAVA 프로그래밍
6. 내부 클래스(inner class) (1/5) 자바에서는 프로그램을 작성하다보면 클래스내부에 다시 클래스를 선언해야 할 경우가 있다. 이때 클래스내부에 들어 있는 클래스를 내부클래스라 한다. 내부클래스(중첩클래스:nested class)는 바깥클래스(Outer class)의 다른 멤버(메소드, 멤버변수를 말함)와 같은 클래스의 멤버가 된다. 내부클래스는 다른 클래스멤버와 마찬가지로 접근속성을 가질 수도 있으며, 바깥클래스 외부에서의 접근가능 여부는 접근제어자에 의해 결정된다. JAVA 프로그래밍
6. 내부 클래스(inner class) (2/5) static 내부클래스(static inner class) static 내부클래스(static inner class)는 내부클래스의 객체를 바깥클래스에 대해 독립적으로 만들 때 사용한다. static키워드를 가진 내부클래스로, 멤버변수나 메소드처럼 클래스 내부에서 선언된다. 다른 클래스에서 Outer클래스 내부의 클래스인 Inner클래스에 접근하기 위해서 객체를 생성할 때 다음과 같이 객체를 생성한다. public class Outer{ public static class Inner{ //Inner 클래스의 내용 } //Outer 클래스의 내용 } Outer.Inner ex = new Outer.Inner(); JAVA 프로그래밍
6. 내부 클래스(inner class) (3/5) non-static 내부클래스( non-static inner class) non-static 내부클래스는 static내부클래스와 선언되는 위치는 같으나 static이 선언되지 않은 내부클래스이다. 다른 클래스에서 Outer클래스의 내부클래스인 Inner클래스에 접근하기 위해서 객체를 생성할 때는 먼저 바깥클래스의 객체를 생성해서 그 레퍼런스를 가지고 내부클래스의 객체를 생성한다. public class Outer{ public class Inner{ //Inner클래스의 내용 } //Outer클래스의 내용 } Outer out = new Outer(); //바깥클래스인 Outer클래스의 객체 out생성 Outer.Inner in = out.new Inner(); //내부클래스인 Inner클래스의 객체 in 생성 JAVA 프로그래밍
6. 내부 클래스(inner class) (4/5) 지역내부클래스(local inner class) static과 non-static내부클래스가 바깥클래스의 멤버의 위치에 선언되는 것에 비해, 지역내부클래스는 바깥클래스의 메소드안에 선언된 내부클래스이다. public class LocalInnerClass{ // 바깥클래스 int i=10; void outerMethod(){ class Inner{ // 지역내부클래스 final int x=10; String innerMethod(){ return i+" StaticInnerClass"; } } } } JAVA 프로그래밍
6. 내부 클래스(inner class) (5/5) 무명 내부클래스(anonymous inner class) 무명내부클래스는 지역내부클래스의 변형으로서 클래스명을 갖지 않고 한번만 사용할 수 있다. 주로 이벤트처리에서 많이 사용된다. window.addWindowListener( new WindowAdapter() { //무명내부클래스 public void windowClosing( WindowEvent e ){ System.exit( 0 ); } } ); JAVA 프로그래밍
기본 데이터타입(primitive data type) 7. 중요클래스들 (1/7) Wrapper 클래스 자바에서 프로그램을 개발하다 보면 기본 데이터타입(primitive data type)인 int, double, char등등을 객체로 표현해서 써야 할 때가 있다. 기본 데이터타입(primitive data type) Wrapper 클래스 byte Byte short Short int Integer long Long float Float double Double boolean Boolean char Character JAVA 프로그래밍
7. 중요클래스들 (2/7) Vector 클래스(1/3) 자바에서 동적인 배열의 역활을 하는 것은 Vector클래스이다. 채팅프로그램에서 접속한 아이디를 저장할 때 Vector클래스를 사용한다. Vector클래스는 커질 필요가 있다면 지정한증가량, 또는 기본증가 값(원래크기의 두 배)만큼 커진다. Vector는 Object클래스의 레퍼런스들을 저장하도록 만들어져 있다. 따라서 모든 클래스형의 객체에 대한 레퍼런스가 Vector에 저장될 수 있다. Vector는 기본데이터 유형(int, float , short , double , byte , char , boolean)을 저장하지 못한다. 기본데이터 유형을 저장하고 싶으면 Wrapper클래스를 사용해야 한다. JAVA 프로그래밍
7. 중요클래스들 (3/7) Vector 클래스(2/3) Vector클래스는 java.util패키지에 속해있다. Vector를 사용하려면 java.util 패키지를 import해야 한다. Vector클래스의 생성자중 자주 사용하는 생성자 public Vector() : 크기가 10인 벡터생성 public Vector(int initialCapacity) : 크기가 initialCapacity인 벡터생성 public Vector(int initialCapacity, int capacityIncrement) : 크기가 initialCapacity인 벡터가 생성되고, 용량이 부족할 때마다 크기가 capacityIncrement씩 늘어난다. JAVA 프로그래밍
7. 중요클래스들 (4/7) Vector 클래스(3/3) Vector의 메소드중 자주 사용하는 메소드 public int capacity() : 벡터의 크기(용량)를 리턴(반환)한다. public int size() : 벡터안에 저장된 엘리먼트(원소)의 수를 리턴(반환)한다. public void addElement(Object element) : 원소의 끝에 엘리먼트를 추가한다. public void removeElement(Object element) : 벡터에서 처음 매칭되는 엘리먼트를 제거한다. public void trimToSize() : 벡터의 capacity(용량)을 현재 벡터에 저장되어 있는 엘리먼트의 수(size)까지 자른다. 벡터의 용량을 벡터의 크기에 맞추어서 최적화한다. public Object elementAt(int index) : 벡터의 엘리먼트중에서 index번째의 엘리먼트를 리턴(반환)한다. JAVA 프로그래밍
7. 중요클래스들 (5/7) String 클래스 String 클래스는 문자열의 내용을 변경시킬 수없는데 반해 StringBuffer 클래스는 문자열의 내용을 변경 시킬 수 있다. 그래서 String 클래스타입의 문자열을 정적문자열이라 한다. String클래스가 가지고 있는 중요한 메소드이다. public char charAt(int index) : 해당문자열의 index위치에 있는 문자를 리턴(반환)한다. public int indexOf(char char) : 해당문자열에서 char에 해당하는 문자가 몇번째 위치에 있는지 위치값을 리턴(반환)한다. public int length() : 해당문자열의 크기를 리턴(반환)한다. public String substring(int begin, int end) : 해당문자열에서 문자의 위치번호가 begin부터 end까지 문자열을 추출한다. 이때 추출할 마지막 위치번호를 end라고 지정하면 end-1번째 위치까지만 추출된다. 즉, 추출할 마지막 위치번호를 end전까지만 추출된다. public String trim() : 해당문자열의 좌우의 불필요한 공백을 제거하한다. public String toLowerCase() : 해당문자열을 모두 소문자로 변경한다. public String toUpperCase() : 해당문자열을 모두 대문자로 변경한다. JAVA 프로그래밍
7. 중요클래스들 (6/7) StringBuffer 클래스 StringBuffer 클래스타입 문자열을 동적 문자열이라 한다. StringBuffer 클래스는 단독으로 쓰이기 보다는 String 클래스타입의 문자열을 변경시킬때 사용된다. StringBuffer클래스의 중요한 메소드이다 public int capacity() : 해당 StringBuffer클래스 타입의 문자열의 용량를 리턴(반환)한다. 문자열의 크기를 capacity()를 사용해서 얻어낸다. public void ensureCapacity(int len) : 해당 StringBuffer클래스 타입의 문자열의 용량을 len크기만큼으로 변경한다. public StringBuffer reverse() : 해당 StringBuffer클래스 타입의 문자열을 역순으로 배열한다. 예를들어 "abc"의 경우는 "cba"가 된다. public StringBuffer append(Object o) : 해당 StringBuffer클래스 타입의 문자열의 끝에 내용을 추가할 수 있다. 이때 Object, String, boolean , char, int 타입 등등을 추가 할 수 있다. public StringBuffer insert(int offset, String str) : 해당 StringBuffer클래스 타입의 문자열의 어느 위치에나 내용을 삽입할 수 있다. 이때 위치값은 offset이, 삽입할 내용은 str이 가지고 있다. 이때 String타입 뿐만 아니라 Object, boolean , char, int 타입 등등을 추가 할 수 있다. JAVA 프로그래밍
7. 중요클래스들 (7/7) StringTokenizer 클래스 문자열을 분할하기 위해 StringTokenizer 클래스를 제공한다. StringTokenizer 클래스는 문자열을 토큰(Token)이라 불리는 단위로 분리할 수 있다. 토큰(Token)은 분리된 문자열을 각각의 덩어리를 말한다. 토큰은 경계 분리자(delimiter)를 중심으로 분리된다. 경계 분리자(delimiter)는 쉼표(,), 마침표(.), 공백( )등등으로 지정할 수 있다. StringTokenizer 클래스의 생성자 public StringTokenizer(String str, String delimiter) : delimiter를 중심으로 토큰을 분리한다. public StringTokenizer(String str, String delimiter, boolean returnDelims) : delimiter를 중심으로 토큰을 분리하는데 delimiter도 화면에 표시할 것인가? 의 여부를 표시한다. 세번째 매개변수인 returnDelims가 true면 표시하고, 세번째 매개변수를 안 쓰거나 false면 표시하지 않는다. JAVA 프로그래밍