[필기정리] Day8-1 - static변수, 메소드 오버로딩 등

SW/Java

2020. 6. 21. 19:01

# Static 변수(클래스 변수) : 모든 객체가 공유하는 변수, 클래스 변수라고도 함

                                   (클래스 이름으로 접근가능하기때문!)

class Number
{
	public int num1;  // num1 부분은 인스턴스 변수라고도 함
	public static int num2;
	Number()
	{
		num1++;
		num2++;
	}

 

 

class NumberMain
{
	public static void main(String[] args)
	{
		Number n1 = new Number();
		Number n2 = new Number();
		Number n3 = new Number();
		
		System.out.println(n1.num1); //  1 출력
		System.out.println(n1.num2); // 3 출력
		System.out.println(Number.num2); // 3 출력

		n1.num1++;
		n3.num1+=2;
		n1.printNumber1();  // 2 3 출력
		n2.printNumber1(); // 1 3 출력
		n3.printNumber1(); // 3 3 출력
		n2.printNumber2();
		n3.printNumber1();
		Number.printNumber2();  
	}
}

- 객체가 생성되지 않은 상태에서도 클래스 변수를 사용할 수 있다

- 인스턴스 변수가 최초로 호출되는 순간 new 썼을 때 인스턴스 변수 초기화됨

- 클래스 변수가 최초로 호출되는 순간 초기화가 이루어진다

class Number
{
	public int num1;
	public static int num2;
	Number()
	{
		num1++;
		num2++;
	}
	public void printNumber1()
	{
		System.out.println(num1+" "+num2);
	}
	public static void printNumber2() // 스테틱메소드(클래스메소드) 
	{
		System.out.println(num2);
	}

- 스테틱메소드에서는 인스턴스변수를 참조할 수가 없다

  스테틱메소드에서는 스테틱변수만 참조할 수 있다.

 

ex)

Q.

class SimpleMath    // 단순 계산 클래스
{
	public static final double PI=3.1415;	
	public double add(double n1, double n2){ return n1+n2; }
	public double min(double n1, double n2){ return n1-n2; }
	public double mul(double n1, double n2){ return n1*n2; }
}

class AreaMath    // 넓이 계산 클래스
{	
	public double calCircleArea(double rad)
	{
		SimpleMath sm=new SimpleMath();
		double result=sm.mul(rad, rad);
		result=sm.mul(result, SimpleMath.PI);
		return result;
	}
	public double calRectangleArea(double width, double height)
	{
		SimpleMath sm=new SimpleMath();
		return sm.mul(width, height);
	}
}

class PerimeterMath    // 둘레 계산 클래스
{	
	public double calCirclePeri(double rad)
	{
		SimpleMath sm=new SimpleMath();
		double result=sm.mul(rad, 2);
		result=sm.mul(result, SimpleMath.PI);
		return result;
	}
	public double calRectanglePeri(double width, double height)
	{
		SimpleMath sm=new SimpleMath();
		return sm.add(sm.mul(width, 2), sm.mul(height, 2));
	}
}

class HowMethod
{
	public static void main(String[] args)
	{
		AreaMath am=new AreaMath();
		PerimeterMath pm=new PerimeterMath();
		
		System.out.println("원의 넓이: "+am.calCircleArea(2.4));
		System.out.println("직사각형 둘레: "+pm.calRectanglePeri(2.0, 4.0));
	}
}

A.

class SimpleMath    // 단순 계산 클래스
{
	public static final double PI=3.1415;	
	 //  문법적으로는 순서가 상관없지만 이 순서대로 할 것!
	public static double add(double n1, double n2){ return n1+n2; }
	public static double min(double n1, double n2){ return n1-n2; }
	public static double mul(double n1, double n2){ return n1*n2; }
}

class AreaMath    // 넓이 계산 클래스
{	
	public static double calCircleArea(double rad)
	{
		SimpleMath sm=new SimpleMath();
		result=SimpleMath.mul(rad, rad);
		result=sm.mul(result, SimpleMath.PI);
		return result;
	}
	public static double calRectangleArea(double width, double height)
	{
		SimpleMath sm=new SimpleMath();
		return SimpleMath.mul(width, height); 참조변수, 클래스명 모두 가능
	}
}

class PerimeterMath    // 둘레 계산 클래스
{	
	public static double calCirclePeri(double rad)
	{
		double result=sm.mul(rad, 2);
		result=sm.mul(result, SimpleMath.PI);
		return result;
	}
	public static double calRectanglePeri(double width, double height)
	{
		SimpleMath sm=new SimpleMath();
		return sm.add(SimpleMath.mul(width, 2), SimpleMath.mul(height, 2));
	}
}

class HowMethod
{
	public static void main(String[] args)
	{
		System.out.println("원의 넓이: "+AreaMath.calCircleArea(2.4));
		System.out.println("직사각형 둘레: "+PerimeterMath.calRectanglePeri(2.0, 4.0));
	}
}

- (import java.lang.*;) 자바 컴파일러가 자동으로 삽입시키기 때문에 클래스 이름으로만 접근 가능한 것

 

class Hello
{
	public static void main(String[] args)
	{
		(java.lang)System.out.println("Hello");
		               // 대문자이므로 클래스, out - 참조변수(스테틱변수), println - 메소드
	}
}

- 메인메소드가 가장 먼저 호출됨

  메인메소드를 어디서나 접근가능해야 해서 public

  Hello 객체 만들지 않고 접근할 수 있도록 static

 

class Number
{
	public int num1;
	public static int num2;
	public void printNumber1()
	{
		System.out.println("1");
	}
}

class NumberMain
{
	public static void main(String[] args)
	{
		Number n1 = new Number();
		System.out.println(n1.num2);
		System.out.println(Number.num2);
                      // 클래스변수이기 때문에 클래스 이름으로 접근 가능, 가독성이 높음
		n1.printNumber2();
		Number.printNumber2();
	}
}

 

Q. SimpleNumber를 오직 인스턴스 하나만 생성되도록 하자.

 

A.

//인스턴스 하나
class SimpleNumber
{
	private static SimpleNumber inst;
	int num=0;
	private SimpleNumber() {}	// 생성자 private
	public  void addNum(int n) { num += n; }
	public  void showNum() 
	{ 
		System.out.println(num); 
	}
	
	public static SimpleNumber getSimpleNumberInst()
	{
		if(inst==null)
			inst = new SimpleNumber();
		return inst;
	}
}

class OnlyOneINstance
{
	public static void main(String[] args)
	{
		SimpleNumber num1 = SimpleNumber.getSimpleNumberInst();
		num1.addNum(20);
		
		SimpleNumber num2 = SimpleNumber.getSimpleNumberInst();
		num2.addNum(30);
	
		num1.showNum();
		num2.showNum();
	}
}

- 싱글톤패턴 : 객체의 개수를 1개로 제한해야 할 때 사용

 

- 클래스메소드에선 인스턴스 변수, 인스턴스 메소드를 참조할 수 없다 - 참조 시 에러

 

ex)

class InstCnt
{
	static int instNum=0;

	public InstCnt()
	{
		instNum++;
		System.out.println("인스턴스 생성:“+instNum);
	}
}
class ClassVar
{
	public static void main(String[] args)
	{
		InstCnt cnt1 = new InstCnt();
		InstCnt cnt2 = new InstCnt();
		InstCnt cnt3 = new InstCnt();
	}
}

A.

인스턴스 생성 : 1

인스턴스 생성 : 2

인스턴스 생성 : 3

 

ex)

class AccessWay
{
	static int num=0;
	
	AccessWay()
	{
		incrCnt();
	}
	public void incrCnt(){num++;}
}
class ClassVarAccess
{
	public static void main(String[] args)
	{
		AccessWay way=new AccessWay();
		way.num++; 2
		AccessWay.num++; 3
		System.out.println("num="+AccessWay.num); num=3 출력
	}
}

 

ex)

class InstCnt
{
	static int instNum=100;
	
	public InstCnt()
	{
		instNum++;
		System.out.println("인스턴스 생성: "+instNum);
	}
}
class StaticValNoInst
{	
	public static void main(String[] args)
	{
		InstCnt.instNum-=15;
		System.out.println(InstCnt.instNum); 
	}
}

 

ex)

class AAA
{
	int aaa;
	public AAA(int num){ aaa=num; }
	
	public static void main(String[] args)
	{
		AAA ins1=new AAA(10); // 메인메소드 내 자기 클래스를 생성할 수 있다
		BBB ins2=new BBB(20);
		
		System.out.println("ins1.aaa="+ins1.aaa);
		System.out.println("ins2.bbb="+ins2.bbb); 
	}
}
class BBB 
{
	int bbb;
	public BBB(int num){ bbb=num; } // 매개변수 bbb에 초기화
	
	public static void main(String[] args)
	{
		AAA ins1=new AAA(11); 
		BBB ins2=new BBB(22); // 메인메소드 내 자기 클래스를 생성할 수 있다
		
		System.out.println("ins1.aaa="+ins1.aaa);
		System.out.println("ins2.bbb="+ins2.bbb);
	}
}

- 메인메소드는 어디든 존재할 수 있다

- 대개는 메인메소드는 관리상의 목적으로 딱 메인메소드만 넣는다

- 자바는 필요할 때 메모리에 노드를 호출한다 (있는 내용이어도 필요하지 않으면 메모리에 호출 안한다)

 

ex)

class Circle
{
	static final double PI=3.1415;
	private double radius;
	
	public Circle(double rad){ radius=rad; }
	public void showPerimeter()   // 둘레 출력
	{
		double peri=(radius*2)*PI;
		System.out.println("둘레: "+peri);
	}
	public void showArea()    // 넓이 출력
	{
		double area=(radius*radius)*PI;
		System.out.println("넓이: "+area);
	}
}
class ClassVarUse
{
	public static void main(String[] args)
	{
		Circle cl=new Circle(1.2);
		cl.showPerimeter();
		cl.showArea();
	}
}

 

ex)

class NumberPrinter
{	
	public static void showInt(int n){ System.out.println(n); }
	public static void showDouble(double n) { System.out.println(n); }
}
class ClassMethod 
{
	public static void main(String[] args)
	{
		NumberPrinter.showInt(20);
		
		NumberPrinter np=new NumberPrinter(); // 객체 생성
		np.showDouble(3.15); // 참조변수를 통해서도 접근 가능하다
	}
}

 

ex) 과일 장수 예제와 비슷

class Employer     /* 고용주 */
{
	private int myMoney;
	
	public Employer(int money)
	{
		myMoney=money;
	}
	public void payForWork(Employee emp, int money)
	{
		if(myMoney<money)
			return;
		emp.earnMoney(money);
		myMoney-=money;
	}
	public void showMyMoney()
	{
		System.out.println(myMoney);
	}	
}
class Employee   /* 고용인 */
{
	private int myMoney;
	
	public Employee(int money)
	{
		myMoney=money;
	}
	public void earnMoney(int money)
	{
		myMoney+=money;
	}
	public void showMyMoney()
	{
		System.out.println(myMoney);
	}	
}

 

# string 클래스

- 메소드 오버로딩 : 메소드 이름은 같지만 메소드의 개수가 다르거나 메소드의 매개변수의 자료형이 다른 것

class NumberMain
{
	Number n1 = new Number();
	n1.printNumber();
}

 

- 반환형이 다른 것으로는 메소드 오버로딩이 지원되지 않는다

ex)

public int printNumber()
public void printNumber() // 처럼 반환형만 다른 경우 에러 발생!

 

- 생성자도 반환형이 없는 특수한 형태의 메소드이기 때문에

  아래 예시와 같은 형태로 생성자도 메소드 오버로딩이 지원된다.

ex)

class Number
{
	int num1, num2;
	Number()
	{
		System.out.println("매개변수 없음“);
	}
	Number(int num1)
	{
		this.num1=num1;
	}
	Number(int num1, int num2)
	{
		this.num1=num1;
		this.num2=num2;
	}
}

 

ex)

void aaa(int num1, int num2){}
void aaa(int num1, double num2){}

aaa(5,'a');

- int, char와 같은 형태로 있는 메소드 오버로딩이 없으나 에러는 나지 않는다

  자동형변환 규칙에 따라 가장 가까운 형으로 변환 되므로 int, int를 호출하게 된다.

  이와 같은 형태로 애매하게 없는 것을 호출하는 것은 좋지 않은 습관이다(문법적으로만 가능)

 

ex)

class Person   // 일반적으로 남자는 주민번호, 군번이 있다고 가정
{
	private int perID;
	private int milID;
	
	public Person(int pID, int mID)
	{
		perID=pID;
		milID=mID;
	}
	public Person(int pID)
	{
		perID=pID;
		milID=0;
	}
	public void showInfo()
	{
		System.out.println("민번: "+perID);
		if(milID!=0)
			System.out.println("군번: "+milID+'\n'); // 군번이 0이 아니면 참
		else
			System.out.println("군과 관계 없음 \n");
	}
}
class Overloading
{
	public static void main(String[] args)
	{
		Person man=new Person(950123, 880102); // 주민번호, 군번
		Person woman=new Person(941125);	
		man.showInfo();  // 결과 : 민번: 950123, 군번: 880102
		woman.showInfo(); // 결과 : 민번 : 941125, 군과 관계없음 출력
	}
}

ex)

class Person
{
	private int perID;
	private int milID;
	private int birthYear;
	private int birthMonth;
	private int birthDay;
	
	public Person(int perID, int milID, int bYear, int bMonth, int bDay)
	{
		this.perID=perID;
		this.milID=milID;
		birthYear=bYear;
		birthMonth=bMonth;
		birthDay=bDay;
	}
	public Person(int pID, int bYear, int bMonth, int bDay)
	{
		this(pID, 0, bYear, bMonth, bDay); // this()가 생성자를 의미함
    }
    public void showInfo()
	{
		System.out.println("민번: "+perID);
		System.out.println(
				"생년월일: "+birthYear+"/"+birthMonth+"/"+birthDay);
		if(milID!=0)
			System.out.println("군번: "+milID+'\n');
		else
			System.out.println("군과 관계 없음 \n");
	}
}    
class CstOverloading
{
	public static void main(String[] args)
	{
		Person man=new Person(950123, 880102, 1995, 12, 3);
		Person woman=new Person(990117, 1999, 11, 7);
		man.showInfo(); // 결과 : 민번:950123 생년월일:1995,12,3 군번:880102
		woman.showInfo(); // 결과 : 민번:990117 생년월일:1999,11,7 군과 관계 없음
	}
}
728x90