String class

문자열 배열 필드와 배열을 사용하는 메소드로 구성된 클래스

 

주요 String class

equals 같은지 비교하는 메소드
charAt(순번) 순번에 해당하는 문자를 구하는 메소드
compareTo(문자열) 두 문자열을 비교하는 메소드
  (문자열1.compareTo.문자열2)
equals와 compareTo 차이점  
equals true, false로 결과가 나옴.
compareTo 반환값이 같으면 0, 앞의 문자열이 크면 양수(큰 값을 앞에 쓰면), 뒤의 문자열이 크면 음수(큰 값을 뒤에 쓰면)
순서상 어느 것이 먼저인지 나중인지 비교할 수 있음.
startWith, endsWith, indexOf 문자열 내의 문자열 검색 메소드
startWith 문자열이 특정 문자열로 시작하는지 여부 확인
endsWith 문자열이 특정 문자열로 끝나는지 여부 확인
indexOf 문자열에 특정 문자열이 들어있는 위치 검사
length 문자열의 길이를 구하는 메소드
replace  특정 위치의 문자 변경 메소드
substring 문자열에서 문자열을 추출하는 메소드
split 구분자를 사용하여 전체 문자열을 잘라서 부분 문자열을 만드는 메소드
trim 앞뒤 공백 제거 메소드

 

charAt 예제)

	public static void main(String[] args) {
		String str = "Hello world";
		System.out.println("6번째 문자 : " + str.charAt(5));
		
		String order = "01100";
		for(int i = 0; i < order.length(); i++) {
			if(order.charAt(i) == '0') {
				System.out.println("전원을 끕니다.");
			}
			else if(order.charAt(i) == '1') {
				System.out.println("전원을 켭니다.");
			}
		}

전원 버튼 5개에 대한 일괄 처리

문자열의 각 문자를 한씩 가져와서 따로따로 사용해야함.

문자열은 equals 메소드 사용해야함.

char은 문자가 되기때문에 ==과 '' 사용해서 단순비교 가능하다.

 

compareTo 예제)

String s1 = "Hello";
		String s2 = "Hello";
		String s3 = "Ahello";
		String s4 = "Zhello";
		
		int r = s1.compareTo(s2);
		System.out.println("s1과 s2 비교 결과 : " + r);
		
		r = s1.compareTo(s3);
		System.out.println("s1과 s3 비교 결과 : " + r);
		
		r = s1.compareTo(s4);
		System.out.println("s1과 s4 비교 결과 : " + r);
		

알파벳 순서상 같으므로 수치 비교까지 같이 출력됨.

첫번째 글자가 같으면 다음 글자를 비교해줌.

지금 들어온 문자가 앞에 올지, 뒤에 올지 비교해서 배치해줌.

 

공백문자와 null문자

공백문자 ASKII 코드 값 가지고있음. 값이 없는 것이 아님
null 비어있는 문자

 

starWith, indexOf, endsWith 비교 예제)

public static void main(String[] args) {
	String name[] = new String[6];
	
	name[0] = "유상민";
	name[1] = "노희원";
	name[2] = "백길현";
	name[3] = "김철수";
	name[4] = "안철수";
	name[5] = "김민철수";

 

startWith

	String nStr = "김";
	
	for(String n : name) {
		if(n.startsWith(nStr)) {
			System.out.println(n);
		}
	}
	System.out.println();

무조건 첫번째 글자만 비교해서 김씨인 사람들만 출력

 

	nStr = "철";
	for(String n : name) {
		if(n.startsWith(nStr, 1)) {
			System.out.println(n);
		}
	}

이름 2번째 글자가 "철"인 이름 출력

 

indexOf

	for(String n : name) {
		if(n.indexOf(nStr) > -1) {
        System.out.println(n);
		}
	}

indexOf 없을 경우에 -1을 반환하게 때문에 0 이상이 된다면 내용이 들어있다는 의미이다.

 

	nStr = "민";
	for(String n : name) {
		if(n.endsWith(nStr)) {
			System.out.println(n);
		}
	}

끝이  "민"으로 끝나는 이름 출력

 

	String cn = "aaa";
	
	if(cn.equals("aaa")) {
	}

cn에 저장된 값이 aaa라면 참

 

	if("aaa".equals(en)){
	}

aaa가 cn의 값과 같으면 참.

문자열이라고 만들어있는 "aaa" 자체가 인스턴스니까 뒤집어서 문자열을 비교대상으로서 기준으로 잡아 처리하는 것도 가능하다.

 

replace 예제)

		String s1 = "abaccbacbacbacbcccabab";
		
		String s2 = s1.replace('a', 'z');
		System.out.println("s1 : " + s1);
		System.out.println("s2 : " + s2);

		System.out.println();
		
		String s3 = s1.replace("c", "zz");
		System.out.println("s1 : " + s1);
		System.out.println("s3 : " + s3);
		
		System.out.println();

		String s4 = s1.replace("ab", ",");
		System.out.println("s1 : " + s1);
		System.out.println("s4 : " + s4);

replace는 원본은 변경하지 않음. 복사 후 복사된 내용을 바꾼 후 출력.

변경된 문자열 사용시에는 새로운 공간에 다시 대입해서 저장 후 변경된 문자열 사용 가능함.

바꾸기 전 기존의 문자열과 바꿔지는 문자의 갯수 차이는 상관 없음.

 

toLowerCase, toUpperCase 예제)

		String oriStr = "HELLO";
		String tarStr = oriStr.toLowerCase();
		System.out.println("oriStr : " + oriStr);
		System.out.println("tarStr : " + tarStr);
        
		String oriStr2 = "Hello";
		String tarStr2 = oriStr2.toLowerCase();
		String tarStr3 = oriStr2.toUpperCase();
		System.out.println("oriStr2 : " + oriStr2);
		System.out.println("tarStr2 : " + tarStr2);
		System.out.println("tarStr3 : " + tarStr3);
toLowerCase 대문자  소문자
toUpperCase 소문자  대문자

주로 (y/n) 선택시에 들어오는 문자를 소문자 또는 대문자로 일괄적으로 바꿔서 하나만 조건을 삼을 때 사용함.

대소문자 섞여있으면 다 같은걸로 바꿔준다.

 

trim 예제)

		String oriStr3 = "	Hello world	";
		String trimStr = oriStr3.trim();
		System.out.println("oriStr3 : " + oriStr3);
		System.out.println("trimStr : " + trimStr);

문자 사이의 공백은 지우지 않고 앞과 뒤만 지움.

 

substring 예제)

		String longStr = "Hello Java Programming World!!";
		int stIdx = longStr.indexOf("Pro");
		int endIdx = longStr.indexOf(" Wo");
		String subStr = longStr.substring(stIdx, endIdx);
		System.out.println(subStr);
		System.out.println("전체 길이 : " + longStr.length()
				+ ", stIdx : " + stIdx
				+ ", endIdx : " + endIdx);

subString에 값을 집어넣는 방법 두가지

1. 괄호안에 하나만 넣는 방법(거기서부터 나머지 전부)

2. 두개 넣는 방법(A부터 B까지 추출)

 

split 예제)

		longStr = "Hello Java Programming World";
		String sub[] = longStr.split(" ", 3);

구분자를 집어넣어줌.

longStr의 경우에는 공백으로 나누어져있기 때문에 공백으로 구분해줌.

숫자를 지정하지 않으면 다 구분자를 사용해서 나눠줌.

숫자 입력시 분할 갯수를 지정해준다.

 

 

 

 

 

 

 

 

 

 

 

- Error(오류)와 Exception(예외사항)

Error(오류) 프로그램이 실행될 수 없는 오류
프로그램이 실행중에 처리할 수 없음(코드를 고쳐야 실행 가능)
ex.오타
Exception(예외사항) 프로그램 실행 중에 발생하는 오류
수습 코드를 통해 실향할 수 있는 오류

 

- 예외처리

수습 코드를 작성하여 사전에 예외로 인한 프로그램의 비정상적 종료를 미연에 방지하는 작업

 

- 주요 예외 사항

ArithmeticException 수학적으로 해결할 수 없는 예외
NullPointException 인스턴스가 생성되지 않았다.
ArrayIndexOutOfBoundsException 배열 범위 밖
ex. 0~9까지인데 10번 사용할 경우 
NumberFormatException 숫자로 변환할 수 없음
ex. Scanner 사용해서 다 문자열로 받아서 숫자로 변환할 때 숫자가 아니여서 변환할 수 없을 경우(one, 하나, ... 입력시)
IOException 입출력 예외(파일 입출력 포함)
SQLException DB 처리 관련 예외

 

- 예외 사항의 처리

try
(시도하다)
예외 사항이 발생될 수 있는(가정) 코드를 작성하는 부분.
정상적으로 처리될 수도 있으며, 코드를 작성할 때는 잘 처리될 것으로 생각하며 작성함.
catch
(예외사항을 잡아서 처리하다)
try부분에서 예외사항이 발생되면 처리해야할 작업 코드를 작성하는 부분(문제에 대한 출력문 등...)
catch 부분은 예외사항에 따라 여거개가 존재할 수 있음.
finally
(반드시 마지막에 실행하다)
생략할 수 있는 부분. 예외가 없어도, 예외가 있어도 마지막에 실행되야하는 코드를 작성하는 부분.
마지막에 실행할 작업이 없으면 작성하지 않아도 됨.

 

- 처리 순서

1. 메소드 안에서 자체적으로 처리 try, catch 구문을 사용
2. 호출한 메소드에서 처리하도록 예외를 넘김 반환형 메소드() throws 예외사항 { ... }
메소드를 호출한 위치에 try, catch를 사용하여 예외를 처리해야함.

 

- Multi-catch

catch부분은 여러개를 작성할 수 있음.

try {
	//숫자 입력 처리
    //나눗셈 처리
} catch (NumberFormatException ne) { //(1)
	... //숫자를 입력해야 합니다.
} catch (ArithmeticException ae) { //(2)
	... //0으로 나눌 수 없습니다.
} catch (Exception e) { //(3)
	... //그 외의 예외사항 처리
}

작성 순서대로 실행됨.

(1)이 아니면 (2), (2)도 아니면 (3) catch 부분 실행.

 

마지막에 큰 범위의 예외사항이 와야함.

 

-호출하는 메소드에게 예외사항 전달

throws Exception 클래스1, Exception 클래스2.., Exception 클래스n

 

메소드 선언 뒤쪽에 throws 키워드로 사용하여 예외사항 클래스를 입력하면 호출한 메소드에 발생한 예외사항을 넘길 수 있음

 

다양한 예외사항을 처리해야 할 경우 ','로 구분하여 여러 개의 예외사항 클래스를 입력할 수 있음.

 

-예외사항 일부러 만들기

예외 사항 인스턴스를 만들어서 보내기.

Exception 클래스로 예외사항 인스턴스를 생성

 

- 생성 시 메시지로 사용할 문자열 추가

Exception ex = new Exception("메시지");

 

- throw 키워드를 사용하여 예외 인스턴스 전달

throw ex;

 

이 때 메소드는 예외를 전달하기 때문에 throws로 예외를 선언해야 함.

public void method() throws Exception { ... }

 

- 에러 코드와 메시지를 갖는 예외 클래스 만들기(작성 단계)

1. Exception 클래스를 상속하여 새로운 클래스(MyException) 작성
2. 작성한 새로운 클래스로 인스턴스 생성
3. 생성 시 메시지, 에러코드 등 값 추가
4. 새로 만든 예외사항임을 알려야함. throws 뒤에 클래스 이름을 작성.
5. 메소드를 호출하는 곳에서 새로운 클래스로 catch 처리. catch 부분에서 새로운 클래스의 정보를 출력 및 처리.

 

예제)

com.dto.package > Infomation.java

package com.dto;

public class Information {
	private String name;
	private String info;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getInfo() {
		return info;
	}
	public void setInfo(String info) {
		this.info = info;
	}
}

 

com.package > ExceptionTest.java

package com;

import java.util.Scanner;

import com.dto.Information;

public class ExceptionTest {
	
	static Information info = new Information();
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		System.out.print("이름 : ");
		info.setName(scan.nextLine());
		System.out.print("정보 : ");
		info.setInfo(scan.nextLine());
	}
}

static Informationinfo = new Information();에서 =new Information()을 붙이기 전에는 참조변수(선언만 되어있고 아무것도 없는 상태이기 때문에) NullPointerException이 발생한다.

 

 

com.package > CalculatorTest.java

1. 덧셈(예외 사항 자체 처리)

package com;

import java.util.Scanner;

public class CalculatorTest {

	static Scanner scan = new Scanner(System.in);
	public static void main(String[] args) {

		String menu = "";

		while(true) {
			System.out.println();
			System.out.println("예외처리 계산기");
			System.out.println("1. 덧셈");
			System.out.println("2. 뺄셈");
			System.out.println("3. 나눗셈");
			System.out.println("4. 예외 발생");
			System.out.println("0. 종료");
			System.out.print("선택>> ");

			menu = scan.nextLine();

			if(menu.equals("0")) {
				System.out.println("종료");
				break;
			}

			switch(menu) {
			case "1":// 덧셈 처리(예외사항 자체 처리)
				add();
				break;
			
	private static void add() {
		int n1, n2, rs;
		String str;

		System.out.println("덧셈 연산");//서브 타이틀

		try {
			System.out.print("첫번째 수 : ");
			str = scan.nextLine();
			n1 = Integer.parseInt(str);
			System.out.print("두번째 수 : ");
			str = scan.nextLine();
			n2 = Integer.parseInt(str);

			rs = n1 + n2;

			System.out.println("계산 결과 : " + rs);
		} catch(Exception ne) {
			System.out.println("숫자를 입력해 주세요.");
		} finally {
			System.out.println("덧셈 연산이 끝났습니다.");
		}
	}//add 끝
	

어떤 예외사항일지 모를 경우에는 가장 높은 Exception으로 모든걸 받아서 사용할 수 있음.

인스턴스로 모든게 처리된다. 즉, 예외 사항도 인스턴스이다.

 

2. 뺄셈(예외 사항 떠넘기기)

case "2":// 뺄셈 처리(예외사항 떠넘기기)
				try {
					subManage();
				} catch (NumberFormatException e) {
					System.out.println("숫자를 입력해 주세요.");} catch (Exception e) {
                    System.out.println("숫자를 입력해 주세요.");					
				}
				break;

	private static void sub() throws NumberFormatException, Exception {
		int n1, n2, rs;
		String str;

		System.out.println("뺄셈 연산");
		
			System.out.print("첫번째 수 : ");
			str = scan.nextLine();
			n1 = Integer.parseInt(str);
			System.out.print("두번째 수 : ");
			str = scan.nextLine();
			n2 = Integer.parseInt(str);

			rs = n1 - n2;

			System.out.println("계산 결과 : " + rs);
	}
    
    	public static void subManage() throws NumberFormatException, Exception{
		sub();		
	}
}

sub에서 전달되는 걸 subManage가 받아서 전달하는 흐름을 만들기 위해 subManage();를 작성해준다.

오류 발생시 가장 가까운 catch문이 받고, 아니면 다른 예외사항으로 다시 던진다.

다른 예외사항 발생할 경우를 대비해서 catch (Exception e)를 만들어준다.

Exception이 더 크기 때문에 나중에 써줘야함(먼저 작은 범위인 NumberFormatException부터 사용한다.)

 

NumberformatException, Exception에 대한 try, catch는 case문에 적어준다.

메소드 부른 곳에서 처리하기 때문에 메소드 이름 뒤에 throws exception을 작성해준다.

 

3. 나눗셈(자체처리, 떠넘기기)

			case "3":// 나눗셈 처리(자체 처리도 하고 떠넘기기도 하고)
				try {
					div();
				} catch (NumberFormatException e) {
					System.out.println("숫자를 입력해주세요.");
				}
				break;
                
       	private static void div() throws NumberFormatException{
		int n1, n2, rs;
		String str;

		System.out.println("나눗셈 연산");//서브 타이틀
		
			System.out.print("첫번째 수 : ");
			str = scan.nextLine();
			n1 = Integer.parseInt(str);
			System.out.print("두번째 수 : ");
			str = scan.nextLine();
			n2 = Integer.parseInt(str);
			
			try {
			rs = n1 / n2;
			} catch (ArithmeticException e) {
				System.out.println("0으로 나눌 수 없습니다.");
				rs = 0;
			}
			System.out.println("계산 결과 : " + rs);
	}

Exception으로만 하면 위에서 처리해야할 부분까지 전체 처리해주므로 오류 발생함.

if문 사전에 비교(true, false)
try~catch문 무조건 계산을 실행하고 봄, 안되면 예외사항으로 실행
if문 대신 try~catch문 사용하는 이유 if문은 연산이 필요하지만, 예외사항은 연산이 필요없기 때문에 사용한다.

 

4. 에외 사항 일부러 발생시켜서 처리하기

			case "4":// 예외를 일부러 발생 시켜서 처리해보기.
				try {
					makeException();
				} catch (MyException e) {
					System.out.println(e.getMessage());
					System.out.println("에러코드 : " + e.getErrCode());
				}
				break;
			default:
				break;
			}
		}
	}
    

	private static void makeException() throws MyException{
		MyException myexp =
				new MyException("페이지를 찾을 수 없습니다.", 404);
		
		throw myexp;
	}

'이런 예외사항이 발생할 수도 있다.'라는 가정을 해두는 것이다. 

여러 예외를 줄 수 있기 때문에 throws로 사용하며, 특정 문구를 가진 예외 인스턴스 만든다.

Exception myexp = new Exception("일부러 만든 예외사항~");

만든 예외를 던졌을 때 실제로 던져지는 부분은 case "4"의 try~catch문에서 받게된다.

실제로 사용하는 것은 throw myexp;이다. 이 경우 하나만 던지기 대문에 throw로 사용한다.

 

5. 예외 코드 저장 필드

class MyException extends Exception{
	private final int ERR_CODE;
	
	public MyException(String msg, int eCode) {
		super(msg);
		ERR_CODE = eCode;
	}
	
	public int getErrCode() {
		return ERR_CODE;
	}
}

super(msg)를 사용하기 때문에 부모 클래스의 메시지 출력한다.

return ERR_CODE는 에러코드만 받아서 상수값으로 넘긴다.

 

-etc

try~catch문 안에 try~catch문을 중첩으로 사용할 수 있음. 하지만 중첩하는 일은 거의 없다.

finally안에 catch 넣어서 사용하는 경우는 종종 있다.

 

굳이 예외처리 어렵게 (상위로 보내서) 할 필요 없다. method안에서 try~catch 사용해서 예외사항 처리하는게 더 좋음.

추상화

미완성 클래스를 작성하는 것, 객체지향에서의 추상화는 개념을 정의하는 것.

기본(부모/조상) 클래스를 설계할 때 메소드의 이름 있는 부분(선언부)만 정의하는 것.

 

추상 클래스와 추상 메소드

추상 클래스
Abstract class
멤버 중에 하나라도 추상 메소드가 있으면 추상 클래스임.
추상 클래스 안에는 추상 메소드가 없을 수도 있음. 이 경우 추상 클래스로 만들 필요가 없음.
추상 메소드
Abstract method
선언부만 정의(작성)된 메소드. 추상 메소드가 있으면 그 클래스는 반드시 추상 클래스여야 함.
추상 메소드는 반드시 상속 받은 하위 클래스에서 내용을 정의해야 함.
(또는 하위 클래스도 추상 클래스가 되어야함.)

 

추상 클래스와 추상 메소드의 예제)

package AbstractPkg;

public class AbstractTest01 {

	public static void main(String[] args) {
		Abs abs2 = new Abs() {
			
			@Override
			public void absMethod() {
				System.out.println(1);				
			}
		};
		
		Abs abs3 = new Abs() {
			
			@Override
			public void absMethod() {
				System.out.println(2);
			}
		};
		
		abs2.absMethod();
		abs3.absMethod();
		
		ChildAbs abs4 = new ChildAbs();
		ChildAbs abs5 = new ChildAbs();
		abs4.absMethod();
		abs5.absMethod();
	}

}


abstract class Abs{
	public abstract void absMethod();
}


class ChildAbs extends Abs {

	@Override
	public void absMethod() {
		System.out.println(5);
	}
}

출력결과

 

Abs abs = new Abs();를 사용하면 안되는 이유는 추상 클래스는 인스턴스를 만들 수 없기 때문이다.

대신 인스턴스를 만들 때 추상메소드를 정의하면 가능하다.

 

abs2와 abs3는 추상 클래스 객체가 아닌, 만듦과 동시에 정의된 추상 클래스를 재정의 해줘서 독자적으로 사용이 가능하다.

 

abs4와 abs5는 하나의 추상 클래스를 상속받은 ChildAbs를 생성한거라서 출력시 같은 결과가 나왔다.

 

부모 클래스의 추상 메소드를 반드시 정의해야 함.

이 메소드에서 실질적으로 처리해야 할 작업을 작성.

 

추상 사용 => 작업 팀 내의 표준화(정해진 규칙대로 진행함)

 

 

인터페이스(Interface)

추상화 정도가 깊은 클래스, 모든 메소드는 추상메소드임.

변수는 없고, 상수는 들어갈 수 있다. 상수일 경우에는 초기값이 있어야함.

완전 미완성이기 때문에 인스턴스를 만들 수 없음.

 

인터페이스를 상속받아서 작성하는 클래스의 작성 형식 

class 클래스명 implements 인터페이스명 { }

*인터페이스에 선언된 모든 메소드를 반드시 재정의(Override)해야한다.

 

인터페이스를 상속받은 클래스에 새로운 멤버(변수, 메소드)를 추가할 수 있다.

 

인터페이스 예제)

package InterfacePkg;

public class InterfaceClass implements ParentInterface {//구현한다.(상속받는다가 아님)

	@Override
	public void iMethod1() {
		
	}

	@Override
	public void iMethod2() {
		
	}
}
package InterfacePkg;

public interface ParentInterface {
	//필드 == 상수
	public static final int ci = 100;
	int ci2 = 200;
	
    //메소드 == 추상 메소드
	public abstract void iMethod1();
	void iMethod2();
}

int ci2 = 200; 앞에는 public static final, void iMethod2(); 앞에는 public abstract 가 생략되어 있다.

 

'JAVA' 카테고리의 다른 글

0408 JAVA - 문자열의 처리  (0) 2020.04.08
0407 JAVA - 예외처리  (0) 2020.04.07
0330 JAVA - 객체지향의 특성(다형성)  (0) 2020.03.31
0330 JAVA - 객체지향의 특성(상속)  (0) 2020.03.31
0327 JAVA - 객체 지향의 특성(상속)  (0) 2020.03.27

업캐스팅(Up_casting), 다운캐스팅(Down_casting), instanceof

업캐스팅 하위에서 상위(대체적으로 자동형변환이 됨)
부모클래스의 참조변수에 자손 클래스의 인스턴스를 저장
다운캐스팅 상위에서 하위(형변환 연산자인 casting 연산자를 사용해야함)
부모클래스의 참조변수에 저장된 자손클래스의 인스턴스를 원래 자손 클래스의 참조변수에 복원
instanceof


인스턴스가 어떤 클래스로 만들어져 있는지를 판별하기 위한 명령(다운캐스팅시에 확인하기 위해서)
사용하여 인스턴스의 클래스를 구분할 경우 부모 클래스에 대한 조건을 마지막에 처리해야함.
먼저 처리할 경우 모든 인스턴스는 부모클래스의 인스턴스에 해당되기 때문에 판별이 안됨.

 

상속, 다형성 예제)

1)상속

class Car{
	String color;
	int door;

	void drive() {
		System.out.println("간다~~~ ");
	}

	void stop() {
		System.out.println("멈춘다!");
	}
}

class FireEngine extends Car {
	void water() {
		System.out.println("물뿌리네...");
	}
}

class Ambulance extends Car {
	void firstAid() {
		System.out.println("사람을 살리네!");
	}
}

자동차의 클래스를 소방차와 구급차가 상속받음.

기본 조건이 동일하기 때문이다.

 

2)다형성

public static void main(String[] args) {
	FireEngine fe = new FireEngine();
	Ambulance ab = new Ambulance();

	Car c1 = fe;
	Car c2 = ab;

	c1.drive();
	c1.stop();

	FireEngine fe2 = (FireEngine)c1;
	fe2.water();

	Car cars[] = new Car[2];
	cars[0] = fe;
	cars[1] = ab;
	
	area(cars);
	
	Student st = new Student();
	Researcher rs = new Researcher();
	Professor pf = new Professor();
	
	System.out.print("new Student() ->\t");
	printPerson(st);
	System.out.print("new Researcher() ->\t");
	printPerson(rs);
	System.out.print("new Professor() ->\t");
	printPerson(pf);
}
public static void area(Car c[]) {
	for(Car ct : c) {
		if(c[0] instanceof FireEngine) {
			FireEngine fea = (FireEngine) c[0];
			fea.water();
		}
		if(c[1] instanceof Ambulance) {
			Ambulance aba = (Ambulance) c[1];
			aba.firstAid();
		}
	}
}

<main>

c1.water(); 사용시 부모입장에서 자식의 필드가 없는 것으로 처리하기 때문에 오류 발생함.

cars[0]는 소방차, cars[1]은 구급차인데 해당 장소로 올때의 역할은 자동차로서 이동, 멈추기만 가능하다.

해당 장소에 와서는 소방차는 불끄기, 구급차는 사람 구하기로 역할이 나뉜다.

따라서 이동시에는 구분이 불필요하기 때문에 자동차로 묶어서 보낸다. 

 

<area>

instanceof를 사용하여 인스턴스를 구분한다.

자동차가 그룹지어서 들어올 때 소방차인지 구급차인지 정해준다.

따로따로 메소드를 만드는 것이 아닌 다형성을 사용해서 한꺼번에 자동차로 묶은 뒤 분류해서 사용한다.

=> 업캐스팅, 다운캐스팅, 인스턴스오브를 사용해준다.

 

instanceof 사용시 규칙

public static void printPerson(Person p) {
	if(p instanceof Person) {
		System.out.print("Person ");
	}		
	else if(p instanceof Student) {
		System.out.print("Student ");
	}
	else if(p instanceof Researcher) {
		System.out.print("Researcher ");
	}	
	else if(p instanceof Professor) {
		System.out.print("Professor ");
	}	
	System.out.println();
}   	

class Person { }
class Student extends Person { }
class Researcher extends Person { }
class Professor extends Researcher { }

 

if로만 했을 경우의 출력 결과

 

else if를 사용했을 경우의 출력 결과

가장 범위가 넓은 것을 조건으로 걸게되면, 나머지는 사용할 필요가 없어짐.

여러개 중 하나, 그 외 나머지로 할 경우, 가장 큰 개념에 해당하는 클래스가 제일 마지막에 와야함

즉, Professor 이나 Student => Researcher => Person 순서로 판단 조건에 올라와야한다.

작은 클래스 => 최고 조상 클래스에 해당하는 클래스 순서로 올라와야한다.

 

Object 클래스

모든 클래스의 조상이기 때문에 Object 참조변수는 모든 인스턴스를 저장할 수 있다.

기본 자료형(8가지)의 값도 저장할 수 있는데, 단! Wrapper 클래스를 사용하여 인스턴스로 만들어야 저장할 수 있다.

package polymorphism;

public class ObjectPolyTest {

	public static void main(String[] args) {
		Integer i = new Integer(1);
		Float f = new Float(3.14f);
		String str = "abc";
		Car c1 = new Car();
		Student st = new Student();
		
		ObjectPrint(i);
		ObjectPrint(f);
		ObjectPrint(str);
		ObjectPrint(c1);
		ObjectPrint(st);
		
	}
	
	public static void ObjectPrint(Object obj) {
		 if(obj instanceof Integer) {
			 System.out.println("정수 : " + (Integer)obj);
		 }
		 else if(obj instanceof Float) {
			 System.out.println("실수 : " + (Float)obj);
		 }
		 else if(obj instanceof String) {
			 System.out.println("문자열 : " + (String)obj);
		 }
		 else if(obj instanceof Car) {
			 System.out.println("자동차 : " + (Car)obj);
		 }
		 else if(obj instanceof Student) {
			 System.out.println("학생 : " + (Student)obj);
		 }
	}
}

Object 클래스의 출력 결과

Car와 Student도 같은 패키지에 있기 때문에 사용이 가능하다.

 

 

super와 this

this 멤버 필드와 일반 변수(매개 변수)를 구분할 때 사용. 같은 인스턴스(클래스) 안에서 활용.
this() 한 생성자가 다른 생성자를 호출할 때 사용

 

super.변수명 부모 클래스의 멤버와 자손 클래스의 멤버를 구분하기 위해 사용.
부모 클래스에 있는 걸 안 쓰면 되는데, 자손 클래스에서 동일한 변수명을 사용해야하는 경우에는 super.을 붙여서 구분해줌.
super() 부모 클래스의 생성자 호출을 위해 사용.
자손 클래스의 생성자에서는 부모클래스의 생서자를 호출해서 먼저 처리되도록 해야함.
부모 클래스에 여러 개의 생성자가 존재할 경우(오버로딩) 생성자의 매개변수로 구분하여 사용.

 

super와 this 메모리 구조 형식

super 부모 클래스가 위치하는 곳의 주소를 저장하게 됨
this 인스턴스 자기자신에 해당되는 주소값이 저장됨

 

super와 this 예제

public class SuperTest {

	public static void main(String[] args) {
		Child c = new Child();
		c.method();
		
		CC cc = new CC();
	}
}

 

class Parent{
	int x = 10;
	int y = 100;
	
	public Parent() {}
	String getLocation() {
		return "x : " + x + ", y : " + y;
	}
}

부모 클래스 자동생성

 

class Child extends Parent {
	int x = 20;
	int z = 300;
	
	void method() {
		System.out.println("x : " + x);
		System.out.println("this.x : " + this.x);
		System.out.println("super.x : " + super.x);
	}
	
	public Child() {
		super();
	}
	
	@Override
	String getLocation() {
		return super.getLocation()
				+ "this.x : " + this.x
				+ "z : " + z ;
	}
}

자손 클래스의 생성자를 만들때 부모 클래스의 생성자를 호출해야한다는 규칙에 따라서 super();가지 들어감. 즉, super();를 생략해도 자동으로 들어가기때문에 작동이 잘된다.

 

class Ancestor {
	int x;
	int y;
	
	public Ancestor() {
	}
	
	public Ancestor(int x, int y) {
		this.x = x;
		this.y = y;
	}
}

super() 부모클래스의 생성자

기본 생성자 : public Ancestor() { }

 

class Descendants extends Ancestor {
	int z;
	
	public Descendants(int x, int y, int z) {
    	super();
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

부모 클래스의 기본 생성자인 super();을 사용함.

부모 클래스의 기본 생성자가 없으면 에러가 발생함.

부모 클래스의 기본 생성자를 호출했음.

 

생성자들의 실행 순서 예제)

class AA{
	public AA() {
		System.out.println("생성자 AA");
	}
}

class BB extends AA{
	public BB() {
		System.out.println("생성자 BB");
	}
}

class CC extends BB{
	public CC() {
		System.out.println("생성자 CC");
	}
}
AA클래스 Object 상속을 받아서 만들어진 것이므로 최상위 클래스는 아니기 때문에 Object의 생성자인 super();가 자동으로 생성됨.
AA클래스에서는 Object의 생성자가 호출되고, super();가 존재함.

 

super가 먼저 실행이 되기 때문에 C의 super => B, B의 super => A이므로 A, B, C 순서대로 출력됨.

작성을 안 하면 생성자의 첫번째줄에서 내부적으로 먼저 호출함.

생성자의 첫번째 줄에 부모 클래스가 호출되도록 해야함

 

etc

부모 클래스가 우선이 아니고 내가 우선이기 때문에 x 값이 10이 아닌 20이 나옴.

이름이 같다고 같은 공간이 아니고, 다른 공간을 각자 사용하는 것임.

 

이름이 다르면 super 안 붙이고 그냥 사용하면 됨.

 

자동 클래스에 있는 메소드가 부모 클래스에 있는 메소드를 덮어서 자동 클래스의 메소드만 보이게됨

이럴 경우 super를 사용해서 부모 클래스의 메소드를 호출해서 사용 가능함.

 

오버라이딩했을 때 똑같은 메소드 호출하고, 부모 자식 클래스 간의 변수이름 같게 사용하는 경우는 별로 없다.

 

 

 

 

 

 

1. 캡슐화(정보은닉)

필드 + 메소드 = class

 

2. 상속

부모로부터 어떤 [성질]을 물려받는 것.

상속하는 그 시점을 봤을 때 그대로 물려받는 것.

기존의 클래스(부모 클래스)를 재사용해서 새로운 클래스 작성하는 방법.

 

발전 순서

구조적 프로그래밍 => 함수 사용 => 객체 지향 

 

기존 클래스의 멤버 + 새로운 멤버 = 새 클래스

=> 기존 클래스의 메버를 그대로 가지고 오는 것을 상속이라고 함.

기존 클래스 : 부모, 조상 클래스

새 클래스 : 자식, 자손 클래스

 

상속의 장점

1. 클래스의 간결화 => 중복된 코드 작성 불필요.

2. 클래스 관리 용이 => 클래스를 계층적으로 분류 및 관리

3. 소프트웨어의 생산성이 향상됨 => 클래스의 재사용과 확장 용이, 새로운 클래스의 작성에 속도 빠름

 

클래스 간의 관계

1. 상속관계 : is a(그게 그거다.)

2. 포함관계 : has a(가지고 있는거다.)

 

상속 예제) 학생, 알바 학생, 연구원 학생, 교수

class Person {
	public void speaking() { }
	public void eating() { }
	public void walking() { }
	public void sleeping() { }
}

class Student extends Person{
	public void studying() { }
}

class StudentWorker extends Student{
	public void working() { }
}

class Researcher extends Person {
	public void research() { }
}

class Professor extends Researcher {
	public void teaching() { }
}

1. 학생 - 말하기, 먹기, 걷기, 잠자기, 공부하기

2. 알바 - 말하기, 먹기, 걷기, 잠자기, 공부하기, 일하기

3. 연구원 - 말하기, 먹기, 걷기, 잠자기, 연구하기

4. 교수 - 말하기, 먹기, 걷기, 잠자기, 연구하기, 가르치기

 

상속의 대칭화 

묶음으로 처리를 해서 관리가 편리(용이함)

공통되는 기능을 person에 넣어 상속 받아 사용함.

 

 

상속의 특징

자바에서 클래스의 상속은 단일 상속만 지원(다중 상속 불가)

여러 클래스를 통합할 경우 주가 되는 하나의 클래스를 상속받고 나머지 클래스는 포함관계로 활용.

 

다중 상속은 불가지만, 다단 상속은 가능함.

모든 클래스는 하나의 조상을 갖는다. => Object 클래스

 

새로 추가해서 작업을 좀 더 간단하게 효율적으로 빠른 시간내에 끝내도록 하는 것이 상속임.

 

상속 예제) 

public class PointTest {

	public static void main(String[] args) {
		Point p1 = new Point();
		ColorPoint cp1 = new ColorPoint();
		Point3D p3_1 = new Point3D();
		
		p1.set(1, 2);
		p1.showPoint();
		
		cp1.set(3, 4);
		cp1.setColor("RED");
		cp1.showColorPoint();
	}
}

colorPoint 안에 setColor도 포함되어있음.

 

class Point {
	private int x;
	private int y;
	
	public void set(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public void showPoint() {
		System.out.println(" (" + x + "," + y + ")");
	}
}

특정 위치를 저장하는데 사용함.

 

class ColorPoint extends Point{
	private String color;
	
	public void setColor(String color) {
		this.color = color;
	}
	
	public void showColorPoint() {
		System.out.println(color);
		showPoint();
	}
}

	public void showPoint3D() {
		showPoint();
		System.out.println("z : " + z);
	}
}

class ColorPoint3D extends Point3D{
	ColorPoint cp = new ColorPoint();
}

점의 색상을 표현하는 부분

showPoint() 상속받은 거라 보이지는 않지만 호출해서 사용 가능함.

private, public void showPoint, public void setColor 다 있음.

 

class Point3D extends Point {
	int z;
	
	public void setZ(int z) {
		this.z = z;
	}
	
	public void showPoint3D() {
		showPoint();
		System.out.println("z : " + z);
	}
}

class ColorPoint3D extends Point3D{
	ColorPoint cp = new ColorPoint();
}

Point3DPoint3D는 Point를 확장한(상속받은) 클래스다.

class ColorPoint3D extends Point3D, ColorPoint 이런 형식으로는 사용이 불가능함.

 

 

오버라이딩(Overriding)

부모 클래스의 메소드를 자손 클래스에서 새로 정의하는것.

반환형, 이름, 매개변수(type, 갯수)는 동일하지만, 정의된 내용이 다르다.

cf. 매개변수 다를 경우 오버라이딩이 아닌 오버로딩이 된다.

 

부모 클래스의 메소드가 자손 클래스에서 사용하기에 맞지 않을 때 부모 클래스의 메소드를 덮어써서 새로운 메소드로 다시 만드는 작업.

자손 클래스의 인스턴스에서는 부모 클래스의 메소드를 없는 것으로 처리

(메소드가 없어지는 것은 아니며, 부모 클래스의 인스턴스에서는 사용이 가능하다.)

부모 클래스의 모든 매소드를 재정의하는 것이 아니라 변경이 필요한 메소드만 재정의한다.

 

생성자의 이름은 클래스의 이름과 동일하다. => 자동클래스는 자동클래스로서의 이름을 가지고 있다.

 

 

오버라이딩 예제) 커피의 이름, 가격

public class OverrideTest {

	public static void main(String[] args) {
		TeaInfo coffee = new TeaInfo();
		coffee.setName("아메리카노");
		coffee.setPrice(3000);
		System.out.println(coffee);
		
		Point01 p1 = new Point01();
		p1.x = 1;
		p1.y = 2;
		System.out.println(p1.getLocation());
		
		Point3D01 p2 = new Point3D01();
		p2.x = 5;
		p2.y = 6;
		p2.z = 7;
		System.out.println(p2.getLocation());
	}
}

coffee.setName("아메리카노");

coffee.setPrice(3000);

 

동일한 표현 => System.out.println("이름 : " + coffee.getName() +"\n" + "가격 : " + coffee.getPrice());

 

class TeaInfo extends Object{
	private String name;
	private int price;
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	
	@Override
	public String toString() {
		return "이름 : " + name + "\n" + "가격 : " + price;
	}
}

toString은 객체를 문자열화 변환시켜주는 method이다.

System.out.println()에 들어가게되면 객체의 정보를 문자로 변환하게된다.

 

오버라이딩 예제2)

class Point01 {
	int x, y;
	
	String getLocation() {
		return "x : " + x + ", y : " + y;
	}
}


class Point3D01 extends Point01 {
	int z;
	
	@Override
	String getLocation() {
		return "x : " + x + ", y : " + y + ", z : " + z;
	}
}

똑같은 이름을 사용해서 출력을 해준다는 의미이다.

똑같은 이름의 method를 재정의해준다. 파라미터, return, 클래스명이 동일해야한다.

대신 부모클래스의 메소드를 상속받을 대 사용한다.

 

상속의 접근제한

public 상속과 관계없이 제약 없이 접근 가능
default 상속과 관계 없이 같은 패키지의 클래스에서만 접근 가능
protected

같은 패키지와 다른 패키지의 상속받은 클래스에서만 접근 가능

규칙성을 갖고 활용하게끔 제약을 걸어주도록 사용함

private 상속과 관계없이 다른 클래스에서 접근 불가

* private를 제외하면 상속을 하건 안 하건 똑같음

 

 

상속 상황에서의 접근 제어자 테스트

 

package 1 => A, B, D 클래스

 

package 2 => C, E 클래스

 

 

 

1) package1 안의 class A

package package1;

public class A {//상속 상황에서의 접근 제어자 테스트
	private int pri;
	int def;
	protected int pro;
	public int pub;
}

 

 

2) package1 안의 class B

package package1;

public class B extends A {
	public void set() {
		//pri = 1;
        
		def = 2;
		pro = 3;
		pub = 4;		
	}
}

private는 같은 클래스에서만 사용 가능하기 때문에 오류가 발생한다.

상속을 해도 자식 클래스에서는 접근이 불가하다.

protected memeber는 상속했기 때문에 사용이 가능하다.

private는 접근해서 사용하는게 불가능하다.

 

3) package2 안의 class C

package package2;

import package1.A;

public class C extends A {
	public void set() {
		//pri = 10;
		//def = 20;
		pro = 30;
		pub = 40;
	}
}

private private는 상속해서 사용이 불가능하다.
default는 같은 패키지에서만 가능하다. 패키지가 다르므로 사용이 불가능하다.
protected 다른 패키지여도 상속받으면 사용이 가능하다.
public 제한이 없으므로 마음껏 사용 가능하다.

 

4) package1 안의 class D

package package1;

public class D {
	public void set() {
		A a = new A();
		//a.pri = 100;
		a.def = 200;
		a.pro = 300;
		a.pub = 400;
	}
}

private 상속해서 사용이 불가능하다.
default a와 같은 패키지므로 사용이 가능하다.
protected 같은 패키지므로 사용이 가능하다.
public 제한이 없으므로 마음껏 사용 가능하다.

 

 

5) package2 안의 class E

package package2;

import package1.A;

public class E {
	public void set() {
		A a = new A();
		//a.pri = 1000;
		//a.def = 2000;
		//a.pro = 3000;
		a.pub = 4000;
	}
}

protected 
같은 패키지에서는 접근이 가능하다. 다른 패키지의 경우에는 상속을 받지 않는 한 접근이 불가능하다.
같은 패키지일 경우 상속을 받지 않아도 접근이 가능하다.
다른 패키지일 경우에는 상속을 받으면 접근이 가능하다.

 

변수 접근제어 메소드

장점 : 접근 제어 겸 부가 기능을 제공할 수 있음.

필터 기능(값을 받아서 저장하는 것 뿐만 아닌 값이 젣로 된 것인지 확인할 수 있음)

예) 은행에서 수표 받았을 때 진짜인지 확인해서 은행을 보호하는 과정

     자동차에서 가속할 경우 제한 소도 이상으로 속도가 증가되는 것을 막을 수 있음.

 

public void speedUp(int s) {
	speed = s;
	if(speed > 200) {
    	speed = 200;
    }
}

200 이상이면 넘지 못하고, 최대 200이 되도록 함

마이너스로 속도가 내려가면 안되기때문에 마이너스로 넘어가지 못하도록 함

최소치, 최대치를 내부적(자동차 안에서)으로 제약을 걸어주는 과정이다.

 

메소드 정의 방법

메소드는 클래스 영역에만 정의할 수 있음

(메소드 내부에 메소드를 정의할 수 없음)

접근 제어자 리턴타입 메소드명(매개변수 목록)
{
기능처리용 명령문들..
[return 변수/값/연산식;]
}

 

메소드의 장점

반복적인 코드를 줄이고, 코드의 관리가 용이

반복적으로 수행되는 여러 문장을 메서드로 작성

하나의 메서드는 한 가지 기능만 수행하도록 작성하는 것이 좋음
관련된 여러 문장을 메서드로 작성

 

반환형(리턴타입)

메소드 마지막에 반환을 처리하는 return 문장이 있을 경우, 반환하는 값에 따라 결정.

반환이 없을 경우 void를 사용.

 

메소드의 유형

1. 입력(매개변수)과 반환(return)이 있는 경우

2. 입력만 있는 경우

3. 반환만 있는 경우

4. 둘다 없는 경우

 

사용 방법

다른 메소드에서 호출하여 사용

반환값이 있을 경우 반환값을 받기 위한 변수를 사용.

int res = add(1, 2)l

1과 2를 더한 결과가 반환되어 res에 대입됨.

반환값이 없을 경우 메소드이름(매개값)만 작성

setSpeed(10);

10이 메소드에 들어감. 내부적 처리는 모름.

 

메소드 사용하는 경우

1. 매소드 이름

2. 매개변수(어떤 매개변수가 사용됐는지. 어떤 값이 들어가는지)

 

변수의 종류(멤버란)

클래스 내부에 존재하는 변수, 메소드를 멤버라고 함.

멤버 변수

클래스 내부의, 메소드 밖에 있는 변수

클래스 내부에서만 사용되는(존재하는) 변수

인스턴스 멤버변수, 클래스(static) 멤버변수

지역 변수

일반 지역변수, 매개변수

메소드 호출 시에만 생성되었다가 메소드 종료시 제거

 

클래스 변수

모든 인스턴스가 따로따로지만 다 같이 써야하는 데이터도 있다.

다른 영역에 저장이 되야된다.

 

클래스 멤버(static 멤버)

변수나 메소드 앞에 static 키워드가 붙는 멤버

인스턴스를 생성하지 않아도(new를 사용하지 않아도) 사용할 수 있는 멤버

1. 다른 클래스에서 사용할 경우

    클래스이름.변수 = 값;

    클래스이름. 메소드();

2. 같은 클래스에서 사용할 경우

    변수 = 값;

    메소드();;

인스턴스 멤버 변수나 메소드 앞에 static 키워드가 붙지 않는 멤버

 

Setter/ Getter 메소드

1. public 제어자 사용

2. 이름을 지을 때 앞에 무조건 set/get으로 설정해줌

3. 변수 이름을 첫글자를 대문자로 하여 set/get 뒤에 붙임.

cf. 규칙아닌 규칙이지만 이 규칙을 사용하면 내부적으로 자동으로 처리해주는 과정이 발생함

public void setSpeed(int s) {
	speed = s;
}

public int getSpeed() {
	return speed;
}    

값 받아서 집어넣는 메소드라서 set메소드라고 함

꺼내오기만 하는거니까 입력값은 없음

 

set/get을 하나 생성해놓고 set/get 자동으로 생성하기

source > Generate Getters and Setters...

Getter Setter 해주면 자동으로 생성됨

 

public String getModel() {
		return model;
	}

	public void setModel(String model) {
		model = model;
	}

this. 사용법

 

this. 장소적인 의미(여기 안에 있는 model 이라는 뜻) => private String model

this. 를 빼버리게 되면 구분이 안되는 상황이 발생하게 되므로 model을 통해 들어온 데이터를 model에 넣어줌

구별해주기 위해서 필드 안에 있는 변수일 경우 this.를 붙이는 규칙을 가짐

 

this. 일종의 참조변수(주소값 저장하는 데이터)

인스턴스가 내부적으로 this.라는 필드를 만들고 자기자신의 주소를 저장함

자기 자신의 model이라는 필드를 찾아가게끔 하기 위해 만들어둠

 

static 메소드와 인스턴스 메소드

static void add1(int a, int b){
	System.outprintln(a + " + " + b + " = " + (a+b));
}

void add2(int a, int b) {
		System.out.println(a + " + " + b + " = " + (a+b));
	}

add1과 add2 중 메인에서 호출 가능한건 add1임

 

add2형식으로 쓰려면 인스턴스가 있어야함

=> StaticTest st = new StaticTest();

자기 자신의 인스턴스 생성이 가능

 

public static void main(String[] args){

  StaticTest st = new StaticTest();
  add1(4, 5);
  st.add2(7, 8);
}

main은 콜백이라고도 부름

프로그램이 실행이 되려면 객체는 무조건 인스턴스가 있어야함

인스턴스는 클래스 안에서 만듦

프로그램 처음 시작할 때는 인스턴스가 없기 때문에 인스턴스가 없이 사용할 수 있게 해주기 위해 main을 사용함

main은 한 프로그램의 시작 지점을 알려줄 수 있는 역할을 함

 

static으로 만들어야 main안에서 사용가능하지만 static 안붙이고 만들 경우에는 자기자신의 인스턴스를 만들고, 호출해서 사용하면 됨

 

static 메소드와 인스턴스 메소드 차이점

stati 메소드 안에서는 static 멤버만 사용할 수 있다.

 

 

 

 

 

객체 지향의 4대 특성

1. 캡슐화(정보 은닉)

  상태 + 기능 = 객체

  변수 + 메소드 = class

  예제) TV, 의자, 책을 객체로 만들자 -> class로 만들자.

 

  class의 조건

- 상태(변수)와 행동(메소드)가 있어야함(class 안, class 밖에 선언)

 

  필드(변수)의 종류

 - 고유값(변경되지 않는 값)

 - 가변값(변경되는 값)

 메소드 : 가변값을 처리하는 기능을 제공

 정보은닉을 위한 장치 접근제어자

 

예제) class 실습 - TV

상태, 데이터 - on/off 상태, 채널, 볼륨, 크기.

상태(state)는 데이터를 저장하는 필드(field)라도 함.

필드는 고유값을 저장하는 필드돠 기능 처리 시 필요한 가변값을 저장하는 필드가 있음

 

on, off는 변경이 되는 가변 필드이므로 채널 바꿀 수 있는 기능을 제공해야함

따라서 가변필드 변경할 수 있는 메소드가 만들어져야함

채널은 숫자를 받아서 변경, 변수(공간)에 값 대입하면 변경됨

 

외부에 노출되야할 기능인 메소드 앞에는 public을 붙여줌

default가 붙어있지만 생략해서 쓰지 않음

기본적으로(가상적으로) default package가 생성됨

class Tv{
	//가변 필드(변수)
    private boolena power;
    private int channel;
    private int volumn;
    
    //고유 필드(변수)
    private int size;
    private String maker;
    
    public void onOff() {
    
    /*
    if(power == true) {
    	power = false;
    }
    else {  
    	power = true;
    }
    */
    
    power != power;
	}
    
    void channelChange(int num) {
    	channel = num;
        System.out.println("채널 변경 : " + channel);
    }
    
    void volumnUp() {
    	volumn++;
    	System.out.println("볼륨 변경 : " + volumn);
    }
    void volumnDown() {
    	volumn--;
    	System.out.println("볼륨 변경 : " + volumn);
    }

power에 있는거를 반전시켜서 power에 대입

ex. false일 경우 true로, true일 경우 false

 

객체의 종류

1. 완성품에 해당하는 객체 = 프로그램

2. 부품에 해당하는 객체

3. 정보를 저장하는 객체 

 

메소드 안에는 접근제어자 쓰지 않음. 클래스, 메소드, 필드 앞에만 사용함

 

예제) Class 실습 - 사람

연락처 프로그램의 정보 처리용

Data Transfer Objec(DTO)

class PersonInfo {
	String name;
	String phoneNum;
	String birth;
	String gender;
	String address;
	int age;
}

 

인스턴스 만들기(인스턴스 참조변수)

Tv myTv = new Tv();

//power 값 변경
myTv.power = true;
myTv.power = false;
myTv.size = 80;


//power = false;
//무엇의 power값인지 모르기 때문에 이 상태로는 사용이 불가능함

 

제어자 종류

-접근 제어자(public, defaul, protected, private)

public

접근 제한 없음

(접근이 가능한 경우에만 붙여줌)

default

같은 패키지에서는 제한 없음

(같은 폴더 안에 만들어진 파일끼리는 서로 사용 가능함)

protected 상속을 받을 경우 다른 패키지에서 접근 가능
private

접근 불가

(class를 벗어나게 되면 막혀서 사용 불가능해짐, 접근 제한이 최대)

-기타 제어자(접근 제어자가 아닌 제어자)

 final, abstract(추상화)

 

 

패키지 실습

package는 import 표현까지 포함되어 있음

목적에 맞게 분류, 한개의 폴더로 묶은 후 접근제한을 줌

 

user.package

<Main.java>

import 표현가지 포함되어 있는게 package이며 목적에 맞게 분류, 한 폴더로 묶은 후 접근제한을 줌

package user;

import com.*;


public class Main {

	public static void main(String[] args) {
		CarClass myCar = new CarClass();
		Dealer d1 = new Dealer();
	}
}

 

com.package

<CarClass.java>

package com;

public class CarClass {
	//고유 정보
	String modelName;
	public int price;
	
	//가변 정보
	Tire t1, t2, t3, t4;//배열 사용도 가능
}

접근제어자가 없으면 아무것도 안 붙어있는게 아닌 default 접근제어자가 붙어있음.

 

부품클래스 : 다른 클래스 내부에 필요하게된 클래스

ex)car class는 tire class에 의존하게됨

 

의존성 : 부품에 의존하게되는 특성을 나타나게 됨

 

필드에 다른 인스턴스의 정보가 저장

 

<Dealer.java>

package com;

public class Dealer {
	CarClass car1 = new CarClass();
	
	public void method1() {
		car1.modelName = "아반떼";		
	}
}

다른 class에서 불러오기 위해서는 public void method1() { ... } 안에서 사용해야됨.

 

필요하에 package를 만들어야함.

반드시 해야하는 것이 아니고 효율을 높이기 위해서 package를 사용함

유지보수에 편리하기 때문에 사용함

 

<Tire.java>

package com;

public class Tire {
	private String maker;//변수에는 private 붙여주는게 좋음
	private int size;
	private String type;
}

변수에는 private 붙여주는게 좋음

 

 

같은 파일인 경우에는 public은 하나에만 붙일 수 있음

public이 되는거는 파일 이름만 같은 클래스 앞에 public을 붙임

같은 파일에 여러 개의 클래스를 만들 경우에는 나머지 클래스들은 public을 붙이면 안됨

+ Recent posts