main()안의 arguments넣기
논리오류/ 구문오류
구문오류: 컴파일러가 컴파일하면서 알아서 잡아준다. 따라서 오류를 발견하기 쉽고 처리시간은 짧게 걸린다.
논리오류: 개발자가 오류를 잡아야해서 오류를 발견하고 처리하는 시간이 오래걸린다.(안좋게는 멘탈도 안좋아짐)
배열 항목 반복을 위한 향상된 for 문(range base for loop)
for문을 사용하게 되면 인덱스 연산후에 사용하려고 할때 인덱스 밖에 존재하지 않는 데이터를 참조하는 논리 오류를 범할 수 있다. 이러한 논리 오류는 발견하기 어려우므로 구문오류로 바꿔서 컴파일러를 통해 오류를 발견할 수도 있다.
향상된 for문
1. 항상 배열 전체를 순회하도록 한다.
2. 현재 값이 배열에서 존재하는 위치를 알 수 없다.
3. 인덱스를 통한 논리오류가 발생할 일이 없다.
int [] arr2 = {80,90,96,100,22};
for(int i=0;i<arr2.length;i++) {
int idx = i+3;
//확인을 해봐야함
if(0<=idx&&idx<arr2.length) {
//인덱스 오류가 생길수 있음
System.out.println(arr2[i+3]);
}
}
//인덱스 밖의 것을 보지 않기 때문에 논리오류를 만들일이 없다.
for(int value:arr2) {
System.out.println(value);
}
main메소드의 String의 용도
java를 실행할때 같이 전달되는 매개변수들을 받아오는 문자열이다.
Enum타입
요일을 구분하는 코드를 숫자로만 switch문을 구성한다고 해보자. 그러면 주석이 달려 있지않다면 다른 사람이 봤을 때 이코드가 뭘 표현하는 건지 구별하기힘들다. 이럴때 지정된 변수에 다른 값을 입력해서 논리 오류를 범할 수있다. 그래 이전에는 final로 상수화해서 의미를 묘사한 변수명을 통해 구분했다. 이제는 Enum타입으로 구성하면 심볼릭 상수를 쉽게 구현할 수 있다.
public enum Week {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
//상수화 하면 논리오류를 범하지 않을 수 있다.
//심볼릭 상수
final int MONDAY = 0;
final int TUESDAY = 1;
// MONDAY = 3;//논리오류
Week week = Week.MONDAY;
//문자열 monday를 week타입에 관한걸로 바꿀수 있어야함
String ageSTR = "35";
int age = Integer.parseInt(ageSTR);
week = Week.valueOf("MONDAY");//Enum타입으로 타입을 변환한다.
// int week =0;//구문오류
//이제 case에 숫자 쓰지 않고 문자로~
switch(week) {
case MONDAY://월
System.out.println("월요일 ->"+week);
break;
case TUESDAY://화
break;
case WEDNESDAY://수
break;
case THURSDAY://목
break;
case FRIDAY://금
break;
case SATURDAY:
break;
case SUNDAY:
break;
}
열거 타입 변수에는 열거 상수를 입력 가능하다. 열거타입.열거상수형태, null도 입력가능
특정 열거 상수인지 비교할 때는 ==과 != 연산자를 사용한다.
Week today - Week.SUNDAY;
클래스
객체
물리적으로 존재하거나 개념적인 것 중에 다른 것과 식별 가능한 것을 말한다. (속성 + 동작) -> (필드 + 메소드)
객체간의 상호작용은 메소드로 하고 필드는 캡슐화를 위해 감춰져있다. -> 메소드를 통해 필드에 접근가능하다.
객체 간의 관계
집합관계 : 객체들의 조합으로 하나의 객체가 구현되는것, 완성품과 부품의 관계
사용관계 : 다른 객체의 필드를 읽고 변경하거나 메소드를 호출하는 관계
상속관계 : 부모와 자식관계, 부모가 가진 것을 사용하는 것으로 부모를 복사해서 사용한다.
객체 지향 프로그래밍의 특징
캡슐화
누군가 접근해서 강제 변경해서 논리오류가 생기는 것을 막는다. - > 접근제한자를 통해
상속
class와 class 사이에 겹치는 코드들이 존재 할 수 있다. 이때는 상속을 해주면 부모의 코드를 자식이 쓰도록 재사용이 가능하다.
다형성
사용법은 동일하지만 결과가 다양하게 나오는 성질을 말한다. -> 메소드 오버로딩
객체와 클래스
클래스는 객체생성을 위한 설계도이다. 첫문자는 대문자로 하고 첫문자는 숫자가 될수 없고, 특수 문자 중 $ , _ 를포함할 수 있다.
클래스의 두가지 용도
라이브러리 클래스 : 실행할 수 없으며 다른 클래스에서 이용하는 클래스 ->JAR
실행 클래스 : main() 메소드를 가지고 있는 실행 가능한 클래스
객체는 "new 클래스()"를 통해 인스턴스화한 결과이다. 객체는 인스턴스라고도 한다. 객체가 생성될때는 자동으로 기본값 0, null로 초기화된다.
클래스안의 클래스
아래와 같이 A클래스 안에 B클래스를 선언해준 경우 B클래스의 시스템 내부적 이름은 A$B이다.
class A{
class B{
}
}
필드 사용
정적변수는 static함수 안에서만 쓸수 있고 일반 변수는 static함수 안에서 사용할 수 없다. 일반함수 안에서는 전부 사용할 수 있다.
class ex{
int a;//멤버변수
static int b;//정적변수//외부에 선언되어있다.
// 일반멤버메소드
public void func() {
// 일반멤버 메소드 또는 멤버필드를 사용할 수있음
// 정적 메소드 또는 정적 변수 사용할 수 있음
int a = 10;
a = a +10;//지역변수
this.a=this.a+100;//멤버변수
}
//정적 메소드 //외부에 선언되어잇다
public static void func1() {
// 정적 메소드 또는 정적 변수만을 사용할 수 있음
// this.a=10;//에러 static은 클래스에 관련되어있기때문에 객체와 관련된 애들은 쓸수 없다.
}
}
Enum은 참조타입이다. 기본타입 8가지를 제외한 나머지는 참조타입이라고 보면 된다.
생성자
생성자는 객체를 생성할때 객체 안의 필드들을 초기화 시켜줄때 사용한다.
기본생성자
기본생성자는 개발자가 생성자를 만들지 않으면 컴파일러가 자동으로 생성해서 필드를 기본값인 0이나 null로 초기화 해준다. 하지만 필드가 선언시 초기화 되어있다면 그 초기화값으로 대입해서 객체를 생성한다. 여기서 객체에 이미 생성되어있는 변수에 대입하는 것이기 때문에 이전에 함수와 같이 { .... } 이런식의 대입은 초기화방법이기에 불가능하다.
생성자를 쓰는 이유 : 객체끼리 상호작용을 할 때에는 메소드를 가지고 상호작용하게 된다. 누군가 내 객체에 들어와서 변수를 변경하고 나가는 일이 없도록 하기 위해서 변수는 감추도록 한다. 그리고 메소드 호출을 통해서만 조작이 가능하도록하여 캡슐화를 유지한다.
변수 선언
private
같은 클래스 내에서만 사용
protected
부모자식간에만 사용
public
공개 되어 있어 누구나 사용가능하다.
default(아무것도 안씀)
동일한 패키지의 누구나 사용가능
오버로딩
같은 기능을 하는 함수가 인자만 다르게 생성되어 있는 것을 말한다.
함수명은 같고 매개변수의 갯수를 달리해서 구성한다. - > 인자 갯수로 함수명으로 치기 때문에 다르게 인식한다.
생성자도 오버로딩이 가능하다. 생성자의 매개변수만 달리해서 오버로딩할 수 있다.
생성자 this()
this()는 매개변수가 다른 생성자를 불러올때 사용한다. this()는 첫줄에 나와야하고 생성자가 여러개 일때는 this()를 쓸라면 매개변수가 가장 많은 쪽으로 넘겨주는 것이 효율적이다.
메소드 호출
객체 내부에서는 메소드명만으로 호출가능하고 외부에서는 참조변수.함수명으로 호출가능하다.
가변길이 매개변수
함수에 매개변수의 갯수를 지정하지 않고 받아오는 대로 사용하는 방법도 있다. 아래 코드에서는 values라는 매개변수를 배열처럼 사용한다.
int sum(int ...values) {
int sum = 0;
for(int i=0;i<values.length;i++) {
sum+=values[i];
}
return sum;
}
인스턴스 멤버
인스턴스 멤버 - 객체를 생성해야만 사용할 수 있는 필드
정적 멤버 - 클래스만으로 사용할 수있는 필드
메소드와 객체
메소드는 객체에 포함되지 않는다. 메소드는 메모리의 효율을 위해 메소드 영역에 두고 공유에서 사용하면서 객체없이는 사용 못하도록 제한을 걸어둔 것이다.
메소드 역할
1. 동작 -> 클래스 내부에서 행해져도 된다고 해놓은 행위
2. 속성 읽기/쓰기 -> getter/setter
getter/ setter 함수
getter setter 메소드에서 객체 자기자신의 필드값을 리턴하거나 설정할때 this라는 키워드를 사용한다.
public int getSpeed() {
return speed;
}
this는 객체 자기자신을 가리키는 말인데 this는 어디서 온걸까?
public int getSpeed(final Car this) {
return speed;
}
참조변수명.메소드명()으로 함수를 호출하면 객체 본인(this)를 매개변수로 넣어 보낸다. 실제 매개변수를 생략해놓아도 위와같이 final Car this라는 자기자신을 가리키는 객체가 넘어가게 된다.
car2.getSpeed();
정적멤버
정적멤버는 메소드 영역의 클래스에 고정적으로 위치하는 멤버이다. 객체마다 공용적으로 쓰일 필드들을 정적으로 선언한다.
정적블록
클래스가 로딩될때 호출되면서 정적 멤버를 초기화시켜준다.
static{
.....
}
'JAVA공부(이것이 자바다)' 카테고리의 다른 글
상속 (0) | 2023.05.30 |
---|---|
클래스 이어서 (0) | 2023.05.29 |
java의 참조타입 (0) | 2023.05.25 |
java의 연산자와 조건문 반복문 (0) | 2023.05.24 |
java의 변수 (0) | 2023.05.23 |