갈림길 이정표

[6. 클래스] 본문

Programming Language/Java 마스터하기(feat. 이것이 자바다)

[6. 클래스]

이몽뇽 2020. 7. 19. 23:28

6.1 객체지향프로그래밍 .......................................................................................................
6.2 객체와클래스...................................................................................................................
6.3 클래스 선언.......................................................................................................................
6.4 객체생성과클래스변수...................................................................................................
6.5 클래스의 구성 멤버 ...........................................................................................................
6.6 필드..................................................................................................................................
6.7 생성자.............................................................................................................................
6.8 메소드

메소드 선언

접근제한자 리턴타입 메소드 이름 (매개 변수 선언) {                  
Acess Modifier return type method Name parameter, arguments  
public / protected / (defualt) / private void /
... (return 변수)
  ex.
String tiger
                }


6.9 인스턴스 멤버와 this.....................................................................................
6.10 정적 멤버와 static......................................................................................
6.11 final 필드와 상수..........................................................................................................
6.12 패키지..........................................................................................................................
6.13 접근 제한자..................................................................................................................
6.14 Getter와 Setter 메소드..............................................................................................
6.15 어노테이션....................................................................................................................

package pack1;
//패키지 = 폴더같은 것

//class = 설계도 (하나면 필요없지만, 여러개를 생성하고 싶을 때 필요)
//속성(member field[전역변수])과 행위(method) - 엑셀의 함수 기능같은 건가봐
//이세상에 없는 제품(Class)을 만들기 위해 OR 이미 만들어진 제품 활용(Class)
//우리는 후자에 초점 (이미 엄청난 양의 Class 만들어져 있다.) - 만들어진 엑셀파일 인가봐
//부품Class 조립하여 만들어진 완성품도 Class
//새로운 Class 생성은 힘든 것
//이미 만들어진 걸로 홈페이지, 게임, .. 등 창작 가능 - 마치 레고 처럼 (객체지향)
//내가 만들고 싶은 프로그램 = 이미 만들어진 Class 가지고 조립하면 됨

//javascript(함수지향언어) ->  폴리모피즘 활용 할 거임
//java.lang 원채 많이 쓰여서 굳이 import 안해도 됨
//하지만, 다른 기능들은 import 필수

//Class가 모여 Library, Library가 길면 Framework

public class Car { // [접근 지정자][기타 제한자] class 클래스명(첫글자 대문자, 소스파일 완전 일치)
//	전역 (접근 지정자 default) 제한자는 있어도 private은 안됨
	int wheel; //member field (멤버변수, 전역변수)
	public int engine = 1;
	private int airbag = 1;		// [접근 지정자][기타 제한자] type 변수명(멤버필드)
	private int speed;			// 캡슐화 (Car class 안에서만 호출 가능)
	public String name;			// Car class 밖에서도 호출 가능
	
	public Car() { // 생성자는 임의 호출 불가. ①new에 의해 호출, ②생성자에 의해 호출
		//Constructor(생성자): 객체 생성 시 가장 먼저 수행되는 method
		//초기화를 담당
		//class와 같은 이름 (반환 안함)
		System.out.println("난 생성자야!");
		name = "용용";
		wheel = 4;
		int mbc = 11;  //지역변수
	}
	
	public void abc() {		// [접근 지정자][기타 지정자] 변환형 메소드형(argument,..){}    
		//멤버 method
		System.out.println("abc 메소드 수행");
		int kbs = 3;  //지역변수 (메소드 안 local variable)
		def(); // 외부에선 호출 불가능 해서 내부에서 부름
	}
	
	private void def() {    // 오직 class안에서만 호출 가능
		System.out.println("def 메소드 수행");
	}
	void efg() { 			// 접근제한자가 아무것도 안 정해져 있으면 friendly, default
		System.out.println("efg 메소드 수행");
	}
	
	//run 안됨 , 그냥 설계도만 만든 것 
}
package pack1;

public class MyFirstProgram {
//Camel표기법(각단어 시작시 대문자)
	public static void main(String[] args) {
		// 응용 프로그램의 시작 메소드
		System.out.println("프로그램 설계 시작");
		int kbs = 9;
		System.out.println("TV는 " + kbs);
		System.out.println("-----------------");
		Car car1 = new Car(); //객체 생성됨 (instance)
		//  car1 = 객체변수 (instance variable)
		//만들지 않은 class = 상속(heritage)
//		Car car1 = null; //java.NullPointerException: instance가 없음 주소 참조 하질 않음
//		이럴 경우 갑자기 사라지진 않지만 메모리 확보를 위해 자동소멸 (소멸자 필요없음)
//		C의 소멸자 생성, Python의 garbage collector
//		So, 생성자 내용 없으면 안쓰면 돼
		System.out.println("wheel: " + car1.wheel); //기본 값 안주면 숫자는 0 (실수는 0.0)문자는 빈칸
		System.out.println("name: " + car1.name); //문자열은 null이 기본
		System.out.println("enging: " + car1.engine);
		car1.abc();
		System.out.println(car1); //pack1.Car@5305068a
//		System.out.println(car1.toString());
		System.out.println("-----------------");
		System.out.println("프로그램 종료");

	}

}
package pack1;

public class Programmer { 	//접근지정자는 class의 멤버에게만 부여가능
//	public String nickname; //(값이 없으니)null이 초기치
							// new String() 쓰기 귀찮음을 해소
	public String nickname = ""; //(공백)이 초기치
	String spec = "자바";
//	private int age;		//(값이 없으니) 초기값: 0
	private int age = 0;	//이 class 내에서만 유효 //보안을 위함
//	단, 멤버 변수 일때만!
	
	public static String motto = "자바에 미치자!"; //static 멤버(기울임 폰트)
	public final double PI = 3.14; //상수값 고정값 (통상 대문자로만 씀!)
	
	public Programmer() { //생성자 (constructor) //새로운 instance 선언할 때 실행되는 것 또는 값
		System.out.println("난 생성자! , 초기화를 담당");
		//초기화 작업이 없다면 기본값(적지 않아도 내부적으로 컴파일러가 인정)
		nickname = "자바체질"; //초기값 생김
	}
	
	public void displayData() { // void는 빈손으로 돌아가 (return 값이 없음)
		int version = 14;
		//		String sp = spec;	//여기 sp는 지역 변수
		String sp = reSpec(version); //메소드 호출 (private 메소드 이지만 이 class 내에서 부른 거라 호출 가능)
		System.out.println("별명이 " + nickname + "은 " + age + " 살, 보유기술은 " + sp);
	}
	
	private String reSpec(int ver) { 	//데이터 타입이 있음 (match해야됨), input은 복수개 입력 가능
		//int ver (argument, parameter) = version
		String imsi = "언어 중 " + spec + ver; //(입력 값, 반환 값, 호출값 모두 match시켜야 함)
//		문자열 범위가 더 크기 때문에  int ver도 String 으로 인식
//		String imsi = "언어 중 " + spec + Integer.toString(ver);
		return imsi; 			//return 값이 있음 (한 개의 값만 가져 갈 수 있음)
	}
	
//	void는 빈손으로 output, 메소드 ('괄호') 는 빈손으로 input
//	변수에게 값을 주는 방법 :치환 (assign) & 
	
//	private 멤버를 외부 클래스 에서 참조하고 싶을 때 (읽기)
	public int getAge() { 	//getter (값 호출하여 읽기)
//		System.out.println("age: " + age);
		return age;
	}
	
	public void setAge(int password, int aa) { //private 멤버를 외부 클래스에서 참조 (값 수정)
		if(password==11) {
			age = aa;			//seter (값 설정 가능)
		}else {
			System.out.println("비밀번호 불일치로 값 변경 불가");
		}
//	public void setAge(int age) {
//		this.age = age;		//전역 변수(필드) 와 지역변수 구분을 위해 'this.(전역변수)'
		//컴퓨터는 지역변수부터 실행, 후에 전역 변수 실행 (this=현재 class의 멤버야 라는 뜻)
//	}
//		getter setter = 캡슐화 (get, set + 멤버필드 이름)
	}
	public static void myMethod() {
//		System.out.println("나이는 " + age);
		System.out.println("motto " + motto);
		//static 은 이미 만들어진 것은 static 정보만 활용 가능
	}
	
	public void myMethod2() {
		System.out.println("나이는 " + age);
		System.out.println("motto " + motto);
		//새로 만드는 멤버는 새로만든 정보와 static 정보 활용 가능
	}
	

}
package pack1;

public class ProgrammerMain { //응용프로그램 실행 class

	public static void main(String[] args) { // 시작점
		System.out.println("이러저러하다가");
//		Programmer tom = null 이러면 안됌 (기본값이 없어서 참조할 주소가 없음)
		Programmer tom = new Programmer(); //[주소 참조형]생성자 =초기값 (없으면 기본값)
//		tom. -> 모든 class 에서 제공하는 기본 java basic class
		System.out.println(tom.toString()); //->정확한 명령어
		System.out.println(tom); //하지만 축약 허용 (결과 같음)
		
		System.out.println("=======");
		System.out.println("tom의 별명은 " + tom.nickname); //tom.nickname= Programmer class 참조 ,nickname= 지금main 내에서 찾음
//		System.out.println("tom의 나이는 " + tom.age); -> private 멤버 라서 참조 불가 (외부로 호출 불가능 상태)
		System.out.println("tom의 보유기술은 " + tom.spec);  //대문자는 class
		//변수.멤버필드 & 변수.메소드() => 다른 class에서 참조
//		tom = null;
//		System.out.println("tom의 별명은 " + tom.nickname); //err.참조하고 있던 주소를 일어버림.
//		System.out.println("tom의 별명은 " + tom);

//		err 종류 : syntax(문법), compiler(참조 주소), logic
		
		tom.nickname = "자바 귀신";
		System.out.println("tom의 별명은 " + tom.nickname);
		
		tom.displayData(); //ctrl + 왼쪽 클릭 하면 해당 메소드 class파일로 이동
//		tom.age; 이거는 안됨
//		tom.nice(); //캡슐화 (private 멤버 age 를 public method 로 참조 가능
		int nai = tom.getAge();
		System.out.println("tom나이" + nai);
		tom.setAge(123, 22); //비밀 번호 불일치로 값이 안바뀜
		nai = tom.getAge(); // int 없앰 (위에서 선언 했기 때문)
		System.out.println("tom나이" + nai);
		
		System.out.println();
		System.out.println(tom.motto);
		System.out.println(Programmer.motto); //static으로 객체변수가 아닌 class의 이름으로 부를 수 있음
//		tom.PI = 1234.0; //err. final 멤버이므로  수정 불가
		System.out.println(tom.PI);  //참조만 가능
		
		System.out.println();
		Programmer.myMethod();
		tom.myMethod2();
		
		System.out.println("-------------");
		Programmer james = new Programmer(); // 새로운 객체 생성
		System.out.println("james의 별명은 " + james.nickname);
		System.out.println("james의 보유기술은 " + james.spec);
		james.displayData(); // tom과 비슷해 보여도 다른 객체 (참조 주소가 다름)
		
		System.out.println();
		System.out.println(tom.toString());
		System.out.println(james.toString());
	}

}
package pack1;
//Method overload 연습 (동일한 이름의 메소드[인수는 다름]를 여러개 선언)
//ctrl + space 눌렀을 때 옵션 제공하는 것 (재명령)
public class Animal { //새로운 타입을 만드는 것
	private int leg = 4;
	private int age;
	private String name;
	
	public final static int KEYBOARD = 1;
	//   (고정값)(class이름으로 호출 가능)
	
	public Animal() { //생성자 constructor
		//적어줄 내용 없으면 생략 가능
	}
	
	public Animal(int leg) { //constructor overloading
//(필드가 private일 때 외부에서 호출하는 방법: ①constructor overloading, ②setter 설정 (메소드 활용))
		this.leg = leg;
	}
	
	public Animal(String name) { //constructor overloading
		this.name = name;
	}
	
	public Animal(String name, int leg) { //constructor overloading
		this.name = name;
		this.leg = leg;

	}
	public void display() {
		System.out.println("leg: " + leg + ", age: " + age + ", name:" + name);
		
	}
	
	public void display(int nai) { //Method overloading (이름은 같은데 argument가 다름), 객체 이름은 달라도 행위가 같을때
		age = nai;					//argument 타입이나 개수, 순서가 다르면 됨
		System.out.println("leg: " + leg + ", age: " + age + ", name:" + name);
	}
	
	public void display(String name) {
		this.name = name; 		//지역변수와 전역 변수  구분을 위함
			System.out.println("leg: " + leg + ", age: " + age + ", name:" + this.name);
	}
	public void display(int nai, String name) {
		age = nai;
		this.name = name; 
		System.out.println("leg: " + leg + ", age: " + age + ", name:" + this.name);
	}
	public void display(String name, int nai) {
		age = nai;
		this.name = name; 
		System.out.println("leg: " + leg + ", age: " + age + ", name:" + this.name);
	}
//	public void display(int leg) { 
//		this.leg = leg;			
//		System.out.println("leg: " + leg + ", age: " + age + ", name:" + name);
//	}  ---> err. nai 옵션과 타입, 갯수 똑같기 때문
//	public display(int nai) { //Method overloading (이름은 같은데 argument가 다름), 객체 이름은 달라도 행위가 같을때
//		age = nai;					//argument 타입이나 개수, 순서가 다르면 됨
//		System.out.println("leg: " + leg + ", age: " + age + ", name:" + name);
//	} ---> err. nai 옵션의 타입, 갯수 똑같기 때문
	
	public static void abc() {
		System.out.println(KEYBOARD);
	}
}
package pack1;

public class AnimalMain {

	public static void main(String[] args) {
		Animal tiger = new Animal();
		tiger.display();
		tiger.display(5); //--->메소드 오버로딩 (새로운 값 부여)
		tiger.display("호돌이"); //프로그램에게 선택권을 줌
		tiger.display(2, "호순이");
		tiger.display("호동이", 3);
		
		System.out.println(Animal.KEYBOARD); // 필드로 호출
		Animal.abc();	// 메소드로 호출 = 같은 결과(그래도 static 은 아껴써라 메모리 차지 하니까)
		
		System.out.println("\n생성자 오버로딩------");
		Animal lion = new Animal("사자", 5); //--->생성자 오버로딩 (초기값 설정)
		lion.display();
				
		System.out.println();
		Animal hen = new Animal(2);
		hen.display();
		hen.display(4, "닭");
	}

}
package pack1;

public class Bank {
	private int money = 1000; //가입 축하금으로 1000원 은행에서 넣어 줌
	// private 은 어디서도 호출 불가
	int imsi = 10; // defualt 는 같은 패키지에서 호출 가능
	public int imsi2 = 20; // public 는 다른 패키지에서 import할 때 호출 가능
	public Bank() { //생성자
		
	}
	
	public Bank(int money) {
		this.money = money;
	}
	
	public void deposit(int amount) { //입금
		if(amount > 0) money += amount;
	}
	
	public void withdraw(int amount) {
		if((amount > 0) && (money - amount >=0)) {
			money -= amount;
		}else {
			System.out.println("은행 잔고가 부족합니다!");
		}
	}
	
	public int getMoney() { //잔금 확인 getter (money 값 호출[읽기]해야 함)
		return money;
	}
}
package pack1;

public class BankMain {

	public static void main(String[] args) {
		//package, 객체 주소, 참조 범위 연습
		Bank tom = new Bank(); // 빈손으로 왔다 (아무것도 안하지만 객체 생성)
		tom.deposit(5000);
		tom.withdraw(3000);
		System.out.println("tom의 통장 잔고:" + tom.getMoney());
		tom.withdraw(7000);
		
		System.out.println();
		Bank oscar = new Bank(5000);
		oscar.deposit(5000);
		oscar.withdraw(3000);
		System.out.println("oscar의 통장 잔고:" + oscar.getMoney());
		
		System.out.println("\n객체 주소 관련---------------");
		System.out.println("tom : " + tom);// 자바는 시스템 제어를 위한 언어가 아님 = 절대 주소를 바꿀 수 없음 (불러올 수는 있음)
		System.out.println("oscar : " + oscar); //16진수
		System.out.println("oscar : " + oscar.hashCode()); //10진수
		
		Bank james = null;
		System.out.println("james :" + james); //Bank 타입이지만 주소를 참조 할 수 없는 상태
//		System.out.println("james의 통장 잔고:" + james.getMoney()); //err. syntax는 아니고 runtime err. ->
		james = oscar;
		System.out.println("james의 통장 잔고:" + james.getMoney()); //다형성
//		같은 Bank type oscar -> james 주소 값 치환!(oscar가 참조하면 james 도 참조)
		System.out.println("oscar : " + oscar);
		System.out.println("james :" + james); // just 주소 치환
		
		System.out.println();
		if(james == oscar) //기본형 또는 참조형 변수가 같은 지 비교할 때 유용!
							// ==: 일치 여부 / =: 치환, 대입
			System.out.println("둘은 주소가 같음");
		else
			System.out.println("둘은 주소가 다름");
		
		System.out.println();
		if(james == tom)
			System.out.println("둘은 주소 같음");
		else
			System.out.println("둘은 주소 다름");
		
		if(james instanceof Bank) //instanceof : class 타입 비교 연산자
//		if(james instanceof Bank == true) <- 원래는 이거
			System.out.println("Banktype O");
		else
			System.out.println("Banktype X");
		
		System.out.println("\nString type 값의 비교----------");
//		String은 class 이지만 기본형처럼 쓸 수 있게 함
		String ss1 = "kor";
		String ss2 = new String();
		ss2 = "kor";				//-> 원래 이렇게 두줄 써야됨
		String ss3 = new String("kor");
		String ss4 = new String("KOR");
		System.out.println(ss1 + " " + ss2 + " " + ss3 + " " + ss4);
		
		//일반 객체 변수 비교 와 String 비교는 다름 
		
		if(ss1 == ss2)
			System.out.println("같음1");
		else
			System.out.println("다름1");
		
		if(ss1 == ss3)	//문자열(String)을 비교할 때는 이렇게 비교하면 안된다
			System.out.println("같음2");
		else
			System.out.println("다름2");
//		사실
//		저장 영역: Static/stack/heap
//		근데 사실 heap은 literal pool 영역(순수 문자 영역)이 있음
//		new String(Original) 과 new String() 메소드는 다르기 때문
		
//		String 객체의 값을 비교시 ==가 아니라 객체변수명.equals() 을 사용
		
		if(ss1.equals(ss2))
			System.out.println("같음1");
		else
			System.out.println("다름1");
		
		if(ss1.equals(ss3))		//대소문자 구분
			System.out.println("같음2");
		else
			System.out.println("다름2");
		
		if(ss1.equalsIgnoreCase(ss3))		//대소문자 구분 안함
			System.out.println("같음3");
		else
			System.out.println("다름3");
		
		if(ss1.equalsIgnoreCase(ss4))		//대소문자 구분 안함
			System.out.println("같음4");
		else
			System.out.println("다름4");
		
		System.out.println("\n배열------------");
		int ar1[] = {1, 2, 3};
		System.out.println(ar1); //배열의 대표명은 배열 객체의 시작 주소를 기억 (참조형)
		System.out.println(ar1[0] + " " + ar1[1]);
		
		System.out.println();
		int[][] ar2 = {{1, 2, 3}, {4, 5, 6}};
		System.out.println(ar2);
		System.out.println(ar2[0]);
		System.out.println(ar2[1]);
		System.out.println(ar2[0][0]);
	}
	

}

싱글톤 패턴 (Singleton pattern) (feat.GOF)

package pack1;

public class SingleClass {
	int kor = 90;
	
	private static SingleClass class1 = new SingleClass(); //자기 스스로 new
	public static SingleClass getInstance() {
		return class1; //static method는 static member 만 사용 가능
	}
}
package pack1;

public class SingleMain {

	public static void main(String[] args) {
		// Gof의 디자인 패턴 중 싱글톤(Singleton pattern)
		// 애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만들어 사용하는 디자인패턴.

		SingleClass s1 = new SingleClass();
		SingleClass s2 = new SingleClass();
		System.out.println(s1.kor);
		System.out.println(s2.kor);
		System.out.println(s1 + " " + s2);
		
		System.out.println("---------------");
		SingleClass s3 = SingleClass.getInstance();
		SingleClass s4 = SingleClass.getInstance(); //이미 new 했음
		System.out.println(s3.kor);
		System.out.println(s4.kor); //주소가 같음(우리가 보통 사용하는 웹 ex.네이버 사이트 등)
		System.out.println(s3 + " " + s4); //불특정 client 다수가 사용하는 공유된 하나의 객체 = 싱글톤

	}

}
Comments