|
자바 언어 평가과제(1장 ~ 11장)
자바란?
이식성이 높은 객체 지향 언어
메모리를 자동으로 관리해줌
이식성이 높기 때문에 다양한 애플리케이션을 개발할 수 있다.
멀티 스레드를 쉽게 구현할 수 있음
동적 로딩 지원
자바에서 주석 처리 방법
// ==> 행 주석
/* ~ */ ==> 범위 주석
변수
변수란 하나의 값을 저장할 수 있는 메모리 공간
변수 작성 규칙
첫 번째 글자는 문자거나 ‘$’, ‘_’여야 하고 숫자로는 시작할 수 없음(필수)
영어의 대문자와 소문자가 구분된다.(필수)
첫 문자는 영어 소문자로 시작하지만 뒤에 다른 단어가 붙을 경우에는 뒤에 붙은 다른 단어의 첫 자를 대문다로 쓴다.(관례)
문자 수(길이)의 제한은 없음
자바 예약어는 사용할 수 없음(필수)
리터럴
정수 리터럴, 실수 리터럴, 문자 리터럴, 문자열 리터럴, 논리 리터럴
int a = 365;
double bb = 365d;
float b = 365.0f; // 리터럴 접미사 f를 붙인다.
long c= 365L; // 롱타입 정수를 의미하는 리터럴 접미사 L을 붙인다.
// 리터럴 접미사는 대문자 소문자 관계없이 사용가능
String d = "강호동"; // 문자열 리터럴은 쌍따옴표로 둘러 싼다.
char e = 'A'; // 문자 리터럴은 홑따옴표로 둘러 싸고 당연히 한글자만 들어간다.
boolean f = true; // or false; 불리언(논리) 리터럴은 예약어인 true, false를 사용한다.
산술연산자
int a = 10;
int b = 20;
System.out.println(a+b);
System.out.println(10+20);
System.out.println(a+20);
3개의 연산 결과는 모두 30으로 같게 나온다.
연산자중 ‘/’ 나누기를 가장 주의 해야한다.
System.out.println(5/2);
// int/int ===> int – 자바는 정수랑 정수를 나누면 정수만 나온다 (소수점이 날아감)
System.out.println(5.0/2);
// double/int ===> double - 나눌때에 소수점이 필요한 경우 한쪽을 double로 바꿔준다
System.out.println(a/b);
// int/int ===> int
System.out.println((double)a/b);
// double/int ===> double int값 앞에 (double)를 붙여주면 소수점까지 출력된다.
(float와 double 두개가 소수점까지 출력 가능)
byte < short = char < int < long < float < double
부호연산자
int a = 127; // 양수
int b = -a; // a변수의 부호를 바꿔 b에 대입
int c = +a; // a변수 앞에 +는 붙지 않기 때문에 의미 없음
문자열의 결합(숫자+문자열, 문자열+숫자)
System.out.println("안녕" +7); - 결과는 안녕7
System.out.println(7+ "안녕"); - 결과는 7안녕
System.out.println("안녕"+3+4); - 결과는 안녕34
System.out.println(3+4+"안녕"); - 결과는 7안녕
숫자가 앞에 있는지 뒤에 있는지에 따라 결과값이 달라질수 있으니 숫자의 위치에 주의 하고 필요하다면 괄호를 사용하여 먼저 연산되도록 한다.
비교연산자 ( ==, !=, >, >=, <, <=, instanceof)
== 값이 같은지 확인
!= 값이 다른지 확인
> 값이 더 큰지 확인
>= 값이 크거나 같은지 확인
< 값이 더 작은지 확인
<= 값이 작거나 같은지 확인
2항 논리연산 ( &(and), |(or), &&(and), ||(or) )
&(한개)와 &&(두개)의 차이점은 두개짜리를 쓸경우에는 쓸데없는 연산은 실행하지 않는다.
3항 연산자 - (조건)?A:B;
조건이 true라면 A를 취하고, 그렇지 않다면 B를 취한다.
if 대신 3항 연산자를 사용할 경우에는 코딩 줄수가 줄어든다.
int age = 17;
if(age >= 18) {
System.out.println("술 판매 가능");
} else {
System.out.println("미성년자 술 판매금지");
}
위의 식을 3항 연산자로 변환하면
System.out.println((age >= 18)? "술 판매 가능" : "미성년자 술 판매금지");
로 줄이는게 가능하다.
논리의 부정 !
boolean isMan = false;
isMan = !isMan;
System.out.println(isMan);
의 결과는 true가 나온다
이용자에게 값을 입력 받는 창을 띄우기 위한 공식
int pages = Integer.parseInt(JOptionPane.showInputDialog("창에 띄울 문구"))
for문
#####
#####
#####
#####
#####
위의 결과를 만들어 낼수있는 중첩 for문
for(int i = 0; i < 5; i++) {
System.out.println("#####");
}
이 식은 ##### 이걸 5번 반복하여 쌓는 형식임
# 을 한개만 사용하여 for문으로 같은 결과를 만드는법
중첩 for문을 사용하기
for(int i = 0; i < 5; i++) {
for(int j = 0; j <5; j++) {
System.out.print("#");
}
System.out.println();
}
print만 사용할 경우에는 줄을 바꾸지 않음
println를 사용하면 줄을 바꿔서 출력됨
# 을 피라미드 형식과 역피라미드 형식으로 쌓기
피라미드 형식
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++) {
System.out.print("#");
}
System.out.println();
역피마리드 형식
for(int i = 1; i <=5; i++) {
for(int j = i; j <=5; j++) {
System.out.print("#");
}
System.out.println();
}
public class TestNull {
public static void main(String[] args) {
int[] intval = null; // 배열변수의 이름은 정했지만 메모리는 할당안된 상태
intval = new int[10]; //배열 10개를 정수형으로 만들어 기본값을 저장함.
System.out.println(intval); // 정수 10개가 들어있는 첫머리 주소
System.out.println(intval[0]); // intval의 0번째 값을 가져와라
// 김아무개라는 값을 가지는 힙영역의 주소를 name에 넣어 준다.
// name라는 변수는 스택영역에 있다.
String name = "김아무개";
// 힙영역을 활용해야 하는 성질 String
– 왜냐하면 얼만큼의 용량을 차지하는지 모르기 때문에
String 이름 = "김아무개"; // 이미 만들어진 string객체 김아무개를 재사용
System.out.println(name.hashCode());
System.out.println(이름.hashCode());
System.out.println(name == 이름);
// intval[0] = 10;
// System.out.println(intval[0]);
}
}
타입 별 항목의 기본값
기본 타입(정수)
byte[] 0
char[] ' ' - 안에 띄어쓰기한 공백이 초기값임
short[] 0
int[] 0
long[] 0L
기본 타입(실수)
float[] 0.0f
double[] 0.0
기본 타입(논리)
boolean[] false
참조 타입
클래스[] null
인터페이스[] null
코드로 배열의 길이를 얻는법
배열변수.length;
int[] intArray = {10, 20, 30};
int num intArray.lenrth;
주의할점은 배열의 길이는 읽기 전용이기때문에 값을 정해줄수 없음 고로
intArray.length = 10; 이건 잘못된 코드임
배열은 한번 생성하면 크기 변경이 불가능함으로
더 많은 저장 공간이 필요하다면 보다 큰 배열을 생성한뒤 이전 배열로부터
항목 값들을 복사해서 사용해야 한다.
배열 복사 방법
1. for문 사용
2. System.arrayCopy() 메소드 이용
3. Arrays 클래스 이용
객체 표현 양식 - 정확하게 아래 메소드의 선언줄과 일치하게 만들어야함
왜냐하면 자바의 최고 조상 Object가 가지고 있는 메소드를 수정해서 사용하는
형식이기 때문이다 – 오버라이딩 이어서 정확하게 일치 되어야만 한다.
public String toString() {
// 객체의 정보를 리턴하기 위한 표현방식
return name + "," + juminNo + "," + address + "," + phoneNumber;
데이타베이스 한 레코드의 정보를 객체로 만들기 위한 툴 ==> VO 라고 함
VO(Value Object), DTO(Date Transfer Object), Bean
데이타베이스를 아무나 접근하지 못하게 하려면 private 를 사용한다.
생성 메소드를 만들지 않는다 ==> 기본 생성자만 사용한다.
값을 얻어 오게 하는 메소드 ==> getter 메소드
값을 넣기 위한 메소드 ==> setter
각각의 필드에 getter과 setter를 만들어야 한다.
예시)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
관리자용 메소드와 가입자용 메소드를 분리
예시)
// 관리자용 메소드
public void setJoinDate(Date joinDate) {
this.joinDate = joinDate;
}
// 가입자용 메소드
public void setJoinDate() {
Date date = new Date(System.currentTimeMillis());
this.joinDate = date;
}
Getter
- 필드의 값을 리턴하는 역할(필요할 경우 필드 값 제공)
- getField() 또는 isField() 메소드
- 필드 타입이 boolean 일 경우에 isField() 사용
Setter
- 외부에서 주어진 값을 필드 값으로 수정 (필요할 경우 외부의 값을 유효성 검사)
- 매게 변수 타입은 필드 타입과 동일함
package sec12.exam03_import.mycompany;
import sec12.exam03_import.hankook.*;
// 패키지.*; - 이 패키지안에 있는 모든 클래스를 가져와서 쓴다
import sec12.exam03_import.hyndai.Engine;
import sec12.exam03_import.kumho.*;
public class Car {
Engine engine = new Engine();
SnowTire tire1 = new SnowTire();
BigWidthTire tire2 = new BigWidthTire();
sec12.exam03_import.hankook.Tire tire3 = new sec12.exam03_import.hankook.Tire();
sec12.exam03_import.kumho.Tire tire4 = new sec12.exam03_import.kumho.Tire();\
// 서로 다른 패키지 안에 같은 명의 객체가 있을 경우 다시 한번 import 해서 객체를 지정해준다.
}
// 싱글톤 만드는 3가지 조건
public class ShopService {
// private static 으로 객체를 만든다.
// private로 객체를 생성할 경우에는 해당 클래스에서만 사용이 가능하고
// 다른 클래스에서 사용이 불가능하다.
private static ShopService singleton = new ShopService();
// 기본생성자 폐쇄 - 자신 말고는 다른쪽에서 호출 안되게 막는다.
private ShopService() {}
// 유일한 객체를 필요한 곳에 제공할수있는 메소드를 static 으로 만든다
public static ShopService getInstance() {
return singleton;
}
}
public class PrinterExample {
public static void main(String[] args) {
Printer printer = new Printer();
printer.println(10);
printer.println(true);
printer.println(5.7);
// 5.7f 가 아니라 5.7이므로 타입은 double 타입이다.
printer.println("홍길동");
}
}
위의 코드에서 printer.println(10); 이부분의 10을 바이트 타입으로 변경할 수있다.
Printer printer = new Printer();
byte x = 10;
printer.println(x);
이런 형식으로 코딩하면 10의 값을 바이트 타입으로 변경 가능
// 바이트타입이 없으면 바이트 타입이 promotion
조상클래스와 자손 클래스
조상클래스
package org;
// 조상클래스 extends Object가 생략되어 있다.
public class Tire {
public String companny;
public float inch;
public boolean isThick;
// 생성메소드는 상속이 되지 않는다.
public Tire() {
this.inch = 18;
}
public Tire(String companny) {
this();
this.companny = companny;
}
// 생성메소드, getters(), setters() 생략
@Override // 객체 표현 양식
public String toString() {
return "Tire [companny=" + companny + ", inch=" + inch + ", isThick=" + isThick + "]";
}
}
자손클래스
package org;
public class TestOfTire {
public static void main(String[] args) {
Tire 앞오른쪽타이어 = new KumhoTire();
Tire 앞왼쪽타이어 = new KumhoTire();
Tire 뒤오른쪽타이어 = new HankookTire();
Tire 뒤왼쪽타이어 = new HankookTire();
System.out.println(앞오른쪽타이어.toString());
배열을 이용해 보자(폴리모피즘: 다형질 활용)
폴리모피즘 - 조상클래스로 선언하고 객체는 자손클래스로 만든다.
위의 코딩은 객체의 갯수가 적으면 사용할수 있지만 객체의 수가 많다면 사용할수 없기에
배열을 이용하여 코딩한다.
Tire[] tires = new Tire[] {
new KumhoTire(), new KumhoTire(),
new HankookTire(), new HankookTire()
};
// 이부분은 현재 inch의 값이 금호타이어와 한국타이어 모두 18로 나오는데
금호타이어의 값은 20으로 도출하기 위한 코딩이다.
for(Tire x: tires) {
if(x.companny.equals("금호타이어")) {
x.inch = 20;
}
System.out.println(x);
}
}
}
조상클래스
package org.override;
// 인간의 조상격에 해당하는 클래스
public class Humen {
public String country;
public String name;
public int age;
public HairColor hairColor;
// 메소드의 몸통에 아무런 코딩이 없어도 완전한 메소드이다.
// {} ==> 몸통, 몸통이 없는 메소드를 추상메소드라고 한다.
public void walk() {
System.out.println("4발로 엉금엉금 기어서 간다.");
}
public void eat(String food) {
System.out.println(food+"를 손으로 성큼 집어들어 우걱우걱 씹어 먹는다.");
}
public void speech() {}
protected void sleep() {}
}
자손클래스
package org.override;
public class Korean extends Humen {
public Korean() {
super(); // 없어도 기본생성자는 있는거임
}
@Override // 점검용
public void walk() {
System.out.println("당당하면서 사뿐사뿐 잘 걷는다.");
}
@Override // 오버라이딩을 위해서는 시그니처가 동일해야 한다.
public void eat(String food) {
System.out.println(food+ "를 젓가락과 숟가락을 이용해 점잖게 먹는다.");
}
@Override // 조상타입과 자손타입의 반환타입도 일치해야 한다.
// public String speech() {} ==> 이건 안된다는 뜻
public void speech() {}
@Override // 접근제한자는 더 큰 제한자는 바꿔도 된다. 반대는 안됨
public void sleep() {}
}
조상클래스에서 메소드를 설정했어도 자손클래스에서 수정하여 재정의 할수있음
위의 조상클래스에서 "4발로 엉금엉금 기어서 간다"라고 설정을 했음에도
자손클래스에서 "당당하면서 사뿐사뿐 잘 걷는다"라고 재정의 했으므로
결과값도 "당당하면서 사뿐사뿐 잘 걷는다"로 도출된다.
@Override(어노테이션)
컴파일할때 조상클래스의 메소드 선언부와 동일한지 검사하라고 지시하는 명령어
정확한 메소드 재정의를 위해 붙여주면된다.
메소드 제정의의 효과는 조상메소드는 숨겨지고 재정의된 자손메소드가 실행된다.
이와 관련하여 자손클래스에서 수정되기전의 조상클래스를 호출하고 싶다면
super을 사용하면 된다.
인터페이스
- 인터페이스에는 상수 필드만 선언할수 있음(데이터를 저장X)
- 인터페이스에서 선언되는 모든 필드는 public static final 이 컴파일 과정에서 자동으로 붙는다
- 상수명은 꼭 대문자로 적을것
- 선언과 동시에 초기값이 지정됨으로 static {} 블럭을 사용해서 초기화할수 없다
public interface FromVision {
// 인터페이스에서 선언하는 변수는 상수이다.
// 그래서 대문자를 쓴다.
int MIN_IQ = 130; //public static final이 자동으로 붙어 생략됨
// 인터페이스 내의 메소드는 일반적을 추상메소드이다.
String getGisu(); // public abstract 가 생략되어있음
String getGuaJung(); // public abstract 가 생략되어있음
// 자바1.8부터 추가된 기능
// default method는 하나만 사용할 수 있다.
// 람다식에 많이 사용된다.
default int add(int a, int b) { // default 키워드를 반드시 붙여야함
return a+b;
}
// static method는 여러개를 둘수있다.
// 객체 생성없이 기존의 구현체들에게 새로운 기능을 획일적으로
// 간단하게 부여하는 방법이다.
static String getVersion() {
return "Ver 1.03";
}
}
public class TestMain {
public static void main(String[] args) {
Student a = new Student("1","산대특지능형데이터융합개발자","정찬수");
Student b = new Student("1","산대특지능형데이터융합개발자","강호동");
// 폴리모피즘을 이용하기 위한 방식(Promotion: 자동승진이발생됨)
// 이런 점에서 인터페이스는 조상클래스와 유사한 면모를 가지고 있다.
FromVision c = new Student("1","산대특지능형데이터융합개발자","장다연");
System.out.println(a);
System.out.println(b);
System.out.println(c);
// 배열형태로 폴리모피즘 활용
FromVision[] students = new FromVision[] {
new Student("1","산대특지능형데이터융합개발자","정찬수"),
new Student("1","산대특지능형데이터융합개발자","강호동"),
new Student("1","산대특지능형데이터융합개발자","장다연")
};
for(FromVision x:students) {
System.out.println(x);
System.out.println("이 사람의 최소 아이큐는 "+FromVision.MIN_IQ+"입니다.!");
}
System.out.println("FromVision 인터페이스 버전: "+FromVision.getVersion());
// default method 사용한 예 (람다식에서)
Calculator add = (q,w) -> q+w;
Calculator substract = (q,w) -> q-w;
System.out.println(add.calc(10, 5));
System.out.println(substract.calc(10, 5));
}
}
익명 객체
- 익명 객체는 단독으로 생성 불가
- 익명 객체를 만들 때에 추가된 필드나 메소드는 그 객체 바깥에서는 사용이 불가능
(내부에서만 호출 가능)
객체의 동등 비교
해당 코드의 결과를 확인해 보면 객체가 생성될때 할당되는 해시코드가 다르기 때문에
false 라는 결과값이 나오게 되는데 이를 같은 해시코드로 변환하여 ture라는 결과를 출력하기 위해서는
논리적 동등을 사용해야 한다.
object의 equals() 메소드를 사용하여 재정의 한후 논리적 동등 비교를 하면
같은 객체이건 다른 객체이건 상관없이 객체 저장 데이터가 동일하게 변경된다.
해시코드를 변경하여 이전의 flase 결과를 ture로 변환할수 있다.
객체의 해시코드
- 객체를 식별할 하나의 정수값
- 객체의 메모리 번지를 이용하여 해시코드를 만든후 리턴한다.
- 개별 객체는 해시코드가 모두 다름!!!!
import java.util.ArrayList;
public class TestWrapper {
public static void main(String[] args) {
// int 사용에 필요한 기능을 포함시켜 만든 클래스 == >Integer
// byte ===> Byte, boolean ==> Boolean
// char ===> Character
// -------------------------------------------
int a = Integer.parseInt("365");
double b = Double.parseDouble("3.141592");
boolean c = Boolean.parseBoolean("ture");
System.out.println(Integer.MAX_VALUE);
System.out.println(Double.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(Double.MIN_VALUE);
// int타입의 정수를 객체로 만든다.
Integer d = new Integer(365);
Integer d2 = new Integer("365");
Integer d3 = 365;
//자동포장되어 객체로 변환된다. (AutoBoxing)<-->(AutoUnBoxing)
// Generics Type ==> 굳이 번역하자면 일반화 타입
ArrayList<Integer> list = new ArrayList<>(); // 다이아몬드 연산자
list.add(123); // 자동포장 기능이 작동되었음
list.add(new Integer(365));
System.out.println(list.get(0)+100); // 자동으로 포장이 풀림
}
}