본문 바로가기
코딩도전기/JAVA

CODO Day13_JAVA(Overload/멤버 호출/Static/Final/Import/접근제한자)

by 코도꼬마 2023. 2. 17.

Overload*

  • 생성자 overload  :  같은 이름으로 여러개의 생성자를 만드는 것                                                                                    - 생성자 이름은 class 이름과 같아야하기 때문에 원칙적으로 1클래스 1생성자임
  • 매개변수개수나 형태달라야
package chap04.ex06.overload;

public class NoteBook {
	
	String name;
	String color;
	int price;
	
	//노트북을 만들 때 다음의 경우가 있다
	//1. 일단 만들어 놓는 경우
	public NoteBook() { //생성자
			
		}
	
	//2. 모델명을 만들면서 지정하는 경우
	public NoteBook(String name) { //생성자
		this.name = name;
	}
	
	//3. 모델명과 가격을 지정하는 경우
	public NoteBook(String name, int price) { //생성자
		this.name = name;
		this.price = price;
	}	
	
	//4. 모델명과 색상을 지정하는 경우
	public NoteBook(String n, String c) { //생성자
		//받아온 변수와 넣을 변수의 이름이 다르면 this가 없어도 된다.
		n = name;
		c = color;
	}	
	
	//5. 모델명, 색상, 가격을 지정하는 경우
	public NoteBook(String name, String color, int price) { //생성자
		this.name = name;
		this.color = color;
		this.price = price;
	}	

}

  -  overload(과적) : 원래는 생성자를 같은 이름으로 2개이상 만드는 것이 불가능하지만 특정 조건에 의해                                          허용해주는 것
  -  조건 : 매개변수의 갯수와 데이터 타입이 달라야한다.
  -  왜 필요한가? 생성방법이 달라질 때마다 클래스를 만들어야 한다(1클래스 1생성자이기 때문)

 

  • 생성자를 불러와 객체화(복사)하여 사용
package chap04.ex06.overload;

public class Main {

	public static void main(String[] args) {

		NoteBook note = new NoteBook();
		NoteBook note1 = new NoteBook("GRAM");
		NoteBook note2 = new NoteBook("MAC-BOOK", 3000000);
		NoteBook note3 = new NoteBook("NOTE", "white");
		NoteBook note4 = new NoteBook("gramming", "black", 3300000);

	}

}
  • overload(과적) : 원래는 생성자를 같은 이름으로 2개이상 만드는 것이 불가능하지만 특정 조건에 의해                                         허용해주는 것
  • 조건 : 매개변수의 갯수와 데이터 타입이 달라야한다.
  • 왜 필요한가? 생성방법이 달라질 때마다 클래스를 만들어야 한다(1클래스 1생성자이기 때문)

 

 

 

class 멤버 호출

  • Class에 접근(instance)하면 그 class의 멤버 사용 가능

 

  • 생성자(constructor) 객체화&호출
package chap04.ex07.member;

public class Car {
	
	int gear;
	boolean on;
	
	public Car() {		
		gear = 0;
		on = false;		
	}
	
	void start() {
		
		if(on == false) {
			System.out.println("시동이 걸렸습니다");
			on = true;
		}else {
			System.out.println("이미 시동이 걸려있습니다");
		}
		
	}
	
	void change(int gear) {
		
		System.out.println(gear + "단으로 변속했습니다");
		this.gear = gear;
		
	}

}
package chap04.ex07.member;

public class Main {

	public static void main(String[] args) {
		
		//Car의 멤버를 사용하기 위해서는 복사(객체화)해야 함
		Car car = new Car();  
        
		car.start();
		car.change(3);
		System.out.println("시동상태 : " + car.on);

	}

}

 

 

  • 메서드(method) 객체화&호출
package chap04.ex08.overload;

public class Calculator {

	int plus (int a, int b) {
		System.out.println(a+b);
		return a+b;	      
	}

	String plusStr (String a, String b ) {
		System.out.println(a+b);
		return a+b;
	}

	String plusIntStr (int a, String b) {
		System.out.println(a+b);
		return a+b;
	}

	double plusDouInt (double a , int b) {
		System.out.println(a+b);
		return a+b;
	}
	
	String plusDouStr (double a , String b) {
		System.out.println(a+b);
		return a+b;
	}

}

  -  위의 클래스를 객체화(instance)하여 사용할 경우 각 메서드 마다 연산할 수 있는 타입이 다르기 때문에          모든 메서드의이름과 기능을 알아야한다는 단점이 있음

  -  아래의 클래스는 모든 생성자들을 하나의 이름으로 만듦(overload)으로 하나의 이름으로 생성자들을 불       러와 어떤 타입을 대입하든 연산 가능

package chap04.ex08.overload;

public class OverPlus {

	int plus (int a, int b) {
		System.out.println(a+b);
		return a+b;	      
	}

	String plus (String a, String b ) {
		System.out.println(a+b);
		return a+b;
	}

	String plus (int a, String b) {
		System.out.println(a+b);
		return a+b;
	}

	double plus (double a , int b) {
		System.out.println(a+b);
		return a+b;
	}
	
	String plus (double a , String b) {
		System.out.println(a+b);
		return a+b;
	}

}

 

  -  Main 클래스(calculator와 overplus 클래스를 객체화하여 사용)

package chap04.ex08.overload;

public class Main {

	public static void main(String[] args) {
		
		Calculator cal = new Calculator();
	//오버로드를 사용하지 않으면 더하기 하나를 해도 수많은 이름을 알아야 한다.
		cal.plusStr("a", "b");
		
		OverPlus over = new OverPlus();
		//오버로드를 사용하면 하나의 이름에 어떤 값을 넣어도 알아서 동작함
		over.plus("a", "b");

	}

}

 

 

 

정적 멤버와 static

  • Static영역은 클래스 원본이 저장되는 곳
  • Member에게 static키워드를 붙이면 Static영역에 저장
  • static member는 객체화하지 않고 사용(원본만 사용 - 변경X : 변경되면 안되는 것)  *불가피한 경우 임시로 공유해줌

 

  • 원본을 건드릴 때와 복사본을 건드릴 때의 차이
package chap04.ex09.smember;

public class Sub {  // class
	
	//member field
	static int sField = 134;  //static member : 원본 영역에 저장
	int field = 0;
	
	//member method	
	static int plus(int a, int b) {
		return a+b;
	}
	
	static int minus(int a, int b) {
		return a-b;
	}
	
	int multi(int a, int b) {
		return a+b;
	}

}

 

  -  저장영역이 다를 경우 각 멤버들을 부르는 방법

package chap04.ex09.smember;

public class Main {

	public static void main(String[] args) {
		
		//일반적으로 사용하는 방법
		Sub sub = new Sub();
		System.out.println("멤버 필드 : " + sub.field);
		System.out.println("멤버 메서드 : " + sub.multi(3, 4));
		
		//static 멤버 사용하는 방법(원본에 직접 접근)
		System.out.println("static 멤버 필드 : " + Sub.sField);
		System.out.println("static 멤버 메서드 : " + Sub.minus(10, 5));
		
	//복사복에서 원본 접근이 불가능한가? 가능하지만 정식적인 방법이 아님
System.out.println("static 멤버 메서드 - 복사본에서 접근 : " + sub.plus(10, 5));
		//*불가피한 경우 임시로 공유해줌
		
		/*원본과 복사본의 차이?*/
		Sub sub2 = new Sub();
		sub.field = 1000;
		//복사본은 서로에게 영향을 줄 수 없다.
		System.out.println("sub : " + sub.field);
		System.out.println("sub2 : " + sub2.field);
		System.out.println("===============");
		
		//static은 원본이기 때문에 변경하면 모두에게 영향을 줌
		sub.sField = 3000;
		System.out.println("sub : " + sub.sField);
		System.out.println("sub2 : " + sub.sField);

	}

}
package chap04.ex09.smember;

public class Inner {

	public static void main(String[] args) {  //static member
		// 특수한 상황
		
		stMsg("정적 멤버 호출");  
		//같은 클래스에서는 그냥 메서드를 호출하면 된다.
		
		//heapMsg;
		//같은 클래스라 하더라도 저장영역이 다르면 불러올 수 없다.
//이 경우 같은 클래스라 하더라도 영역이 다르면 일반 멤버는 복사해서 써야한다.
		Inner inner = new Inner();
		inner.heepMsg("일반 멤버 호출");

	}
	
	static void stMsg(String msg) {
		System.out.println("static member method : " + msg);
	}
	
	void heepMsg(String msg) {
		System.out.println("member method : " + msg);
		
	//같은 클래스라도 다른 영역이면 정적 멤버는 원본으로 접근해서 써야한다.
		Inner.stMsg("일반 멤버가 부르는 정적 멤버");
	}

}

 

 

 

Final

  • final은 한번 지정되면 프로그램 종료 시까지 변경 불가능
  • final은 생성자에서만 초기화 가능
  • Static final의 경우 객체화, 초기화가 되지 않아 불변의 값으로 간주
    - Static final 필드를 상수(Constant)라고 하며 모두 대문자로 표기
package chap04.ex10.readonly;

public class Person {
	
//final : 생성자만 초기화가 가능(이후 프로그램이 종료될 때 까지 바뀌지 않음)
	final String nation;
	final String name;
	
	//static final : 상수, 불변의 값, 개발자가 작성하면 이후로 변경할 수 없다.
	static final String SSN = "800902-1234567";
			

	public Person(String nation, String name) { 
    //생성자에서 final 값을 초기화할 수 있다
		this.name = name;
		this.nation = nation;

		
	}

}
package chap04.ex10.readonly;

public class Main {

	public static void main(String[] args) {
		
		Person p =new Person("대한민국", "김지훈");
		System.out.println(p.nation);
		System.out.println(p.name);
		System.out.println(Person.SSN);  
		//static이기 때문에 원본을 불러와야함

		/* final은 값이 한번 들어가면 바꿀 수 없다
		p.nation = "KOREA";
		p.name = "홍길동";
		*/
		
	}

}

 

 

 

Import

  • 다른 package(폴더)에 있는 class를 불러와 객체화(instance)할 경우 import문을 사용(import class 위치;)

package chap04.ex11.imp;

public class Info {
	
	int age = 30;
	String job = "개발자";

}
package chap04.ex11.imp;

import chap04.ex08.overload.OverPlus;

public class Main {

	public static void main(String[] args) {

		//같은 패키지는 import문이 필요없다
		Info info = new Info();
		System.out.println(info.age);
		System.out.println(info.job);
		
		//다른 패키지의 클래스 호출 시 import문 필요
		OverPlus over = new OverPlus();  
		//chap04.ex08.overload.OverPlus class의 매서드
	}

}

 

 

접근 제한자

  • 사용자가 사용할 수 있는 코드도 있지만 내부적으로만 사용할 코드도 있어 접근을 허용하거나 제한할 수 있음

package chap04.ex11.imp;

import chap04.ex08.overload.OverPlus;

public class Main {

	public static void main(String[] args) {

		OverPlus over = new OverPlus();
		//다른 패키지의 클래스를 불러왔지만 메서드는 쓸 수 없다 
		// -> 매서드 접근제한자가 default값으로 되어있기 때문
        
//OverPlus클래스의 plus매서드 접근제한자를 default(기본:설정X)->public으로 변경
		over.plus(3, 4);  
		
		//접근 제한자 : 특정 멤버의 접근 영역을 제한
		//public : 아무 제한이 없음
		//default : 같은 패키지만 사용 가능
		//private : 클래스 안에서만 사용 가능

	}

}

 

  • 이렇듯 특정 부분의 접근을 제한하는 것을 캡슐화(Encapsulation)라고 함

 

  • Private 변수 및 메서드는 외부 class에서 사용이 불가능 / 외부에서 꼭 써야 할 경우 불러오는 방법
package chap04.ex12.prv;

public class Computer {
	
	private boolean power;
	private int panSpeed;
	private int temp = 10;
	
	
	public boolean getPower() {  
    //boolean값의 경우 get 대신 is로 사용하기도 함
		return power;
	}
	public void setPower(boolean power) {
		this.power = power;
	}
	public int getTemp() {
		return temp;
	}
	public void setPanSpeed(int panSpeed) {
		this.panSpeed = panSpeed;
		//받아온 팬 속도로 온도를 조절
		this.temp = 110 - this.panSpeed;
	}
}	
//private필드 중에서 가져오거나, 변경하고 싶은 것들은 
//getter(), setter() 매서드를 활용해서 가능(alt+shift+S)

//getter() : 값을 불러올 수만 있음, setter() : 값을 변경할 수 있음
package chap04.ex12.prv;

public class Main {

	public static void main(String[] args) {
		
		Computer com = new Computer();
		
		com.getPower();
		com.setPower(true);
		
		com.setPanSpeed(10);
		System.out.println(com.getTemp());  // console : 100	

	}

}