public class Ex03_constructor {
public static void main(String[] args) {
// Test2 tt = new Test2(); 컴파일오류. 인자가 없는 생성자가 없다.
// 생성자가 존재하면 자바는 디폴트 생성자를 만들지 않는다.
Test2 tt = new Test2(10);
tt.print();
}
}
class Test2 {
private int a;
public Test2(int n) { // 관호 안에 인자가 있음.
a = n;
System.out.println("인자가 하나인 생성자...");
}
public void print() {
System.out.println("a: "+a);
}
}
public class Ex02_constructor{
public static void matin(String[] args) {
Test1 ob = new Test1();
// 객체가 생성되고 객체에 필요한 초기화 작업이 이루어짐.
ob.print();
}
}
1) 객체의 메소드 할당 : a 필드가 heap영역에 메모리 할당을 받는다. 2) a 필드는 디폴트값(0)으로 초기화 된다. 3) 생성자 몸체를 실행하여 a 필드는 10으로 초기화 된다. 생성자 몸체는 객체가 생성될 때 한 번만 실행된다.
- 생성자 클래스와 동일한 이름을 가지며 return 타입이 존재하지 않는다. 모든 클래스는 하나이상의 생성자를 가진다. 생성자를 만들지 않으면 자바는 컴파일할 때 아무코드도 없고 매개변수도 없는 디폴트 생성자를 만든다. 생성자는 new 연산자 다음에 호출하며 객체를 생성할 때 초기화를 담당한다. 생성자는 일반 메소드처럼 호출할 수 없다.
class Test1 {
private int a;
public Test1() {
a = 10;
System.out.println("생성자...");
}
public void print() {
System.out.println("a: "+a);
}
}
티스토리에서 게시글 (특히) 제목 쓸 때 왜 자꾸 지워지는지 모르겠다 정말 사소한 것이지만 너무 성가시다;;
public class Ex01_sort {
public static void main(String[] args) {
int []a = {15,10,25,17,33,40};
print("source: ", a);
sort(a);
print("sort: ", a);
}
public static void print(String title, int[] num) {
// print 라는 클래스 메소드를 만듦.
// 배열에 있는 값을 출력할 때 마다 밑에를 쓸 필요가 없어짐!
System.out.print(title);
for(int n : num) {
System.out.print(n+" ");
}
System.out.println();
}
public static void sort(int[] num) {
// 이 클래스 메소드를 통해 배열에 있는 값들을 작은 값부터 큰 순으로 정렬할 수 있다.
boolean b=ture;
int t;
for(int i=1; b; i++) {
// 배열이 정렬이 다 되면 빠져나가기 위함
b = false;
for(int j=0; j<num.length-i; j++){
if(num[j]>num[j+1]){
// j<num.length-i 인 이유 ? 배열은 0부터 시작임. 그리고
// 이 정렬방법은 첫 회전에 배열 0에 제일 작은 값이 들어감.
// 그 이후로는 배열 0에 있는 값은 비교할 필요가 없음. (회전 수가 5, 4, 3, 2, 1로 줄어든다!)
// j가 배열의 크기보다 커지면 나가고 정렬을 종료함
t=num[j]; num[j]=num[j+1]; num[j+1]=t;
b = true;
}
}
}
}
}
레퍼런스 변수 - 기본형을 제외한 나머지 타입으로 주 기억 장치에 저장되어 있는 객체의 주소 값을 가리킨다. - 레퍼런스 변수(자바) 배열참조형, 클래스 참조형, 인터페이스 참조형, enum 참조형 - 변수 자체가 값을 포함하지 않으며 참조 값만을 가진다.
null ? 해당 값을 가진 레퍼런스 변수의 경우에 가리키고 있는 인스턴스가 없다는 것을 의미.
인스턴스 메소드 - 객체를 생성 후에 객체를 이용하여 접근 - 메소드 내에서 인스턴스 변수나 클래스 변수를 바로 접근 가능 - 메소드 내에서 다른 인스턴스 메소드나 클래스 메소드 호출 가능
클래스 메소드 - 리턴 타입 앞에 static 키워드를 붙여서 선언 - 인스턴스 변수나 인스턴스 메소드를 접근하기 위해서는 먼저 객체를 생성해야 함.
재귀 호출 - 메소드 내에서 메소드 자기 자신을 호출하는 방식 - 실행 시간의 관점에서는 처리 속도가 느려 반복문 보다 비효율적 - 종료 조건을 사용하여 재귀 호출을 종료 하도록 한다. - Stack 영역을 사용
메소드 오버로딩 - 한 클래스 내에서 이름이 같은 메소드를 정의 하는 것으로 매개변수의 타입이 다르거나 매개변수의 개수가 달라야 한다. - 메소드 리턴 타입은 오버로딩 구현하는데 아무런 영향을 주지 못함 =============================================
생성자
- new 라는 연산자와 꼭 같이 사용되어 객체를 생성할 때 호출됨 - 객체가 생성되면 생성자의 몸체를 실행해 초기화를 담당한다. - 생성자는 인스턴스 변수의 초기화 및 객체가 생성될 때 실행해야 할 작업을 위해 사용 - 자바의 모든 클래스에는 하나 이상의 생성자가 존재한다. - 생성자는 인수를 가질 수 있으며, 중복 정의가 가능하다.
디폴트 생성자 - 생성자를 정의하지 않는 경우에 컴파일러는 인수도 없으며 아무런 기능도 지니지 않는 생성자를 자동 삽입하는데 이를 디폴트 생성자라 한다.
절차지향 프로그래밍 장점 - 컴퓨터의 처리 방식과 유사하며, 처리 속도가 빠르다. 단점 - 코드의 양이 증가할수록, 재사용성과 유지보수의 어려움이 급격하게 증가 - 대형 프로젝트에 부적합
특징 - 행동(코드) 중심 // 일에따라서 함. - 처리해야 할 명령어를 결정하고, 필요한 데이터 요청 // 데이터를 나중에 요청한다. - Top-Down 방식으로 설계 // 위에서 아래로
=> 따라서 객체지향이 나옴
객체지향 프로그래밍 - 실제 세계를 모델링 하여 소프트웨어를 개발하는 방법 - 메세지를 교환하는 상호작용을 통해 전체 시스템이 운영되는 개념 - 속성, 메소드로 표현
데이터(상태) 중심 - 개발의 편리, 효율성을 높이는데 목적이 있다. - 생산성을 향상 시킬 수 있다. - 프로그램 모듈을 재사용 할 수 있다. - 프로그램의 확장 및 유지 보수가 용이하다.
객체란 ? - 자동차, 컴퓨터, 책 등과 같이 우리 주위에서 손쉽게 접할 수 있는 모든 물리적 사물 또는 실체를 가르키는 말 - 객체는 특성과 행위, 정체성 등 세가지 특징이 있다. 특성(속성)은 해당 객체에 저장되어 있는 정보 하나의 클래스 안에는 단일책임, 서로 관련성있는 데이터와 코드로 구성되어야 한다.
클래스 : 속성과 메소드를 정의하는 일종의 틀 template 이다. 클래스는 객체를 만들기 위해 필요한 속성, 메소드로 구성
클래스로부터 생성된 실체는 '객체' 객체가 일할수있도록 한 것이 '메소드'
추상화 ? 하나의 클래스를 만들 때 저장할 데이터와 실행해야하는 기능을 추출하는 것. 모델링
캡슐화 ? 객체의 속성과 행위를 하나로 묶고, 실제 구현 내용을 외부에 감추어(변경할 수 없게 함) 은닉한다. 데이터를 보호할 수 있다. 이용자가 데이터에 직접 접근하는 것을 차단하므로 객체 내 데이터 및 코드의 손상과 오용을 막고 안전하게 보호할 수 있다. ex ; Tv를 시청하려면 Tv의 동작 원리를 알아야할까? no. 전원버튼만 누르면 tv를 시청할 수 있다.
하나의 클래스에는 한 가지 종류의 기능을 두어야 한다. (단일 책임의 원칙!) => 응집력을 높이기 위함이다.
인스턴스 생성 -> 메모리를 할당받는다. 생성자는 클래스와 이름이 동일함. 생성자는 메모리를 할당할 때만 씀! new 생성자
인스턴스 변수 - 객체에 종속적이므로 객체에서 호출된다.
클래스 변수 - 클래스 변수는 모든 인스턴스들이 공통적인 값을 갖는다. - 일반적으로 객체가 아닌 클래스 이름을 이용하여 외부에서 접근한다.
생성자 - 클래스와 동일한 이름을 가져야 한다. - 객체를 생성하거나 생성된 객체의 초기화를 담당. - 하나의 클래스에는 하나 이상의 생성자가 필요하다.★ (개발자가 만들지않으면 컴파일할때 자바가 알아서 넣어준다.)
클래스 이름은 대문자로 시작하고 자바 API가 제공하는 클래스의 이름과 중복으로 사용하면 안된다.
일반 독립 클래스에 붙이는 접근 제어자 - public - default : 동일한 패키지(동일 폴더) 에서만 사용가능하다.
내부 클래스 - private - protected - 클래스 안에서만 사용 가능
필드의 접근제어자 - private < default(아무 것도 안 붙인 것) 동일한 패키지에서 사용가능 < protected 동일한 패키지에서는 사용가능+ 자식은 패키지가 달라도 접근가능 < public 누구든지 사용가능
class Test13 {
String tti; // 띠를 구하는 것이니까 나중에 결과값은 문자열 // 인스턴스 변수, 필드
public String tti(int year) {
// 인스턴스 메소드. 가인수 매개변수로 년도를 입력 받는다.
// 리턴 타입은 String(문자열)
// 이 입력받은 수를 가지고 띠를 출력할 수 있도록 만들어야함
// 12로 나눈 나머지가 0일 때 원숭이
// 12로 나눈 나머지가 1일 때 닭
// 12로 나눈 나머지가 2일 때 개
// -> 나머지가 1개씩 늘어남에 따라 원숭이 닭 개 돼지 쥐 소 호랑이 토끼 용 뱀 말 양이 나온다.
String []t = new String[] {"원숭이","닭",개","돼지","쥐","소","호랑이","토끼","용","뱀","말","양"};
// 배열의 첫번째를 나타낼 때는 String[0] 이므로
return t[year%12];
}
}
2. 정수를 매개변수로 넘겨받아 정수의 자릿수 구하기
public int numberLen(int n) {
/*
int len=1;
if(n < 0) {
n = -n;
}
while(n>=10) {
n=n/10;
len++;
}
return len;
*/
if( n < 0 ) {
n = -n; // 음수의 경우 양수로 바꿔주고 삼항연산자를 실행
}
return n>=10 ? 1+numberLen(n/10) : 1;
// 10으로 나누었을 때 몫이 1이면 두자리 몫이 2이면 세자리이므로 +1이고
// 재귀호출로 10으로 나누어질때마다 1을 더해준다.
// 한자릿수의 경우 (1~9)는 1로 값을 되돌려준다.
}
3. 서로 다른 3자릿수의 난수 생성하기
public int number3(){
int m1, m2, m3;
m1 = (int)(Math.random()*9)+1; // 1~9 // 100의자리
// Math.random 은 0< Math.random<1 이렇게 수를 생성해 주므로
// 1<Math.random<10
// 1.xx ~ 9.xx 의 임의의 수를 생성하게 한다.
// 이것은 int 형에 저장될 때 정수형으로 저장되므로
// 1~9 사이의 수가 m1에 저장된다. m1은 백의 자리이므로 0이 될 수 없음.
do {
m2 = (int)(Math.random()*10); // 0~9
} while(m1 == m2);
// m2는 십의 자리이므로 0이 와도 된다. 하지만 서로 다른 수로 구성해야 하므로
// m1에서 생성된 수와 같으면 안된다.
do {
m3 = (int)(Math.random()*10); // 0~9
} while(m1 == m3 || m2 == m3);
// m3는 일의 자리이므로 0이 와도 된다. 하지만 서로 다른 수로 구성해야 하므로
// m1과 m2에서 생성된 수와 같으면 안된다.
return m1*100 + m2*10 + m3;
}
}
잘 만들었는지 확인해보자
public class Ex13 {
public static void main(String[] args) {
Test13 ob = new Test13();
System.out.println(ob.tti(2021));
System.out.println(ob.numberLen(345));
System.out.println(ob.numberLen(-100));
System.out.println(ob.number3());
}
}
※ 지금은 배우고 있는 중이라서 이렇게 짰지만 실무에서는 한 개의 클래스는 한 개의 기능만을 수행해야한다.
public static void main(String[] args) {
/*
Test12 ob;
ob.a=10; // 컴파일 오류. ob가 초기화가 되어 있지 않음.
*/
/*
Test12 ob=null; // null로 초기화. null은 메모리가 할당되지 않은 상태
// ob.a=10; // 런타임오류 : NullPointerException
ob=new Test12();
ob.a=10;
*/
// 객체 배열
Test12 []tt=new Test12[5]; // Test12 객체를 5개 저장 할 수 있는 배열
// 즉, 객체를 저장할 수 있는 배열 5개를 만들거야 라고 선언만 한 상태!!!!
// 각 개체의 메모리가 할당 된 것은 아님.
// 할당은 생성자를 호출할 경우에만 메모리가 할당됨.
// Test12 t1=null, t2=null, t3=null, t4=null, t5=null; 과 유사
/*
// 런타임 오류
// NullPointerException
tt[0].a = 10;
tt[0].print();
*/
// 객체 배열의 메모리 할당
for(int i=0; i<tt.length; i++) {
tt[i] = new Test12();
}
// ★★★ 객체 배열은 하나씩 꼭 new 클래스명(); 으로 메모리를 할당 받아야 한다.
tt[0].a = 10;
tt[0].print();
}
}
class Test12 {
int a;
int b;
public void print() {
System.out.println(a+":"+b);
}
}
// 비정형인자
public class Ex11_method {
public static void main(String[] args) {
Test11 t = new Test11();
int s1 = t.sum(1,2,3,4,5);
System.out.println(s1);
int s2 = t.sum(1,2,3);
System.out.println(s2);
}
}
class Test11 {
public int sum(int ...args) {
int s=0;
for(int n : args) {
s+=n;
}
/*
for (int i=0; i<args.length; i++){
s+=args[i];
}
*/
return s;
}
}
비정형 인자는 가인수에 ...args 를 넣으면 메인 클래스에서 받은 실인수의 갯수만큼 받는다.