1. 오버로딩

오버로딩이란?

같은 클래스 내에 하나의 메서드 이름으로 다양한 매개변수를 가진 여러 개의 메서드를 만드는 것이다.

int add(int a) {}
int add(int a, int b) {}
int add(int a, double b) {}

1.1. 오버로딩의 조건

  1. 매서드 이름이 같아야 한다.
  2. 매개변수의 개수 또는 타입이 달라야 한다.
int add(int a, long b) {}
int add(long a, int b) {}

오버로딩의 예로 println이 있다 참고하길 바란다.

1.2. 오버로딩의 장점

  1. 같은 기능을 하는 여러 메서드 들을 하나의 이름으로 만들 수 있다.
  2. 메서드 네이밍 시간을 단축시킬 수 있다.

1.3. 가변 인자와 오버로딩

가변인자란?

매개변수의 개수를 자유자재로 받을 수 있는 것을 말한다.

 

  • 가변인자는 매개변수들 중 가장 마지막에 선언해야 한다.
  • 가변인자는 내부적으로 배열을 사용한다.
  • 가변인자 대신 배열을 사용하면 매개변수가 필수여서 주의해야 한다.
  • 가변인자를 사용하면 오버로딩에 구분이 되지 않아 에러가 발생한다.
int add(int a, int... arg) {}
int add(int... arg) {}

위의 예제는 오버로딩이 구분되지 않는 예제이다.

2. 오버라이딩

오버라이딩이란?

상속받은 메서드의 내용을 변경하는 것이 오버라이딩이다.

class Parent {
    public int get() {
    	...
    }
}


class Child extends Parent {
    public int get() { // 오버라이딩
    	...
    }
}

Parent의 get메서드와 비슷한 기능을 기대할 수 있어 오버라이딩을 사용한다.

2.1. 오버라이딩의 조건

  1. 하위 클래스와 상위 클래스의 메서드 명이 같아야 한다.
  2. 하위 클래스와 상위 클래스의 메서드 매개변수가 같아야 한다.
  3. 하위 클래스와 상위 클래스의 메서드 반환 타입이 같아야 한다.

한마디로 메서드의 선언부가 같아야 오버라이딩이 된다.

2.2. 제한 딘 조건하에 변경 가능한 것

  1. 접근 제어 가는 상위 클래스의 메서드 보다 좁은 번위로 변경 불가
    넓은 범위로 변경이 가능하며 범위 순서는 public > protected > default > private이다.
  2. 상위 클래스의 메서드보다 많은 예외를 선언할 수 없다.
    class Parent {
        public int get() throws IOException, SQL... {}
    }
    
    class Child {
        public int get() throws IOException {}
    }​

2.3. 오버라이딩의 제한

  1. 접근 제어자를 상위 클래스의 메서드 보다 좁은 범위로 변경 불가능하다.
  2. 예외는 상위 클래스의 메서드보다 많이 선언하는 것은 불가능하다.
  3. 인스턴스 메서드를 static 메서드로 또는 static 메서드를 인스턴스 메서드로 변경 불가능하다.

* 상위 클래스에 정의된 static 메서드를 하위 클래스에 똑같은 선언부로 정의 가능하다. 이것은 오버라이딩이 아닌 각 클래스의 static 메서드이다.

3. 오버로딩 & 오버라이딩 정리

오버로딩 : 중복되는 메서드 이름을 이용해 새로운 메서드를 만드는 것

오버라이딩 : 상위 클래스의 메서드를 하위 클래스의 메서드에서 변경하는 것

'개발 언어 > Java' 카테고리의 다른 글

[Java] 변수의 초기화  (0) 2021.08.24
[Java] 생성자  (0) 2021.08.24
[Java] 클래스와 객체  (0) 2021.08.20
[Java] 객체 지향 프로그래밍  (0) 2021.08.20
[Java] 배열  (0) 2021.08.19

1. 클래스

클래스란?

객체를 정의해 놓은 것이며 객체의 설계도 또는 틀이다. 이러한 설계도(클래스)는 여러 객체를 생성하는 데 사용된다.

클래스에는 변수와 메서드로 이루어있으며 변수는 데이터의 정의, 메서드는 특정 작업을 수행하기 위한 명령문의 집합이다.

 

객체의 사전적 의미는 실제로 존재하는 것이다.

객체 지향적 이론에서는 사물과 같은 유형적인 것뿐만 아니라 개념이나 논리와 같은 무형적인 것들도 객체로 간주한다.

 

  • 객체의 정의 : 실제로 존재하는 것, 사물 또는 개념
  • 객체의 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름
  • 유형의 객체 : 책상, 의자, 자동차와 같은 사물
  • 무형의 객체 : 수학 공식, 프로그램 에러와 같은 논리, 개념

2. 클래스와 객체의 관계

제품 설계도와 제품과의 관계와 같다.

제품 설계도에 의해 제품이 만들어지고 객체도 클래스에 의해 만들어진다.

잘 만들어진 하나의 제품 설계도로 여러 제품을 만들듯이 잘 만들어진 하나의 클래스로부터 객체를 생성하면 된다.

3. 객체와 인스턴스

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

인스턴스 : 클래스로부터 만들어진 객체

객체 : 모든 인스턴스들을 대표하는 포괄적인 의미

Date date = new Date(); // 인스턴스화

// date : 인스턴스

4. 객체의 구성 요소 - 속성과 기능

객체는 속성, 기능 두 종류로 구성되며 속성과 기능의 집합니다.

일반적으로 다수의 속성과 다수의 기능을 갖추고 있다.

객체가 가지고 있는 속성과 기능을 그 객체의 멤버(구성원, Member)라고 한다.

 

* 용어

  • 속성 : 멤버 변수, 특성, 필드, 상태
  • 기능 : 메서드, 함수, 행위
// Tv Class

// 속성 : 크기, 길이, 높이, 색상, 볼륨, 채널 등
// 기능 : 켜기, 끄기, 볼륨 높이기, 볼륨 낮추기, 채널 변경하기 등

public class Tv {
    private int size;
    private int width;
    private int height;
    private String color;
    private int channel;
    
    public turnOn() {}
    public turnOff() {}
    public volumeUp() {}
    public volumeDown() {}
    public channelChange() {}
}

5. 인스턴스의 생성과 사용

  1. Tv 클래스 타입의 참조 변수 t 선언 : Tv t
  2. Tv 인스턴스 생성 : new Tv();
  3. 생성된 Tv 인스턴스의 주소를 t에 저장 : Tv t = new Tv();
  4. 멤버 변수 변경 : t.channel = 7;
  5. 메서드 호출 : t.turnOn();

인스턴스는 위와 같이 참조 변수를 통해서만 컨트롤할 수 있다.

5.1. 인스턴스의 생성 구조

5.2. 두 개의 인스턴스

Tv t1 = new Tv(); // Ox100
Tv t2 = new Tv(); // Ox200

t2 = t1; // Ox200에서 Ox100을 참조

둘 이상의 참조 변수로 하나의 인스턴스를 가리킬 수 있지만 여러 개의 인스턴스를 하나의 참조 변수로 담지 못한다.

6. 객체의 배열

객체의 배열은 참조 변수를 하나로 묶은 참조 변수 배열이다.

객체의 배열 안에는 객체의 주소가 저장된다.

Tv[] tvArr = new Tv[3]; // 초기값 null

tvArr[0] = new Tv();
tvArr = {new Tv(), new Tv(), new Tv()};

객체 배열의 구조

7. 클래스의 또 다른 정의

7.1. 데이터와 함수의 결합

데이터 처리를 위한 저장 형태의 발전 과정

하나의 변수에서 여러 개의 같은 타입 변수를 담을 수 있는 배열을 만들고

배열에서 서로 다른 타입의 데이터를 넣을 수 있게 구조체를 만들고

구조체에 함수를 더해 클래스가 만들어진다.

7.2. 클래스 - 사용자 정의 타입 (user defined type)

프로그래머가 사용하기 위해 직접 만드는 Time 클래스 

class Time {
    private int hour;
    
    public setHour(int h) {
        this.hour = h;
    }
}

 

'개발 언어 > Java' 카테고리의 다른 글

[Java] 생성자  (0) 2021.08.24
[Java] 오버로딩과 오버라이딩  (0) 2021.08.24
[Java] 객체 지향 프로그래밍  (0) 2021.08.20
[Java] 배열  (0) 2021.08.19
[Java] 제어문  (0) 2021.08.18
객체 지향 이론의 기본 개념
실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들을 사물 간의 상호작용이다.

객체 지향은 상속, 캡슐화, 추상화 개념을 중심으로 점차 발전해 왔으며 최초의 객체지향 언어는 시뮬라(simula, 1960)이다.

1. 객체 지향 언어

객체 지향 언어는 기존의 프로그래밍 언어와 다른 전혀 새로운것이 아니라 기존의 프로그래밍 언어에 몇 가지 새로운 규칙을 추가하여 발전한 것이다.

객체 지향 프로그래밍(Object-Oriented Programming, OOP)은 컴퓨터 프로그래밍 패러다임 중 하나로 

2. 장점

코드의 재사용성이 높고 유지보수가 용이하다.

  1. 재사용성 : 새로운 코드를 작성할떄 기존의 코드를 이용하여 쉽게 구현한다.
  2. 편의성 : 코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경한다.
  3. 신뢰성 : 제어자와 메서드를 이용하여 데이터를 보호하고 올바른 값을 유지하며, 코드의 중복을 제거하고 코드의 불일치로 인한 오작동을 방지한다.

3. 단점

  1. 처리속도가 느리다.
  2. 객체가 많아지면 용량이 커진다.
  3. 설계 단계에 많은 시간과 노력이 필요하다.

4. 주요 특징 4가지

4.1. 캡슐화 (Encapsulation)

정의 : 캡슐화는 관련이 있는 변수와 함수를 하나의 클래스에 모아 외부에서 쉽게 접근하지 못하도록 하는 것을 말한다.

 

캡슐화의 큰 장점은 정보은닉이다.

외부에서 변수와 객체를 직접 접근하지 못하고 클래스를 통해서 접근할수 있어 데이터를 보호할 수 있고 클래스를 여러 곳에 사용하여 재사용성을 높일 수 있다. 또한 관련 있는 변수나 함수를 클래스에 모아 두기 때문에 코드 관리도 편하며 수정도 용이하다.

그래서 결합도를 낮추고 응집도를 높일수 있다.

4.2. 상속 (Inheritance)

정의 : 부모 클래스에 있는 속성과 기능을 물려받는 것을 말한다.

 

부모 클래스에 있는 변수와 함수를 자식 클래스가 사용할 수 있다. 부모 클래스는 주로 여러 곳에서 사용할 수 있는 공통 클래스로 만들어져서 여러 자식 클래스들에게 속성과 기능을 제공할 수 있다. 또한, 다형성을 통해 부모 클래스를 기반으로 여러 자식 클래스들의 각자의 기능을 구현할 수 있다.

4.3. 다형성 (Polymorphism)

정의 : 하나의 변수와 함수를 다양하게 이용하는 것을 말한다.

 

부모 클래스에 있는 함수를 오버라이딩하여 내가 원하는 기능으로 대체할 수 있으며 하나의 함수명으로 여러 개의 파라미터를 받아 오버로딩하여 다양하게 함수를 이용할 수 있다.

4.4. 추상화 (Astraction)

정의 : 공통된 속성이나 기능을 뽑아내 하나의 클래스로 만드는 것을 말한다.

 

여러 자식 클래스에서 공통으로 사용하는 함수가 있다고 가정한다면, 그 공통 함수는 부모 클래스로 뽑아내 추상화하여 사용할 수 있다. 보통 추상 클래스는 직접 구현하지 않고 구현체(implements)를 따로 두어 기능을 구현한다.

'개발 언어 > Java' 카테고리의 다른 글

[Java] 오버로딩과 오버라이딩  (0) 2021.08.24
[Java] 클래스와 객체  (0) 2021.08.20
[Java] 배열  (0) 2021.08.19
[Java] 제어문  (0) 2021.08.18
[Java] 연산자  (0) 2021.08.18

배열

배열이란?

같은 타입의 여러 변수를 하나로 묶어 다루는 것을 말한다.

// 변수 선언
int score1, score2, score3, score4, score5;

// 배열 선언
int[] score = new int[5];

같은 타입의 변수를 5개 선언하는 것과 배열의 공간을 5개 선언하는 것 두 개가 같은 의미가 될 수 있다.

1. 배열의 선언과 생성

1.1. 배열의 선언

  • 1. int[] score;
  • 2. int score[];

위 두 가지 방식 중 1번을 가장 많이 사용하며 2번의 경우 배열과 기본형이 혼동될 수 있다.

1.2. 배열의 생성

'new' 연산자를 사용하여 생성한다.

// 배열 선언
int[] score;

// 배열 생성
score = new int[5];

배열을 선언하면 메모리에 변수의 저장 공간이 생성된다.

배열을 생성하면 변수의 저장 공간에 배열의 주소 값이 저장된다.

int형의 배열은 기본값으로 배열에 0이 들어간다.

배열의 선언과 생성

2. 배열의 길이와 인덱스

2.1. 배열의 인덱스

  • 배열의 요소(element) : 배열의 각 저장 공간(score[0] ~ score[2])
  • 접근 방법 : 배열의 이름[인덱스 번호] ex) score[0]
  • 저장 방법 : score[0] = 100;
  • 읽는 방법 : int n = score[0];
  • 인덱스에 상수 대신 변수로 사용 가능하다.
  • 배열의 길이를 벗어나는 인덱스를 사용 시 ArrayIndexOutOfBoundsException 에러가 발생한다.
  • 인덱스를 변수로 사용하면 컴파일 시 에러를 파악하지 못하여 실행 중에 에러가 발생한다.

2.2. 배열의 길이

  • 배열의 길이 접근 방법 : 배열.length
  • 배열의 최대 길이 : int의 최댓값, 약 20억
  • 길이가 0인 배열 생성 가능하다.
  • 길이는 요소를 저장할 수 있는 공간의 개수이다.
  • 배열의 길이는 상수이며 변하지 않고 변경할 수도 없다.
// for문을 이용한 배열 접근

int[] list = new int[]{10, 20, 30, 40, 50};	// 배열 선언 및 생성

for(int i = 0; i < list.length; i++) {	// 배열의 길이를 이용한 for문
	System.out.println(list[i]);	// 변수를 이용한 배열 접근
}

2.3. 배열의 길이 변경하기

  1. 더 큰 배열을 생성한다. ex) new int[10];
  2. 기존 배열(new int[5])을 큰 배열에 복사한다.

3. 배열의 초기화

// 변수 선언
int[] score = new int[]{10, 20, 30, 40, 50}; // {}안에 값의 개수에 의해 길이 지정된

int[] score = new int[]{10, 20, 30, 40, 50}; // 생성과 동시에 초기화 가능
int[] score = {10, 20, 30, 40, 50}; // 선언과 동시에 초기화 가능

int[] score;
score = {10, 20, 30, 40, 50}; // 에러 발생
score = new int[]{10, 20, 30, 40, 50}; // 정상

// 메소드 사용
int add(int[] arr) {...}

add(new int[]{10...80}); // 정상
add({10...80}); // 에러

3.1. 길이가 0인 배열

// 길이가 0인 배열 생성
int[] score = new int[0];
int[] score = new int[]{};
int[] score = {};

3.2. 배열의 출력

int[] arr = {10 ... 80};

// 1. 10부터 80까지 한줄씩 출력
for(int i = 0; i < arr.length; i++) {
	System.out.println(arr[i]);
}

// 2. 배열의 주소 출력
System.out.println(arr);

위의 예제 중 1번은 for문을 이용해서 배열의 요소를 읽어오면서 출력하는 예제이고 2번은 arr변수에 저장되어있는 배열의 주소를 출력하는 예제이다.

 

System.out.println은 Char형 배열을 구분자 없이 출력

char[] crr = {'A', 'B', 'C'};

System.out.println(crr); // ABC 출력

4. 배열의 복사

int[] source = new int[5];
int[] target = new int[7];

// source의 길이만큼 for문을 돌면서 target 요소에 값 넣기
for(int i = 0; i < source.length; i++) {
	target[i] = source[i];
}

source = target;

Ox110은 사용하지 않아 JVM의 가비지 컬렉터에 의해 자동으로 메모리에서 제거된다.

 

System.out.arrycopy() 함수를 이용한 복사

System.out.arrycopy(source, 0, target, 0, source.length); // source[0]에서 target[0]으로 source.length개의 데이터 복사

5. 배열의 활용

5.1. 배열의 위치 랜덤 하게 바꾸기

// 배열의 위치 랜덤하게 바꾸기
int[] num = new int[]{10, 20, 30, 40, 50, 60, 70, 80};

for(int i = 0; i < num.length; i++) {
  int n = (int) Math.random() * 10;
  
  int t = num[0]
  num[0] = num[n];
  num[n] = t;
}

5.2. 로또 번호 생성기

int[] num = new int[7];

for(int i = 0; i < num.length; i++) {
  int n = (int) Math.random() * 45;
  
  int t = num[i];
  num[i] = num[n];
  num[n] = t;
}

5.3. 버블 정렬을 이용한 오름 차순

for(int i = 0; i < num.length; i++) {
	for(int j = 0; j < num.length - 1 - i; i++) {
    	if(이전 > 이후) swap();
    }
}

// 총 비교 회수는 num.length가 내림차순 되는 회수이다.
// num의 길이가 5이면

// 1 => 5 - 1 => 4회
// 2 => 5 - 2 => 3회
// 3 => 5 - 3 => 2회
// 4 => 5 - 4 => 1회
// 5 => 5 - 5 => 0회

// 총 10번의 비교를 한다.
// 버블 정렬은 비효율적이나 간단하다.

6. String 배열

6.1. String 배열의 선언과 생성

String[] str = new String[5]; // 기본 값 : null

6.2. String 배열의 초기화

// 초기화 1
String[] names = new String[3];

names[0] = "개";
names[1] = "발";
names[2] = "자";


// 초기화 2
String[] names = new String[]{"개", "발", "자"};
String[] names = {"개", "발", "자"};

String은 클래스라서 객체를 생성해야 하지만 큰따옴표("") 리터럴을 이용하여 생성 가능하다.

// 클래스를 이용한 초기화
names[0] = new String("개");

// 리터럴을 이용한 초기화
names[0] = "개";

참조형 배열의 경우 배열에 값이 들어가지 않고 객체의 주소가 저장된다.

참조형 변수에는 객체가 메모리에 저장된 주소인 4byte의 정수 값(Ox0 ~ Oxffffff) 또는 null이 저장된다.

7. char 배열과 String 클래스

String class는 char 배열에 여러 가지 기능을 추가하여 만든 것이다.

문자열은 변경되지 않고 추가만 되며 변경 시에는 StringBuffer를 이용하여 변경 가능하다.

7.1. String 클래스의 주요 메서드

  • charAt : 문자열에서 특정 위치의 문자 찾기
  • length : 문자열의 길이
  • substring : 문자열에서 from, to로 문자 찾기
  • equals : 대상 문자열과 같은지 비교
  • toCharArray : 문자열을 char배열로 변환

7.2. char 배열과 String 클래스의 변환

// char[] => String
char[] c = {'A', 'B', 'C'};
String s = new String(c); // ABC로 변환


// String => char[]
String s = "ABC";
s.toCharArray(); // {'A', 'B', 'C'}로 변환

8. 커맨드 라인을 통해 입력받기

// 커맨드 라인 입력
> java MainTest abc 123

main(String[] args) {
	args[0]; // "abc";
    args[1]; // "123";
}

매개변수는 공백으로 구분되기 때문에 문자열에 공백이 있다면 큰따옴표("")로 묶어서 사용해야 한다. ex) "Hello World"

main 메서드에 전달된 파라미터가 없을 때 JVM이 null 대신 크기가 0인 배열을 생성하여 매개변수로 전달한다.

9. 다차원 배열

다차원 배열이란? 2차원 이상의 배열을 말한다.

9.1. 2차원 배열의 선언과 인덱스

* 2차원 배열의 선언 방식

  1. int[][] num;
  2. int num[][];
  3. int[] num[];

차원이 늘어날수록 []가 추가된다.

 

* 2차원 배열의 길이

int[][] num = new int[4][3];

num.length => 4

num[0].length => 3

 

* 2차원 배열의 인덱스

생성 방식 : int[][] num = new int[4][3]; // 4행 3열의 배열 생성

접근 방식 : num[1][1]; // 1행 1열 읽기

9.2. 2차원 배열의 초기화

// 2차원 배열 선언 및 생성
int[][] num = new int[][]{{1, 2, 3}, {4, 5, 6}};
int[][] num = {{1, 2, 3}, {4, 5, 6}};

// 보기 좋은 선언

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

9.3. 2차원 배열의 메모리 구성

2차원 배열 메모리 구성

10. 가변 배열

// 가변 배열 선언 및 생성
int[][] num = new int[5][]; // 2번쨰 차원의 길이를 지정하지 않는다.

num[0] = new int[3];
num[1] = new int[4];
num[2] = new int[5];
num[3] = new int[6];
num[4] = new int[7];


// 가변 배열 초기화
int[][] num = {
				{100, 100, 100},
                {100, 100, 100, 100},
                {100, 100, 100, 100, 100}
               };

위의 예제에서 볼 수 있듯이 num배열의 각 요소 안에 들어 있는 배열의 길이가 서로 다르다.

'개발 언어 > Java' 카테고리의 다른 글

[Java] 클래스와 객체  (0) 2021.08.20
[Java] 객체 지향 프로그래밍  (0) 2021.08.20
[Java] 제어문  (0) 2021.08.18
[Java] 연산자  (0) 2021.08.18
[Java] 형변환  (0) 2021.08.18

+ Recent posts