반응형

           

  JAVA Study







6. 추상클래스 (abstract class)


- 미완성 메서드(추상메서드)를 포함한 미완성 클래스 (추상메서드가 없어도 키워드를 붙여 추상클래스로 지정 가능)


- 추상클래스 자체로는 클래스로서의 역할을 다하지 못함, but 새로운 클래스를 작성할 때 바탕이 되는 조상클래스로서 중요한 의미를 가짐


- 추상클래스는 키워드 abstract를 붙이기만 하면 됨


- 추상클래스에도 생성자는 존재, 멤버변수와 메서드도 가질 수 있음


- 추상메서드 없이 완성된 클래스여도 추상클래스로 지정되면 클래스의 인스턴스를 생성할 수 없음


- 추상 메서드 

: 선언부만 작성하고 구현부는 작성하지 않은 메서드

: 실제 내용은 상속받는 클래스에서 구현하도록 비워둠

: 키워드 abstract를 앞에 붙여줌, 구현부가 없으므로 {}대신 ;을 붙임

: 추상클래스를 상속받은 자손클래스에서 오버라이딩을 통해 추상클래스의 추상메서드들을 모두 구현해야 함

- 만약 하나라도 구현하지 않으면 자손클래스역시 추상클래스로 지정해주어야 함


- 추상클래스 작성

: 여러 클래스에 공통적으로 사용될 수 있는 클래스를 바로 작성

: 기존 클래스의 공통 부분을 뽑아 조상클래스를 만듦

: 추상화 - 클래스간의 공통점을 찾아내 공통의 조상을 만드는 작업

: 구체화 - 상속을 통해 클래스를 구현, 확장하는 작업



7. 인터페이스 (interface)


- 일종의 추상클래스, 추상메서드를 갖지만 추상클래스보다 추상화정도가 높아 추상클래스와달리 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없음


- 오직 추상메서드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않음


- 인터페이스 작성

: 인터페이스를 작성하는 것은 클래스 작성과 같다, 키워드로 class 대신 interface를 사용한다

: 접근제어자로 public 또는 default를 사용할 수 있다.


interface 인터페이스 이름 {

public static final 타입 상수이름 = 값;

public abstract 메서드이름(매개변수목록);

}


: 인터페이스 제약사항

- 모든 멤버변수는 public static final 이어야하며, 이를 생략할 수 없음

- 모든 메서드는 public abstract 이어야하며, 이를 생략할 수 없음 (단, static메서드와 default메서드 제외)


- 인터페이스 상속

: 인터페이스는 인터페이스로부터만 상속받을 수 있음, 다중상속 가능

: 자손 인터페이스는 조상 인터페이스에 정의된 멤버를 모두 상속받음


- 인터페이스 구현

: 그 자체로는 인스턴스생성할 수 없음 -> 인터페이스를 구현하는 클래스를 작성해야 함 

: implements를 사용해 구현하는 인터페이스의 메서드 중 일부만 구현한다면 abstract를 붙여서 추상클래스로 정의해야 함

: 상속 (extends)과 구현(implements)을 동시에 할 수 있음


class Fighter extends Unit implements Fightable{

}


- 인터페이스를 이용한 다중상속

: 인터페이스는 static상수만 정의할 수 있으므로 조상클래스의 멤버변수와 충돌하는 경우는 거의 없고 충돌된다 하더라도 클래스 이름을 붙여서 구분이 가능함


- 인터페이스를 이용한 다형성

: 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로 형변환 가능

: 인터페이스 타입의 매개변수가 갖는 의미는 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야 한다는 것

: 리턴타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미


package apple;


interface Parseable{

// 구문 분석작업을 수행

public abstract void parse(String fileName);

}


class ParserManager{

// 리턴타입이 Parseable인터페이스

public static Parseable getParser(String type){

if(type.equals("XML")){

return new XMLParser();

} else{

Parseable p = new HTMLParser();

return p;

//return new HTMLParser();

}

}

}


class XMLParser implements Parseable{

public void parse(String fileName){

//구문 분석 작업을 수행하는코드를 적는다.

System.out.println(fileName+"- XML parsing completed.");

}

}


class HTMLParser implements Parseable{

public void parse(String fileName){

//구문 분석 작업을 수행하는 코드를 적는다.

System.out.println(fileName+"-HTML parsing completed.");

}

}

public class ParserTest {


public static void main(String[] args) {

Parseable parser = ParserManager.getParser("XML");

parser.parse("document.xml");

parser = ParserManager.getParser("HTML");

parser.parse("document2.html");

}


}


: Parseable인터페이스는 구문분석(parsing)을 수행하는 기능을 구현할 목적으로 추상메서드 'parse(String fileName)'을 정의

: XMLParser클래스와 HTMLParser클래스는 Parseable인터페이스를 구현

: 매개변수로 넘겨받은 타입값에 따라 XMLParser인스턴스 또는 HTMLParse인스턴스를 반환


- 인터페이스의 장점

: 개발시간 단축

: 표준화 가능

: 서로 관계없는 클래스들에게 관계를 맺어줄 수 있음

: 독립적인 프로그래밍 가능


- 인터페이스의 이해

: 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provider)이 있다.

: 메서드를 사용(호출)하는 쪽(User)에서 사용하려는 메서드(Provider)의 선언부만 알면된다.(내용은 몰라도 됨)


- 디폴트 메서드와 static메서드
: 디폴트 메서드
- 추상메서드의 기본적인 구현을 제공하는 메서드
- 추상메서드가 아니기 때문에 디폴트메서드가 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 됨
- 여러 인터페이스의 디폴트 메서드간 충돌
: 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩
- 디폴트 메서드와 조상 클래스의 메서드 간 충돌
: 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시

8. 내부클래스 (inner class)


- AWT나 Swing같은 GUI어플리케이션의 이벤트처리 외에는 잘 사용하지 않음


- 클래스 내에 선언된 클래스

: 두 클래스가 긴밀한 관계이기 때문에 내부에 선언


- 내부클래스 장점

: 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있음

: 코드의 복잡성을 줄일 수 있음 (캡슐화)


- 내부클래스의 종류와 특징

: 변수의 선언위치에 따른 종류와 같음

: 인스턴스 클래스

- 외부 클래스의 멤버변수 선언위치에 선언

- 외부 클래스의 인스턴스멤버처럼 다루어짐

- 외부클래스의 인스턴스멤버들과 관련된 작업에 사용될 목적으로 선언

: static 클래스

- 외부 클래스의 멤버변수 선언위치에 선언

- 외부 클래스의 static멤버처럼 다루어짐

- 외부 클래스의 static멤버, 특히 static메서드에서 사용될 목적으로 선언

: 지역 클래스

- 외부 클래스의 메서드나 초기화블럭 안에 선언

- 선언된 영역 내부에서만 사용될 수 있음

: 익명 클래스

- 클래스 선언과 객체의 생성을 동시에 하는 이름없는 클래스 (일회용)


- 내부 클래스의 선언

: 변수의 선언위치와 동일한 위치에 선언

: 각 선언위치에 따라 같은위치의 변수와 동일한 유효범위, 접근성을 가짐


- 내부 클래스 제어자와 접근성

: 변수와 동일

: 내부 클래스 중 static클래스만 static멤버를 가질 수 있음


- 익명 클래스 

: 이름이 없음

: 클래스의 선언과 객체 생성을 동시에 하기 때문에 단 한번만 사용될 수 있고, 오직 하나의 객체만 생성할 수 있는 일회용 클래스

: 이름이 없으므로 생성자도 가질 수 없음

: 조상클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용해서 정의하기 때문에 하나의 클래스로 상속받는 동시에 인터페이스를 구현하거나 둘 이상의 인터페이스를 구현할 수 없음

: 이름이 없기 때문에 '외부 클래스명 $숫자.class'의 형식으로 클래스파일명이 결정됨

반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 7 객체지향 프로그래밍 2-2  (0) 2017.07.21
[JAVA] 7 객체지향 프로그래밍 2-1  (0) 2017.07.11
[JAVA] 6 객체지향 프로그래밍1  (0) 2017.07.05
[JAVA] 배열 예제  (0) 2017.07.04
[JAVA] 5 배열 (Array)  (0) 2017.07.03
반응형

           

  JAVA Study






3. package와 import


- 패키지란 클래스의 묶음이다

: 클래스 또는 인터페이스를 포함시킬 수 있음

: 서로 관련된 클래스들끼리 그룹 단위로 묶어놓음으로써 클래스를 효율적으로 관리할 수 있음

: 패키지는 물리적으로 하나의 디렉토리

: 하나의 소스파일에 첫 번째 문장으로 단 한 번의 패키지 선언을 허용

: 모든 클래스는 반드시 하나의 패키지에 속함

: 패키지는 점(.)을 구분자로하여 계층구조로 구성가능

: 클래스 파일(.class)을 포함하는 하나의 디렉토리


- 패키지 선언

package 패키지명;

: 패키지명은 대소문자를 모두 허용하지만 클래스명과 구분하기 위해 소문자를 사용

: 모든 클래스는 반드시 하나의 패키지에 포함되어야 함, 패키지를 선언하지 않을 경우 기본으로 제공되는 'unnamed package'에 속함


- import 문

: 사용하고자 하는 클래스의 패키지를 미리 명시해줌

: 컴파일러에게 소스파일에 사용된 클래스의 패키지에 대한 정보를 제공


- import문 선언

:한 소스파일에 여러 번 선언 가능

import 패키지명.클래스명;

import 패키지명.*; // '*'은 패키지에 속하는 모든 클래스를 의미함


- static import문

: static 멤버를 호출할 때 클래스 이름을 생략할 수 있음

: 특정 클래스의 static멤버를 자주 사용할 때 편리

import static java.lang.Integer.*;  // Integer 클래스의 모든 static메서드


4. 제어자 (modifier)


- 제어자는 클래스, 변수, 메서드 선언부에 함께 사용되어 부가적 의미를 부여


- 접근 제어자와 그 외의 제어자로 구분

: 접근 제어자 - public / protected / default / private

: 그 외 제어자 - static / final / abstract / native / transient / synchronized / volatile / strictfp


- 하나의 대상에 대해 여러 제어자를 조합하여 사용 가능


- 접근 제어자는 한 번에 하나만 선택해서 사용가능


- static ( 클래스의, 공통적인 )
: 클래스변수는 인스턴스에 관계없이 같은 값을 가짐
: 하나의 변수를 모든 인스턴스가 공유
: static이 붙은 멤버변수와 메서드, 초기화 블럭은 인스턴스가 아닌 클래스에 관계된 것이므로 인스턴스를 생성하지 않고 사용 가능
: 인스턴스 메서드와 static 메서드의 근본적인 차이는 메서드 내에서 인스턴스 멤버를 사용하는가의 여부에 있음
: 멤버변수 / 메서드 / 초기화 블럭에서 사용 가능

- final ( 마지막의, 변경될 수 없는 )
: 거의 모든 대상에 사용될 수 있음 ( 클래스 / 메서드 / 멤버변수 / 지역변수 )
: 변수에 사용되면 값을 변경할 수 없는 상수가 됨
: 메서드에 사용되면 오버라이딩을 할 수 없게 됨
: 클래스에 사용되면 자신을 확장하는 자손 클래스를 정의할 수 없음
: 생성자를 이용한 final 멤버 변수의 초기화
- final이 붙은 변수는 상수이므로 일반적으로 선언과 초기화를 동시에 함
- 인스턴스변수의 경우 생성자에서 초기화 되도록 할 수 있음
: 클래스 내에 매개변수를 갖는 생성자를 선언하여, 인스턴스를 생성할 때 final이 붙은 멤버변수를 초기화하는데 필요한 값을 생성자의 매개변수로부터 제공받는 것

- abstract ( 추상의, 미완성의 )
: 메서드의 선언부만 작성하고 실제 수행내용은 구현하지 않음
: 클래스 / 메서드에서 사용 가능
: 클래스 - 클래스 내에 추상 메서드가 선언되어 있음을 의미
: 메서드 - 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알림
: 추상 클래스는 아직 완성되지 않은 메서드가 존재하기 때문에 인스턴스를 생성할 수 없음
: 추상 클래스만으로는 쓸모가 없지만 다른 클래스가 이 클래스를 상속받아서 오버라이딩해 사용함

- 접근 제어자 ( access modifier )
: 멤버, 클래스에 사용되어 해당 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 함
: 클래스 / 멤버변수 / 메서드 / 생성자에서 사용됨
: private - 같은 클래스 내에서만 접근 가능
: default - 같은 패키지 내에서만 접근 가능
: protected - 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근이 가능
: public - 접근 제한 없음
: public > protected > default > private

- 접근 제어자를 이용한 캡슐화
: 접근제어자를 사용하는 이유는 클래스의 내부에 선언된 데이터를 보호하기 위해서이다.
- 외부로부터 데이터 보호
- 외부에 불필요한, 내부적으로만 사용되는 부분을 감추기 위해
: 데이터 감추기 (data hiding) - 데이터가 유효한 값을 유지하도록 또는 비밀번호와 같은 데이터를 외부에서 함부로 변경하지 못하도록 하기 위해 외부로부터의 접근을 제한하는 것 => 객체지향의 캡슐화
: 클래스 내에서만 사용되는, 내부 작업을 위해 임시로 사용되는 멤버변수나 부분작업을 처리하기 위한 메서드 등의 멤버들을 클래스 내부에 감추기 위해

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Time {
    private int hour;    // 접근 제어자를 private으로 하여 외부에서 직접 접근 불가
    private int minute;
    private int second;
 
    public int getHour() {
        return hour;
    }
    public void setHour (int Hour) {
        if (Hour <0 ||  Hour > 23return;
        this.hour = hour;
    }
 
    public int getMinute() {
        return Minute;
    }
    public void setMinute (int minute) {
        if (minute<0 ||  minute> 23return;
        this.minute= minute;
    }
 
    public int getSecond() {
        return second;
    }
    public void setHour (int second) {
        if (second<0 ||  second> 23return;
        this.second= second;
    }
}
cs


- getter 
: get으로 시작하는 메서드는 멤버변수의 값을 반환하는 일
: 멤버변수의 값을 읽는 메서드의 이름을 'get멤버변수 이름'으로 작성

- setter
: set으로 시작하는 메서드는 매개변수에 지정된 값을 검사하여 조건에 맞으면 멤버변수 값을 변경
: 멤버변수의 값을 변경하는 메서드의 이름을 'set멤버변수 이름'으로 작성

- 생성자의 접근 제어자
: 생성자에 접근 제어자를 사용함으로 인스턴스 생성을 제한할 수 있음
: 보통 생성자의 접근제어자는 클래스의 접근제어자와 같지만 다르게 사용할 수 있음
: 생성자가 private인 클래스는 다른 클래스의 조상이 될 수 없다
- 자손클래스의 인스턴스 생성 시 조상클래스의 생성자를 호출해야하는데 private이므로 호출이 불가하기 때문
: 따라서 생성자가 private인 클래스 앞에 final을 붙여 상속할 수 없는 클래스임을 알리는 것이 좋다

- 제어자 조합
: 메서드에 static과 abstract를 함께 사용할 수 없음
- static 메서드는 몸통이 있는 메서드에만 사용할 수 있음
: 클래스에 abstract와 final을 동시에 사용할 수 없음
- 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미, abstract는 상속을 통해서 완성되어야 한다는 의미이기 때문
: abstract메서드의 접근제어자가 private일 수 없음
- abstract메서드는 자손클래스에서 구현해 주어야 하는데 접근제어자가 private이면, 자손클래스에서 접근할 수 없기 때문
: 메서드에 private과 final을 같이 사용할 필요 없음
- 접근 제어자가 private인 메서드는 오버라이딩 될 수 없기 때문, 둘 중 하나만 사용해도 의미 충분히 전달됨

5. 다형성 (polymorphism)


- 상속과 깊은 관계가 있음

- 여러가지 형태를 가질 수 있는 능력을 의미

- 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함으로써 다형성을 구현

: 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하는 것


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Car{
    String color;    
    int door;    
 
    void drive() {    // 운전하는 기능
        System.out.println("drive, Brrr");
    }
    void stop() {    // 멈추는 기능
        System.out.println("stop!!");
    }
 
}
 
class FireEngine extends Car{    //소방차
    void drive() {    // 소방차운전
        System.out.println("drive,fire!!");
    }
}
 
 
class Ambulance extends Car{
    void siren() {    // 사이렌 울리는 기능
        System.out.println("siren!!");
    }
}
 
cs




: 인스턴스 타입과 참조변수 타입이 일치하는 것이 보통이지만 클래스가 서로 상속관계에 있을 경우 조상클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조하도록 하는 것도 가능하다


FireEngine e = new FireEngine();

car c = new FireEngine();       // 조상 타입의 참조변수로 자손 인스턴스를 참조

=> 자손의 인스턴스를 참조하므로 c.drive()의 결과는 drive, fire이 된다.

=> 둘 다 같은 타입의 인스턴스지만 참조변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라짐





반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 7 객체지향 프로그래밍 2-3  (0) 2017.07.22
[JAVA] 7 객체지향 프로그래밍 2-1  (0) 2017.07.11
[JAVA] 6 객체지향 프로그래밍1  (0) 2017.07.05
[JAVA] 배열 예제  (0) 2017.07.04
[JAVA] 5 배열 (Array)  (0) 2017.07.03
반응형

           

  JAVA Study





1. 상속 (inheritance)


- 기존 클래스를 재사용하여 새로운 클래스를 작성하는 것 


- 보다 적은 양의 코드로 새로운 클래스 작성 가능 & 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이


- 새로 작성하고자 하는 클래스 이름 뒤에 상속받고자 하는 클래스의 이름을 키워드 'extends'와 함께 써줌


class child extends parent{

// parent 클래스를 상속받은 child 클래스

}


- 상속해주는 클래스를 조상클래스, 상속 받는 클래스를 자손클래스라고 함

: 조상클래스 - 부모 클래스, 상위클래스, 기반 클래스

: 자손클래스 - 자식 클래스, 하위클래스, 파생된 클래스


- 자손 클래스는 조상 클래스의 모든 멤버를 상속 받음

: child 클래스는 parent 클래스의 모든 멤버들을 포함

: child 클래스에 새로운 코드가 추가되어도 조상인 parent클래스는 아무 영향을 받지 않음

: 자손클래스는 조상 클래스의 모든 멤버를 상속받으므로 항상 조상 클래스보다 같거나 많은 멤버를 갖음


- 생성자와 초기화 블럭은 상속되지 않음, 멤버만 상속


- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많음


class parent { }

class child extends parent { }

class child2 extends parent { }


: child와 child2클래스 모두 parent클래스를 상속받음

: 클래스 간 관계에서 형제관계는 없음

: child와 child2 클래스에 공통적으로 추가되어야 하는 멤버변수나 메서드가 있다면 공통조상인 parent에 작성


class parent { }

class child extends parent { }

class grandchild extends child{ }


: 자손 클래스는 조상 클래스의 모든 멤버를 물려받으므로 grandchild클래스는 child 클래스의 모든 멤버, child클래스의 조상인 parent 클래스로부터 상속받은 멤버까지 상속받게 됨

: grandchild 클래스는 child의 자손이면서 parent의 자손이기도 함

: child클래스는 grandchild클래스의 직접조상, parent 클래스는 grandchild 클래스의 간접 조상이 됨

: parent클래스에 변수를 추가하면 parent를 상속받고 있는 child, grandchild클래스에 변수가 공통적으로 추가됨


- 자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버도 함께 생성되므로 따로 조상클래스의 인스턴스를 생성하지 않아도 조상클래스의 멤버들을 사용할 수 있음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Tv{
    boolean power; //전원상태 on/off
    int channel; //채널
    
    void power(){
        power = !power;
    }
    
    void channelUp(){
        ++channel;
    }
    
    void channelDown(){
        --channel;
    }
    
}
 
class CaptionTv extends Tv{
    boolean caption; //캡션상태 on/off
    void displayCaption (String text){
        if(caption){ //캡션 상태가 on(true)일 때만 text를 보여준다.
            System.out.println(text);
        }
    }
}
 
public class CaptionTvTest{
 
    public static void main(String[] args) {
    
        CaptionTv t = new CaptionTv(); //자손 클래스의 인스턴스를 생성하면 조상클래스의 변수와 메서드를 사용할 수 있다.
        
        t.channel = 10;   // 조상 클래스에서 상속받은 멤버
        t.channelUp();      // 조상 클래스에서 상속받은 멤버 
        System.out.println(t.channel); // channel은 11
        
        t.displayCaption("Hello world1"); // 캡션 상태가 on이 아니므로 출력되지 않음
        t.caption = true;
        t.displayCaption("Hello world2"); // Hello world2 출력
    }
}
cs


- 클래스간의 관계 (포함관계)

클래스 간에 포함관계를 맺어 상속외에 클래스를 재사용하는 방법

: 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 뜻함


1
2
3
4
5
6
7
8
9
10
class Circle{
    int x;    // 원점의 x좌표
    int y;    // 원점의 y좌표
    int r;    // 반지름
}
 
class Point{
    int x;    // x좌표
    int y;    // y좌표
}
cs


: Point 클래스를 재사용해서 Circle 클래스를 작성


1
2
3
4
5
6
7
8
9
class Circle{
    Point c = new Point(); //원점
    int r;    // 반지름
}
 
class Point{
    int x;    // x좌표
    int y;    // y좌표
}
cs
   

- 클래스간의 관계 결정하기

: 상속관계를 맺을 지, 포함관계를 맺을지 결정

- ~은 ~이다. : 상속관계

- ~은 ~을 가지고 있다. : 포함관계

ex. 원은 점이다 / 원은 점을 가지고 있다. => 원은 점을 가지고 있다가 더 자연스러우므로 포함관계를 맺는 것이 옳다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class DrawShap{
    public static void main(String args[]){
        Point[] p = {
                new Point(100,100),
                new Point(140,50),
                new Point(200,100)
        };
        
        Triangle t = new Triangle(p);
        Circle c = new Circle(new Point(150,150),50);
        
        t.draw(); //삼각형을 그린다
        c.draw(); //원을 그린다
    }
}
 
class Shap{
    String color="black";
    void draw(){
        System.out.print("color = "+color);
    }
}
 
class Point{
    int x;
    int y;
    
    Point(int x, int y){
        this.x = x;
        this.y = y;
    }
    Point(){
        this(0,0);
    }
    String getXY(){
        return "("+x+","+y+")"//x와 y의 값을 문자열로 반환
    }
}
 
class Circle extends Shape{
    Point center;
    int r;
    
    Circle(){
        this(new Point(0,0),100); // Circle(Point center,int r)를 호출
    }
    
    Circle(Point Center, int r){
        this.center =center;
        this.r = r;
    }
    
    void draw(){ //원을 그리는 대신에 원의 정보를 출력하도록 했다.
        System.out.print("");
    }
}
 
class Triangle extends Shape {
    Point[] p = new Point[3];
    
    Triangle(Point[] p){
        this.p = p;
    }
    
    void draw(){
         System.out.print("[p1]=("+p[0].getXY()+"), [p2]=("+p[1].getXY()+"), [p3]=("+p[2].getXY()+")");
    }
    
}
 
 
 
 
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package apple2;
 
public class DectTest {
 
    public static void main(String[] args) {
        Deck d = new Deck(); // 카드 한 벌 만듦
        Card c = d.pick(0);  // 섞기 전 제일 위의 카드를 뽑는다.
        System.out.println(c); //뽑은 카드 확인
        
        d.shuffle(); // 카드를 섞음
        c = d.pick(0); // 섞은 후 제일 위의 카드를 뽑는다.
        System.out.println(c); //뽑은 카드 확인
    }
}
 
class Deck{
    final int CARD_NUM =52// 카드의 개수
    Card cardArr[] = new Card[CARD_NUM]; // Card 객체 배열 포함
    
    Deck(){ // Deck의 카드를 초기화
        int i=0;
        
        for(int k=Card.KIND_MAX; k>0; k--){
            for(int n=0; n<Card.NUM_MAX; n++){
                cardArr[i++= new Card(k, n+1);
            }
        }
    }
    
    Card pick(int index){    // 지정된 위치에 있는 카드 하나를 꺼내서 반환
        return cardArr[index];
    }
    
    Card pick(){ // Deck에서 카드하나 선택
        int index = (int)(Math.random() * CARD_NUM);
        return pick(index);
    }
    
    void shuffle(){ // 카드의 순서를 섞는다
        for(int i=0; i<cardArr.length; i++){
            int r = (int)(Math.random() * CARD_NUM);
            
            Card temp = cardArr[i];
            cardArr[i] = cardArr[r];
            cardArr[r] = temp;
        }
    }
    
}
 
class Card{
    static final int KIND_MAX = 4// 카드 무늬의 수
    static final int NUM_MAX = 13// 무늬별 카드 수
    
    static final int SPADE = 4;
    static final int DIAMOND = 3;
    static final int HEART = 2;
    static final int CLOVER = 1;
    
    int kind;
    int number;
    
    Card() {
        this(SPADE,1);
    }
    
    Card(int kind, int number){
        this.kind = kind;
        this.number = number;
    }
    
    public String toString(){
        String[] kinds = {"","CLOVER","HEART","DIAMOND","SPADE"};
        String numbers = "0123456789XJQK"//숫자10은 X로 표현
        
        return "kind : "+kinds[this.kind] + ", number : "+numbers.charAt(this.number);
    }
}
cs



- 단일 상속 (Single inheritance)

: 자바는 단일상속만을 허용한다 -> 하나 이상의 클래스로부터 상속받을 수 없음


- Object 클래스 - 모든 클래스의 조상

: Object 클래스는 모든 클래스 상속계층도의 최상위에 있는 조상클래스

: 다른 크랠스로부터 상속 받지 않는 모든 클래스들은 자동적으로 Object클래스로부터 상속받게 함

: 모든 클래스의 조상이 되는 클래스

: 만일 다른 클래스를 상속받더라도 상속계층도를 따라 조상클래스를 올라가다보면 마지막 최상위 조상은 Object클래스임



2. 오버라이딩 (overriding)


- 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Point {
    int x;
    int y;
 
    String getLocation() {
        return "x : "++ "y : "+y;
    }
}
 
class Point3D extends Point {
    int z;
    
    String getLocation() {
        return "x : "+x+", y : "+y+", z : "+z;
    }
}
cs

 

: Point 클래스의 getLocation() 은 한 점의 x,y좌표를 문자열로 반환하도록 작성되었다.

: 이 두 클래스는 서로 상속관계에 있으므로 Point3D클래스는 Point 클래스로부터 getLocation()을 상속받은 후 자신에 맞게 z축의 좌표를 포함하여 반환하도록 오버라이딩 하였다


- 오버라이딩 조건

: 자손클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와 이름 / 매개변수 / 반환타입이 같아야 한다

: 선언부가 서로 일치해야 함

: 접근 제어자와 예외는 제한된 조건 하에서만 다르게 변경할 수 있음

- 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없음

- 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없음

- 인스턴스메서드를 static메서드로 또는 그 반대로 변경할 수 없음


- 오버로딩 vs 오버라이딩

: 오버로딩 (overloading) - 기존에 없는 새로운 메서드를 정의하는 것(new)

: 오버라이딩(overriding) - 상속받는 메서드의 내용을 변경하는 것(change, modify)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Point {
    int x;
    int y;
 
    String getLocation() {
        return "x : "++ "y : "+y;
    }
}
 
class Point3D extends Point {
    int z;
    
    String getLocation() { //
        return "x : "+x+", y : "+y+", z : "+z;
    }
    String getLocation(int i){ //오버로딩
    }
}
cs



- super

: 자손클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수

: 멤버변수와 지역변수의 이름이 같을 때 this를 붙여서 구별했듯이 상속받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때 super를 붙여서 구별할 수 있음

: 조상 클래스로 상속받은 멤버도 자손 클래스의 멤버이므로 super대신 this를 사용할 수 있음

: 조상 클래스의 멤버와 자손클래스의 멤버가 중복 정의되어 서로 구별해야하는 경우에만 super를 사용하는 것이 좋음

: 모든 인스턴스변수에는 자신이 속한 인스턴스 주소가 지역변수로 저장되는데, 이것이 참조변수인 this와 super의 값이 됨

: static메서드는 인스턴스와 관련없기때문에 super를 사용할 수 없음  (인스턴스에서만 사용할 수 있음)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Point {
    int x;
    int y;
 
    String getLocation() {
        return "x : "++ "y : "+y;
    }
}
 
class Point3D extends Point {
    int z;
    
    String getLocation() { //오버라이딩
        return "x : "+x+", y : "+y+", z : "+z;
        return super.getLocation() + ", z : "+z; //조상 메서드 호출
    }
 
}
cs


: 조상클래스의 메서드의 내용에 추가적으로 작업을 덧붙이는 경우 super를 사용해 조상클래스의 메서드를 포함시키는 것이 좋음 

- 후에 조상 클래스의 메서드가 변경되더라도 변경된 내용이 자손클래스의 메서드에 자동적으로 반영될 것이기 때문


- super()

: 조상 클래스의 생성자를 호출하는데 사용됨

: 자손 클래스의 인스턴스를 생성하면, 자손과 조상의 멤버가 모두 합쳐진 하나의 인스턴스가 생성되는데, 이 때 조상 클래스 멤버의 초기화 작업이 수행되어야 함 -> 자손클래스의 생성자에서 조상 클래스의 생성자를 호출

: Object클래스를 제외한 모든 클래스의 생성자의 첫 줄에서 조상클래스의 생성자를 호출, 그렇지 않으면 컴파일러가 생성자의 첫 줄에 'super();'를 자동적으로 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class PointTest {
    public static void main (String args[]) {
        Point3D p3 = new Point3D(1,2,3);
    }
}
 
class Point {
    int x, y;
    
    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
 
    String getLocation() {
        return "x : "+x+", y : "+y;
    }
}
 
class Point3D extends Point {
    int z;
 
    Point3D(int x, int y, int z) {
        super(x,y);    // 조상클래스 생성자 
       // this.x = x;
       // this.y = y;
        this.z = z;
    }
 
    String getLocation() {
        return "x : "+x+", y : "+y+", z : "+z;
    }
}
 
cs






반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 7 객체지향 프로그래밍 2-3  (0) 2017.07.22
[JAVA] 7 객체지향 프로그래밍 2-2  (0) 2017.07.21
[JAVA] 6 객체지향 프로그래밍1  (0) 2017.07.05
[JAVA] 배열 예제  (0) 2017.07.04
[JAVA] 5 배열 (Array)  (0) 2017.07.03
반응형

           

  JAVA Study





1. 객체지향 언어


- 객체지향의 기본개념 

: 실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이다

: 상속, 캡슐화, 추상화 개념을 중심으로 구체적으로 발전됨


- 객체지향 언어

: 코드의 재사용성이 높다 - 기존코드를 이용하여 새로운 코드 작성이 쉬움

: 코드의 관리가 용이하다 - 코드간의 관계를 이용해 쉽게 코드변경 가능

: 신뢰성이 높은 프로그래밍을 가능하게 한다 - 제어자와 메서드를 이용해 데이터를 보호하고 올바른 값을 유지하게 하며, 코드 중복 제거, 코드 불일치로 인한 오동작 방지

: 객체지향 프로그래밍은 프로그래머에게 거시적 관점에서 설계할 수 있는 능력을 요구



2. 클래스와 객체


- 클래스

: 객체를 정의해 놓은 것

: 객체의 설계도

: 객체를 생성하는데 사용되며


- 객체

: 클래스에 정의된 내용대로 메모리에 생성됨

: 객체의 용도는 객체가 가지고 있는 기능과 속성에 따라 다름


- 먼저 클래스를 작성한 후, 클래스로부터 객체를 생성해 사용한다


- 인스턴스화

: 클래스로부터 객체를 만드는 과정

: 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스라고 함

: 객체는 모든 인스턴스를 대표, 인스턴스는 어떤 클래스에서 생성된 객체인지를 강조하는 보다 구체적 표현


- 객체의 속성과 기능

: 객체는 다수의 속성과 다수의 기능을 가짐 ( 속성과 기능의 집합 )

: 클래스는 객체를 정의한 것이므로, 클래스에 객체의 모든 속성과 기능이 정의되어있음

: 클래스로부터 객체 생성 -> 클래스에 정의된 속성과 기능을 가진 객체가 만들어짐

: 속성 - 멤버변수, 특성, 필드, 상태

: 기능 - 메서드, 함수, 행위


- 인스턴스 생성

: 클래스명 변수명= new 클래스명();   ( ex. Tv t = new Tv(); )

-> Tv 클래스 타입의 참조변수 t 선언& 초기화

-> 인스턴스 속성을 사용하려면 '참조변수.멤버변수'로 작성 ( ex. t.멤버변수 )

: 인스턴스는 오직 참조변수를 통해서만 다룰 수 있음

: 참조변수의 타입은 인스턴스의 타입과 일치해야 함

: 같은 클래스로부터 생성되어도 각 인스턴스의 속성은 서로 다른 값을 유지할 수 있음, 메서드의 내용은 모든 인스턴스에 동일


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Tv{
    // Tv 속성 (멤버변수)
    String color;     //색상
    boolean power;    //전원상태 (on/off)
    int channel;    //채널
 
    // Tv기능 (메서드)
    void power() {
        power = !power;    //Tv를 켜거나 끄는 메서드
    }
    void channelUp() {
        ++channel;        //채널을 높이는 메서드
    }
    void channelDown() {
        --channel;        //채널을 낮추는 메서드
    }
}
 
class TvTest2{
    public static void main(String args[]){
        Tv t1 = new Tv();
        Tv t2 = new Tv();
        
        System.out.println("t1의 channel 값은 : "+t1.channel +"입니다.");    //t1의 channel 값은 : 0
        System.out.println("t2의 channel 값은 : "+t2.channel +"입니다.");    //t2의 channel 값은 : 0
 
        t1.channel = 7//채널 7 저장
        System.out.println("t1의 channel 값은 : "+t1.channel +"입니다.");  //t1의 channel 값은 : 7
        System.out.println("t2의 channel 값은 : "+t2.channel +"입니다.");    //t2의 channel 값은 : 0
        
    }
}
cs


- 객체배열

: 많은 수의 객체를 다룰 때 배열 사용

: 객체 배열안에 객체의 주소 저장, 참조변수를 하나로 묶은 참조변수 배열


- 클래스의 또다른 정의 (프로그래밍적 관점)

: 변수 - 하나의 데이터를 저장할 수 있는공간

: 배열 - 같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간

: 구조체 - 서로 관련된 여러 데이터를 종류에 관계없이 하나의 집합으로 저장할 수 있는 공간

: 클래스 - 데이터와 함수의 결합 (구조체 + 함수)

: 자바와 같은 객체지향언어는 변수(데이터)와 함수를 하나의 클래스에 정의하여 서로 관계 깊은 변수와 함수를 함께 다룰 수 있게 한다



3. 변수와 메서드


- 선언 위치에 따른 변수의 종류

: 클래스 변수 / 인스턴스 변수 / 지역변수

: 변수의 선언된 위치가 변수의 종류를 결정

: 멤버변수를 제외한 나머지는 모두 지역변수

: 멤버변수 중 static이 붙은 것은 클래스변수, 붙지 않은 것은 인스턴스변수


1
2
3
4
5
6
7
8
9
10
11
class Tv{
 
    String color;     // 인스턴스 변수
    static int channel;    // 클래스변수, 공유변수, static변수
 
 
    void method() {
        String color = 0// 지역변수
    }
        
}










cs

: ㄴㅇ라ㅓ

- 인스턴스 변수 

: 클래스영역에 선언

: 클래스의 인스턴스를 생성할 때 만들어짐

: 인스턴스 변수의 값을 읽어 오거나 저장하기 위해서 먼저 인스턴스 생성해야 함

: 독립적 저장공간을 가지므로 서로 다른 값을 가질 수 있음

: 인스턴스마다 고유한 상태를 유지해야 하는 속성의 경우 인스턴스변수로 선언


- 클래스 변수

: 인스턴스 변수 앞에 static을 붙이면 클래스 변수 선언됨

: 모든 인스턴스가 공통된 저장공간을 공유

: 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야 하는 경우 클래스 변수로 선언

: 인스턴스를 생성하지 않고 바로 사용 가능

: 클래스가 메모리에 로딩될 때 생성되어 프로그램이 종료될 때까지 유지

: public을 앞에 붙이면 같은 프로그램 내 어디서나 접근가능한 ' 전역변수 ' 성격을 가짐


- 지역 변수 

: 메서드 내에 선언되어 메서드 내에서만 사용 가능, 메서드 종료 시 소멸

: for문, while문의 블럭 내에 선언된 지역변수는 블럭을 벗어나면 소멸되어 사용 불가


- 메서드

: 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것

: 높은 재사용성 / 중복된 코드 제거 / 프로그램의 구조화

: 선언부와 구현부로 이루어짐

: 메서드 선언부 

- 메서드의 이름, 매개변수의 선언, 반환타입으로 구성  ( ex. int add ( int z, int b) )

: 매개변수 선언 

- 메서드가 작업을 수행하는데 필요한 값을 제공받기 위한 것

- 필요한 값의 개수만큼 변수를 선언하며 구분은 ','로 함

- 선언할 수 있는 매개변수의 개수는 거의 제한이 없지만, 배열이나 참조변수 사용

- 값을 받을 필요가 없다면 괄호안에 아무것도 적지 않음

: 메서드의 이름

- 동사인 경우가 많고, 메서드의 기능을 쉽게 알 수 있도록 함축적이면서 의미있는 이름을 사용

: 반환타입

- 메서드 작업수행 결과인 '반환값'의 타입

- 반환값이 없는 경우 반환타입으로 'void' 작성

: 메서드의 구현부

- 메서드를 호출했을 때 수행될 문장을 넣음

: return문

- 반환타입이 void가 아닌경우, 구현구 안에 'return 반환값;'을 반드시 포함

- 작업 수행 결과를 호출한 메서드로 전달

- 반환타입과 일치하거나 자동 형변환이 가능한 것

- 단 하나의 값만 반환할 수 있음


- 메서드의 호출

: 메서드 정의 후 호출하지 않으면 아무일도 발생하지 않음

: 인자와 매개변수

- 메서드를 호출할 때 괄호안에 지정한 값을 '인자' 또는 '인수'라고 함

- 인자의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야 함

- 인자는 메서드가 호출되면서 매개변수에 대입되므로 , 인자의 타입은 매개변수의 타입과 일치하거나 자동형변환되어야 함

: 메서드의 실행흐름

- 같은 클래스 내의 메서드끼리는 참조변수를 사용하지 않고도 서로 호출이 가능

- static메서드는 같은 클래스 내의 인스턴스 메서드를 호출할 수 없음

- 메서드가 호출되면 지금까지 실행중이던 메서드는 실행을 멈추고 호출된 메서드의 문장이 실행됨


- return문

: 현재 실행중인 메서드를 종료하고 호출한 메서드로 돌아감

: 반환타입이 void가 아닌 경우, 반드시 return문을 작성해야함


- JVM메모리 구조

: method area / heap / call stack

: method aret (메서드 영역)

- 클래스에 대한 정보 저장

: heap

- 인스턴스가 생성되는 공간, 인스턴스 변수들이 생성되는 공간

: call stack or executive stack (호출스택)

- 메서드의 작업에 필요한 메모리 공간 제공

- 메서드가 작업을 마치면 할당된 메모리 공간이 반환되어 비워짐

- 호출스택 제일 상위에 위치하는 메서드가 현재 실행중인 메서드이며 나머지는 대기상태

- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드임


- 기본형 매개변수 

: 변수의 값을 읽기만 할 수 있음


- 참조형 매개변수

: 변수의 값이 저장된 곳이 주소를 알 수 있기 때문에 값을 읽고 변경할 수 있음


- 참조형 반환타입

: 메서드가 '객체의 주소'를 반환


- 재귀호출

: 매서드 내부에서 매서드 자신을 다시 호출하는 것

: 재귀호출하는 메서드를 '재귀메서드'라 함

: 재귀호출만 하게되면 무한히 자기 자신을 호출하기 때문에 조건문을 필수적으로 사용


- 클래스 메서드( static 메서드 ) 와 인스턴스 메서드

: 메서드 앞에 static을 붙이면 클래스 메서드, 붙어있지 않으면 인스턴스 메서드

: 메서드작업 수행 시 인스턴스 변수를 필요로하는 메서드를 인스턴스메서드로 정의, 인스턴스를 생성해야 호출가능

: 인스턴스와 관계 없는 메서드를 클래스 메서드로 정의 


- 클래스 설계 시, 모든 인스턴스에 공통적으로 사용하는 것에 static을 붙임

- 클래스 변수(static변수)는 인스턴스를 생성하지 않아도 사용 가능

- 클래스 메서드(static 메서드)는 인스턴스 변수를 사용할 수 없음

- 메스드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려

- 클래스 멤버가 인스턴스 멤버를 참조, 호출 할 때는 인스턴스를 생성해야 함

- 같은 클래스 내의 메서드는 서로 객체의 생성이나 참조변수 없이 직접호출이 가능하지만 static 메서드는 인스턴스 메서드를 호출할 수 없음

- 인스턴스멤버 간의 호출은 가능, 하나의 인스턴스멤버가 존재한다는 것은 이미 인스턴스가 생성되었다는 의미이기 때문



4. 오버로딩


- 한 클래스 내에 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메서드를 정의할 수 있음

- 한 클래스 내에 같은 이름의 메서드를 여러 개 정희하는 것을 '메서드 오버로딩', '오버로딩(overloading)'이라 함


- 오버로딩 조건

: 메서드 이름이 같아야 함

: 매개변수의 개수 또는 타입이 달라야 함


- 오버로딩의 장점

: 메서드 이름 절약 - 하나의 이름으로 여러개의 메서드를 정의할 수 있음


- 가변인자와 오버로딩

: 가변인자는 '타입...변수명' 과 같은 형식으로 선언

: 가변인자를 매개변수 중 가장 마지막에 선언

: 가변인자가 선언된 메서드를 호출할 때마다 배열이 새로 생성



5. 생성자


- 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드' 


- 인스턴스 변수의 초기화 작업에 주로 사용됨


- 클래스 내에 선언되며, 리턴값이 없음


- 생성자의 이름은 클래스 이름과 같아야 함


- 오버로딩이 가능하므로 하나의 클래스에 여러개의 생성자가 존재할 수 있음


1
2
3
4
5
6
7
8
9
10
class Tv{
    
    Tv() {
        //매개변수 없는 생성자
    }
 
    Tv(int a, String b) {
        //매개변수 있는 
    }        
}
cs


- 모든 클래스에는 반드시 하나 이상의 생성자가 정의되어야 함


- 소스파일(*.java)의 클래스에 생성자가 하나도 정의되지 않은 경우 컴파일러는 자동적으로 기본 생성자를 추가하여 컴파일 함

: 기본생성자 - 매개변수와 내용이 없는 생성자

: 컴파일러가 자동적으로 기본 생성자를 추가하는 경우는 클래스 내에 생성자가 하나도 없을 때 뿐


- 매개변수가 있는 생성자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Tv{
    int channel;
    String brand;    
 
    Tv() {
        //매개변수 없는 생성자
    }
 
    Tv(int a, String b) {
        channel = a;
        brand = b;
    }        
 
}
 
class TvTest{
    public static void maint(String args[]){
        Tv t = new Tv();
        t.channel = 2;
        t.brand = samsung;
 
        Tv t2 = new Tv(8,"LG");
 
    }
}
cs


- 생성자에서 다른 생성자 호출 

: 생성자 간에도 서로 호출이 가능

- 생성자의 이름으로 클래스이름 대신 this를 사용

- 한 생성자에서 다른생성자를 호출할 때는 반드시 첫번째 출에서만 호출이 가능

: 매개변수의 이름과 인스턴스변수 이름이 같을 경우 서로 구별되지 않기때문에 인스턴스 변수이름 앞에 'this.'을 붙인다

- 만약 붙이지 않은 상태로 작성하면 둘 다 지역변수로 간주된다.


- this 

: 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있음

: 모든 인스턴스메서드에 지역변수로 숨겨진 채 존재함


- this(), this(매개변수)

: 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용


- 생성자를 이용한 인스턴스 복사

: 현재 사용 중인 인스턴스와 같은 상태를 갖는 인스턴스를 하나 더 만들고자 할 때 생성자 활용 가능



6. 변수의 초기화


- 변수를 선언하고 처음으로 값을 저장하는 것

: 멤버변수는 초기화를 하지 않아도 자동적으로 변수의 자료형에 맞는 기본값으로 초기화 됨 

  ( 변수 타입 별 기본값 확인하기 http://blog.naver.com/kegljk/221034527671 )

: 지역변수는 사용하기 전에 반드시 초기화 해야 함


- 멤버변수의 초기화 방법

: 명시적 초기화

: 생성자

: 초기화 블럭

- 인스턴스 초기화 블럭 : 인스턴스 변수를 초기화 하는데 사용

- 클래스 초기화 블럭 : 클래스 변수를 초기화 하는데 사용


- 명시적 초기화

: 변수 선언과 동시에 초기화하는 것  ( ex. int age = 20; )


- 초기화 블럭

: 클래스 초기화 블럭

- 클래스 변수의 복잡한 초기화에 사용

- 클래스가 메모리에 처음 로딩될 때 한번만 수행

: 인스턴스 초기화 블럭

- 인스턴스 변수의 복잡한 초기화에 사용

- 인스턴스를 생성할 때마다 수행

- 생성자보다 인스턴스 초기화 블럭이 먼저 수행됨


- 멤버변수의 초기화 시기와 순서

: 클래스변수의 초기화시점

- 클래스가 처음 로딩될 때 단 한번 초기화

: 인스턴스 변수의 초기화 시점

- 인스턴스가 생성될 때마다 각 인스턴스 별로 초기화가 이루어짐

: 클래스변수의 초기화 순서

- 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭

- 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자







반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 7 객체지향 프로그래밍 2-2  (0) 2017.07.21
[JAVA] 7 객체지향 프로그래밍 2-1  (0) 2017.07.11
[JAVA] 배열 예제  (0) 2017.07.04
[JAVA] 5 배열 (Array)  (0) 2017.07.03
[JAVA] 제어구조 예제 6 - while문  (0) 2017.07.02
반응형

           

  JAVA Study





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import java.util.Arrays;
public class tistory {
    public static void main(String[] args) {
        //배열 출력
        int[] score = new int[5];
        int k=1;
        
        score[0= 50;
        score[1= 60;
        score[k+1= 70;
        score[3= 80;
        score[4= 90;
        
        int tmp  = score[k+2+score[4];
        
        for(int i=0; i<score.length; i++){ //score.length는 score배열의 길이값
            System.out.println("score ["+i+"] :"+score[i]); //score[0]~score[4] 의 합
        }
        
        System.out.println("tmp : "+tmp); // score[3] + score[4]의 값
//        System.out.println("score[7] : "+score[7]); //배열 범위를 벗어나므로 오류
        
System.out.println("====================");
        
        //배열의 복사
        int[] arr = new int[5];
        
        for(int i=0; i<arr.length; i++){
            arr[i] = i+1//배열arr에 1~5를 저장한다
        }
        
        System.out.println("[변경전]");
        System.out.println("arr.length:"+arr.length);
        
        for(int i=0;i<arr.length;i++){
            System.out.println("arr["+i+"] : "+arr[i]);
        }
        
        int[] temp = new int[arr.length*2];  // arr배열보다 두배 긴 길이의 temp 배열 생성
        
        for(int i=0; i<arr.length;i++){
            temp[i] = arr[i]; // arr배열의 값들을 temp배열에 저장
        } 
        
        arr = temp; //tmp에 저장된 값들을 arr에 저장
        
        System.out.println("[변경후]");
        System.out.println("arr.length:"+arr.length);
        
        for(int i=0;i<arr.length;i++){
            System.out.println("arr["+i+"] : "+arr[i]);
        }
        
System.out.println("====================");
        
        // 배열 일부 복사
        char[] abc = {'A','B','C','D'};
        char[] num = {'0','1','2','3','4','5','6','7','8','9'};
        System.out.println(abc);
        System.out.println(num);
        
            //배열 abc와 num을 붙여서 하나의 배열(result)로 만듦
        char[] result = new char[abc.length+num.length];
        System.arraycopy(abc,0,result,0,abc.length); 
        System.out.println(result);//ABCD
        
        System.arraycopy(num,0,result,abc.length,num.length);
        System.out.println(result);//ABCD0123456789
        
        System.arraycopy(abc, 0, num, 0, abc.length);
        System.out.println(num);//ABCD456789
        
        System.arraycopy(abc, 0, num, 63);
        System.out.println(num);//ABCD45ABC9
    
System.out.println("====================");
        
        //배열 값 총합과 평균
        int sum = 0;
        float avg = 0f;
        
        int[] score1 = {100,88,100,100,90};
        
        for(int i=0;i<score1.length;i++){
            sum += score1[i];
        }
        avg = sum /(float)score.length;
        
        System.out.println("총점 : "+sum);
        System.out.println("평균 : "+avg);
    
System.out.println("====================");
        
        //최대값 최소값
        int max = score1[0];
        int min = score1[0];
        
        for(int i=1; i<score1.length;i++){
            if(score1[i] >max){
                max = score1[i];
            } else if(score1[i]<min){
                min = score1[i];
            }
        }
        
        System.out.println("최대값 : "+max);
        System.out.println("최소값 : "+min);
System.out.println("====================");
        //섞기
        int[] numArr = new int[10];
        
        for(int i=0; i<numArr.length; i++){
            numArr[i] = i;
            System.out.print(numArr[i]);
        }
        System.out.println();
        
        for(int i=0;i<100; i++){
            int n = (int)(Math.random()*10);
            int tmp1 = numArr[0];
            numArr[0= numArr[n];
            numArr[n] = tmp1;
        }
        
        for(int i=0;i<numArr.length; i++){
            System.out.print(numArr[i]);
        }
        System.out.println();
System.out.println("====================");
        
        //로또번호 생성예제
        int[] ball = new int[45]; //45개 정수를 저장할 수 있는 배열
        
            //배열의 각 요소에 1~45의 값을 저장한다.
        for (int i=0; i<ball.length; i++){
            ball[i] = i+1;
        }
        
        int temp3 =0//두 값을 바꾸는데 사용할 임시변수
        int j=0// 임의 값을 얻어서 저장할 변수
        
            //배열의 i번째 요소와 임의의 요소에 저장된 값을 서로 바꿔서 값을 섞는다.
            //0번재 부터 5번째 요소까지 모두 6개만 바꾼다.
        for (int i=0; i<6; i++){
            j=(int)(Math.random()*45); // 0~44까지 임의의 값
            temp3 = ball[i];
            ball[i] = ball[j];
            ball[j] = temp3;
        }
        
            //배열 ball의 앞에서 부터 6개 요소 출력
        for(int i=0; i<6; i++){
            System.out.println("ball ["+i+"] = "+ball[i]);
        }
        
System.out.println("====================");
        
        //임의의 값으로 배열 채우기
        int[] code = {-4,-1,3,6,11}; //불 연속적 값으로 구성된 배열
        int[] arr4 = new int[10];
        
        for(int i=0; i<arr4.length; i++){
            int tmp4 = (int)(Math.random() * code.length);
            arr4[i] = code[tmp4];
        }
        System.out.println(Arrays.toString(arr4));
System.out.println("====================");
        //정렬하기
        int[] numArr5 = new int[10];
        
        for(int i=0; i<numArr5.length; i++){
            System.out.print(numArr5[i] = (int)(Math.random() *10));
        }
        System.out.println();
        for(int i=0; i<numArr5.length-1; i++){
            boolean changed= false//자리바꿈이 발생했는지 체크
            
            for(int j5=0; j5<numArr5.length-1-i; j5++){
                if(numArr5[j5] > numArr5[j5+1]){ //옆 자리 값이 작으면 서로 바꿈
                    int tmp5 = numArr5[j5];
                    numArr5[j5] = numArr5[j5+1];
                    numArr5[j5+1= tmp5;
                    changed = true//자리바꿈 발생 시 true로 변환
                }
            }
            
            if (!changed) break//자리바꿈 없으면 반복문 벗어남
            
            for(int k5=0; k5<numArr5.length; k5++){
                System.out.print(numArr5[k5]);
            }
            System.out.println();
        }
        
    }
}
 
cs
반응형
반응형

           

  JAVA Study






1. 배열(array) 
 

- 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것


- 저장공간이 연속적으로 배치되어 있음


- 배열의 선언

: 원하는 타입의 변수를 선언하고 대괄호를 붙임 ( ex. int[] arr;  int arr[]; )


- 배열의 생성

: 연산자 'new'와 함께 배열의 타입과 길이 지정 ( ex. int[] arr = new int[5]; )


배열의 요소 : 생성된 배열의 각 저장공간


- 인덱스

: 배열의 요소마다 붙여진 일련번호, 0부터 '배열길이-1'까지 

: 인덱스로 상수 대신 변수나 수식도 사용가능하다

for(int i=0; i<5; i++) {

score[i] = i*10;

 }

: 인덱스 범위를 벗어난 값을 인덱스로 사용하면 실행 시 에러 발생


- 배열의 길이

: 배열의 요소개수, 저장 가능한 공간의 개수

: 양의 정수로 작성해야 함

: 길이가 0인 배열 생성 가능


- 배열이름,length

: JVM이 모든 배열의 길이를 별도로 관리하며, '배열이름.length'를 통해 배열 길이 정보를 얻을 수 있음

: 배열은 생성 후 길이변경이 안되므로 '배열이름.length'는 상수


- 배열 길이 변경

: 배열에 저장공간이 부족할 경우 더 큰 길이의 새로운 배열 생성 후 기존배열의 값을 복사

: 기존 배열길이의 2배 정도의 길이로 생성하는 것이 유용


- 배열의 초기화

: 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화 됨     ( 변수 타입 별 기본값 확인하기 http://keepitupjk.tistory.com/231 )


: 배열의 생성과 초기화를 동시에 한 예

int[] score = new int[] {5,6,7,8,9}; 

int[] score = {5,6,7,8,9};  (new int[] 생략 가능)


: 매개변수로 배열을 받는 메서드를 호출할 경우 'new int[]'를 생략할 수 없음

int add( int[] arr ) { 메서드 내용  }

int result = add ( new int[] {1,2,3,4,5} );


- 배열의 출력

: Arrays.toString(배열이름)' 메서드 사용

int[] Arr = {1,2,3,4,5};

System.out.println( Arrays.toString (Arr) );  ( 타입@주소 형식으로 출력 )


char[] chArr={'a','b','c'};

System.out.printlnArrays.toString (chArr) ); (abc 출력) 


- 배열의 복사

: 기존 배열길이의 두배 긴 배열 생성 후 내용 복사

int [] arr = new int [5];


int[] tmp = new int [arr.length * 2];     (기존 보다 2배 긴 배열 생성)


for(int i=0; i < arr.length; i++) {

tmp [i] = arr[i];    (arr[i]의 값을 tmp[i]에 저장)

}

arr = tmp;    (참조변수 arr이 새로운 배열을 가리키게 함

: System.arraycopy()를 이용해 지정된 범위의 값을 한번에 통째로 복사

System.arraycopy ( arr, 0 , tmp, 0, num.length);   (num[0] 에서 tmp[0]으로 num.length개 만큼 복사)


- 버블정렬 알고리즘 (bubble sort)

: 크기 순으로 배열 정렬

for( int i=0; i<numArr.length-1; i++ ){


changed = false;  // 매 반복마다 changed를 false로 초기화


for( int j=0; j<numArr.length-1-i; j++ ){

if ( numArr[j] > numArr[j+1] ){ // 왼쪽 값이 크면 자리를 바꿈

int tmp = numArr[j];

numArr[j] = numArr[j+1];

numArr[j+1] = tmp;


changed = true; // 자리바꿈 발생 시 true변환

}

}


if (!changed) break; // 자리바꾸면 반복문 탈출


for (int k =0; i<numArr.length; k++) {

System.out.print(numArr[k];  //정렬 결과 출력

System.out.println();

}



2. String배열
 

- String 배열 생성

String[] name = new String[3];


- String 배열 초기화

String[] name = new String[3];

name[0] = "kim";

name[1] = "Lee";

name[2] = "park";


String[] name = new String[]{"kim","Lee","park"};

String[] name = {"kim","Lee","park"};


- 참조형 배열의 경우 객체의 주소를 배열에 저장함


- String 클래스는 char 배열에 메서드를 추가한 것


- String 객체(문자열)는 읽기만 가능, 내용변경 불가


- String 클래스 주요 메서드

 메서드

설명 

char charAt(int index) 

문자열에서 해당 위치(index)에 있는 문자 반환 

 int length()

문자열 길이 반환 

String substring(int from,int to) 

문자열에서 해당범위(from~to바로 앞까지) 문자열 반환 

 boolean equals(String str)

문자열 내용이 같은지 확인, 같으면 true, 다르면 false 

char[] toCharArray() 

문자열을 문자배열(char[])로 변환해서 반환 


- char배열과 String 클래스의 변환

char chArr={'A','B','C'};

String str = new String(chArr);  // char -> String

char[] tmp = str.toCharArray(); // String-> char
 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class tistory {
 
    public static void main(String[] args) {
        
        String  src = "ABCDE";
        
        for(int i=0; i<src.length; i++){
            char ch = src.charAt(i); // src의 i번째 문자를 ch에 저장
            System.out.println("src.charAt("+i+"):" + ch);
        }
 
        // String을 char[]로 변환
        char[] chArr = src.toCharArray();
 
        // char배열(char[])을 출력
        System.out.println(chArr);
    }
}
cs



3. 다차원 배열
 

- 2차원 배열 선언

: 타입[][] 변수이름; int[][] abc;

  int[][] abc = new int[3][5];

: 각 요소에 접근하는 방법은 'abc[행 index] [열 index]'


- 2차원 배열 초기화

: int[][] abc = {{1,2,3,4,5},{10,20,30,40,50},{100,200,300,400,500}};


- for문을 통한 2차원 배열 초기화

for(int i=0; i<abc.length; i++){ // 행 index 값

for(int j=0; j<abc[i].length; j++){ // 열 index 값

abc[i][j] = 10; //모든 값을 10으로 초기화

}

}


- 가변배열

: 다차원 배열 생성 시 전체 배열 차수 중 마지막 차수의 길이를 지정하지 않고, 각기 다른 길이의 배열을 생성함으로 유동적 가변배열을 구성

int[][] score = new int[5][]; // 열의 개수 설정 안함

score[0] = new int[4]; // 행 0번에 열 4개생성

score[1] = new int[3]; // 행 1번에 열 3개생성

score[2] = new int[4]; // 행 2번에 열 4개생성

score[3] = new int[2]; // 행 3번에 열 2개생성

score[4] = new int[1]; // 행 4번에 열 1개생성


int[][] score = {

{1,2,3,4}, 

{1,2,3},

{1,2,3,4},

{1,2},

{1}

};





자바의 정석 저자 강의

- 배열



반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 6 객체지향 프로그래밍1  (0) 2017.07.05
[JAVA] 배열 예제  (0) 2017.07.04
[JAVA] 제어구조 예제 6 - while문  (0) 2017.07.02
[JAVA] 제어구조 예제 5 - for문  (0) 2017.07.01
[JAVA] 제어구조 예제 4 - switch문  (1) 2017.06.30
반응형

           

  JAVA Study





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import java.util.Scanner;
 
public class tistory {
 
    public static void main(String[] args) {
        // while문
        int i=5;
        
        while(i--!=0){ // i를 1씩 감소시켜 0이 아니면 다음 문장 실행
            System.out.println(i+" - I can do it");
        } // i--가 후위형 이므로 조건식이 평가된 후에 i값이 감소 -> 4~0까지 출력
        
        // 카운트 다운
        int j = 11;
        
        System.out.println("카운트다운 시작");
        
        while(j--!=0){
            System.out.println(j);
            
            for(int k=0; k<2_000_000_000;k++){
                ; // 아무 내용 없는 빈 문장
            }
        }
        System.out.println("GAME OVER");
        
        // 사용자가 입력한 숫자 , 각 자리의 합을 구하는 예
        int num = 0, sum = 0;
        System.out.print("숫자를 입력하세요>>");
        
        Scanner scn = new Scanner(System.in);
        String tmp = scn.nextLine();
        num = Integer.parseInt(tmp);
        
        while(num!=0){
            sum +=( num%10); //num을 10으로 나눈 몫을 계속 더해 sum에 저장
            num = num/10// num값 재설정
        }
        System.out.println("각 자리수의 합 : "+sum);
        
        //do-while문
        int input1 = 0, answer1 = 0;
        
        answer1 = (int)(Math.random() * 100+1;
        Scanner scn1 = new Scanner(System.in);
        
        do{
            System.out.println("1과 100사이 정수를 입력하세요>");
            input1 = scn1.nextInt();
            
            if(input1 > answer1){
                System.out.println("더 작은 수로 다시 시도해보세요");
            } else if(input1 < answer1){
                System.out.println("더 큰 수로 다시 시도해보세요");
            }
        } while (input1 != answer1);
            System.out.println("정답입니다.");
        
            
        //break 문
        int s = 0;
        int a = 0;
        
        while (true){
            if(s<100)
                break;
            ++a;
            sum += a;
        }
        
        System.out.println("a="+a);
        System.out.println("sum="+sum);
        
        //continue문
        int menu = 0;
        int number = 0;
        
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.println("(1) square");
            System.out.println("(2) square root");
            System.out.println("(3) log");
            System.out.print("원하는 메뉴(1~3)를 선택하세요.(종료 : 0)");
            
            String temp = scanner.nextLine();
            menu = Integer.parseInt(temp);
            
            if (!(1<=menu && menu <=3)){
                System.out.println("메뉴를 잘못 선택했어요.(종료 : 0)");
                continue
            } else if(menu == 0){
                System.out.println("프로그램을 종료합니다.");
                break;
            }
            
            System.out.println("선택하신 메뉴는 " + menu +"번 입니다.");
        }
    
    }
}
 
cs
반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 배열 예제  (0) 2017.07.04
[JAVA] 5 배열 (Array)  (0) 2017.07.03
[JAVA] 제어구조 예제 5 - for문  (0) 2017.07.01
[JAVA] 제어구조 예제 4 - switch문  (1) 2017.06.30
[JAVA] 제어구조 예제 3 - if문  (0) 2017.06.29
반응형

           

  JAVA Study






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import java.util.Scanner;
 
public class tistory {
 
    public static void main(String[] args) {
        // for문
        for(int i=1; i<=5; i++){
            System.out.print(i); //i의 값 12345 출력
        }
        
        int sum=0;
        for(int i=1; i<=10; i++){
            sum+=i;
        }
        System.out.println(sum); // 1~10까지의 합 출력
        
        // 중첩 for문
        int num=0;
        
        System.out.println("*을 출력할 라인의 수를 입력하세요>");
        
        Scanner scn = new Scanner(System.in);
        int number = scn.nextInt();
        
        for(int i=0; i<number;i++){ // 입력한 라인을 출력하기 위한 for문
            for(int j=0; j<=i; j++){ // *을 반복출력하기 위한 for문
                System.out.print("*");
            }
                System.out.println();
        }
    
        // 구구단 
        for(int i=2; i<10; i++){
            for(int j=2; j<10; j++){
                System.out.println(i+" * "+j+" = "+(i*j));
            }
        }
        
        // 배열
        for(int i=1; i<5; i++){ // 행
            for(int j=1; j<5; j++){ // 열
                 System.out.printf("["+i+","+j+"]");
            }
            System.out.println();
        }
        
        for(int i=1; i<=5; i++){
            for(int j=1;j<=5; j++){
                if (i==j){
                    System.out.printf("["+i+","+j+"]");
                } else {
                    System.out.print("     ");
                }
            }
            System.out.println();
        }
        
        // 향상된 for문
        int[] arr = {1,2,3,4,5};
        int sum1=0;
        
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
        
        for(int tmp : arr){
            System.out.println(tmp);
            sum1+=tmp;
        }
        
        System.out.println("sum1 = "+sum1);
        
    }
}
 
cs
반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 5 배열 (Array)  (0) 2017.07.03
[JAVA] 제어구조 예제 6 - while문  (0) 2017.07.02
[JAVA] 제어구조 예제 4 - switch문  (1) 2017.06.30
[JAVA] 제어구조 예제 3 - if문  (0) 2017.06.29
[JAVA] 제어구조 예제 2  (0) 2017.06.28

+ Recent posts