본문 바로가기
개발 공부 Today I Learned

[국비 20일차 TIL] 자바 static, 인스턴스, 상속

by 개발자신입 2023. 12. 18.
반응형

- static (정적 메소드)

static은 정적이라는 의미.

클래스가 로드되는 시점

동적은 로드된 클래스가 실행된 이후

 

이 중 객체는 동적 데이터, 프로그램이 실행된 이후에 발생하는 대표적인 형태.

 


 

 


멤버

인스턴스 멤버 :

  • 인스턴스 = 같은 클래스에 속하는 개개의 객체로, 하나의 클래스에서 생성된 객체
  • 인스턴스 생성 시 가지게 되는 자신의 변수
  • (인스턴스명.변수명)으로 호출
  • new가 필요함. 인스턴스 생성 후 사용 가능

 

정적 멤버 static :

  • 모든 객체가 공통적으로 사용하는 변수
  • (클래스명.변수명)으로 호출
  • 인스턴스 없이 클래스명으로 바로 불러서 사용 가능
  • 하나의 클래스에 하나의 변수만 사용 가능
  • 인스턴스보다는 클래스에 의지(연결)해서 사용함
  • static을 붙여서 사용

 

주의사항

인스턴스가 생성되지 않은 상태에서 호출되는 변수/메소드이므로

인스턴스 안에서만 사용되는 인스턴스 변수 사용 불가능

정젹 변수와 지역 변수만 사용가능함.

 

정적 메소드에서 인스턴스 메소드를 호출하면 오류 발생함

 

인스턴스 메소드로 객체가 생성되어야만 사용 가능하기 때문임.

 

정적 메소드에서 정적 메소드 호출은 가능.

인스턴스 메소드에서 정적 메소드 호출 가능.

 

정적 메소드는 this 키워드 사용 불가함. (this는 인스턴스 생성 후 사용 - this가 참조할 인스턴스 없음)

 

final 붙인 상수는 모두가 같이 사용하는 상수임. (상수는 대문자로)

인스턴스를 만들지 않고 쓰는게 좋음. 그래서 final static을 붙임.

 

 

package dec18;

class Cat{
	static String name;
	int age;
	static double pi = 3.14;
}

public class Static01 {
	public static void main(String[] args) {
		Cat cat = new Cat();	// 인스턴스 없이 사용 가능
		Cat cat2 = new Cat();
		Cat.pi = 3.14;
		
		cat.age = 10;
		cat2.age = 120;
		
		Cat.name = "kong";
		Cat.name = "mong"; // static은 클래스명으로 호출
		
		System.out.println(cat.age);
		System.out.println(cat2.age);
		System.out.println(cat.name);
		System.out.println(cat2.name); // static이 붙어있기 때문에 하나의 변수만 생성함
		
	}
}

 

 

 

static & non-static

static :

non-static 호출 불가. static만 호출 가능

this 사용 불가

여러개 생성 가능

클래스를 만든 직후 사용 가능 (인스턴스 없이도 사용 가능)

공유 변수 또는 하나만 만들때는 static 붙여야 함

 

non-static :

static 호출 가능

this도 사용 가능

인스턴스 생성 후에 사용 가능 (인스턴스 필요)

 

싱글톤 :

단 하나의 객체만 만들도록 보장해야 하는 경우

ex) 데이터베이스 접속 정보 (id, pw, url)

final :

수정 불가함. 값을 꼭 지정해줘야 함. 상수는 대문자로 표기.

 

 

package dec18;

class Car{ // model부터 id까지 인스턴스
	
	String model;
	String color;
	int speed;
	int id;
	static int numbers; // static
	
	public Car(String model, String color, int speed) {
		this.model = model;
		this.color = color;
		this.speed = speed;
		this.id = ++numbers; // 위의 numbers가 0이기 때문에 먼저 ++를 적어줌. 0번차는 없으니깐.
							 // 만약 위의 numbers가 1이면 뒤에 ++를 붙여줌.
	}
	
	static public void aaa() { // static이 있으면 인스턴스 없이 호출 가능 = Car.aaa
							   // static은 static 있는 변수만 사용 가능.
	}
	public void bbb() {		// static이 없으면 인스턴스 발생 후에 사용 가능
		aaa();				// static이 없으면 static을 호출 가능함.
		this.speed = 190; 	// speed에도 static이 없고 bbb에도 static이 없어서 this 사용 가능
	}  
	public void ccc() {
		this.model = "ccc";		// this 키워드 사용 가능
	}
}



public class Static02 {
	public static void main(String[] args) {
		
		Car car = new Car("i5", "흰색", 150);
		Car car2 = new Car("i5", "흰색", 150);
		Car car3 = new Car("i5", "흰색", 150);
		Car car4 = new Car("i5", "흰색", 150);
		Car car5 = new Car("i5", "흰색", 150);
		
		System.out.println(car.id);
		System.out.println(car2.id);
		System.out.println(car3.id);
		System.out.println(car4.id);
		System.out.println(car5.id);
		
		System.out.println(Car.numbers);
	}
}

 

 


 


접근 제어자


접근 제어자를 통해 각 api의 접근 권한을 제한할 수 있음

public < protected < default(비어있음) < private

public : 제한 없이 모두 접근 가능

 

protected :

같은 패키지에서 접근 가능
다른 패키지에서는 상속받은 자식 클래스/인터페이스인 경우만 가능

 

default :

아무것도 안 붙은 형태
접근 제한 없음
같은 패키지 내에서는 모두 접근 가능하지만, 다른 패키지에서는 접근 불가

 

private : 오직 내 클래스에서만 확인 가능 (같은 패키지 x, 다른 패키지 x)

접근 제한자는 클래스명, 필드, 생성자, 메소드에 모두 사용 가능
단, 클래스에서는 public과 default만 가능함.

  클래스 내부 동일 패키지 하위 클래스 그 외
public  O O O O
protected  O O O x
default  O O x x
private  O x x x

 

 

class Apple { 					// default class
	private String name;		// default field
	int age;
	
	private Apple() {}
	
	static Apple getInstance() {
		return new Apple();		// 생성자가 private로 잠겨있다면 새로운 객체를 만들어서 내보내기
	}
	
	void print() {
		System.out.println("저는 " + name + "입니다.");
	}
	
	void setName(String name) { 	// setter 저장하기
		this.name = name;			// 같은 클래스여서 private여도 사용 가능
	}
	
	String getName() {				// getter 가져오기
		return name;
	}
	
	void setAge(int age) {
		if(0>age) {
			this.age = 1;
		} else {
			this.age = age;
		}
	}
	
	int getAge() {
		return age;
	}	
}


public class AccessModifiers {
	public static void main(String[] args) {
		
		
		Apple a = Apple.getInstance();
//		Apple a = new Apple();  // 위에 Apple을 private로 잠금
		
		//a.name = ""; 			// 위에 private가 있기 때문에 접근 불가
		
		a.setName("kong");
		String name = a.getName();
		System.out.println(name);
	}
}

 

 

- DTO (Data Transfer Object)

 

- HeidiSQL, mariadb : 데이터베이스에서 자바로 값 불러오기

 

package com.*****.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DB01 {
	
//   다른 데이터베이스 자바에서 접속하기
 
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		Connection conn = null;
		Statement stmt = null;
		String url = "jdbc:mariadb://______";
		String id = "______";
		String pw = "______";
		
		Class.forName("org.mariadb.jdbc.Driver");
		conn = DriverManager.getConnection(url, id, pw);
		stmt = conn.createStatement();
		
		// 데이터베이스에 질의하기 SQL
		String sql = "SELECT * FROM departments";
		// 오는 값 저장하기
		ResultSet rs = stmt.executeQuery(sql);
		// 출력하기
		while(rs.next()) {
			System.out.print(rs.getString(1) + " : ");
			System.out.print(rs.getString(2) + "\n");
		}

		// 마지막에 생성한 인스턴트부터 닫아주기
		rs.close();
		stmt.close();
		conn.close();		
	}
}



-----아래는 무조건 필요한 코드임. 계속 쓰이기 때문에 다른 곳으로 놔둘거임. -----

		Connection conn = null;
		Statement stmt = null;
		String url = "jdbc:mariadb://______";
		String id = "______";
		String pw = "______";
		
		Class.forName("org.mariadb.jdbc.Driver");
		conn = DriverManager.getConnection(url, id, pw);
		stmt = conn.createStatement();

 

 

 

정보처리기사 

2021년 2회차 17번 (static) 

package dec18;

public class Test03 {
	public static void main(String[] args) {
		
	      System.out.print(Test03.check(1));
	   }
	  
	   static String check (int num)
	   {
	      return (num >= 0) ? "positive" : "negative";
	   }
	}

 

 

 

package dec18;

class Connection {
	private static Connection _inst = null;
	private int count = 0;

	static public Connection get() {
		if (_inst == null) {
			_inst = new Connection();
			return _inst;
		}
		return _inst;
	}

	public void count() {
		count++;
	}

	public int getCount() {
		return count;
	}
}

public class Test04 {
	public static void main(String[] args) {
		Connection conn1 = Connection.get();
		conn1.count();
		Connection conn2 = Connection.get();
		conn2.count();
		Connection conn3 = Connection.get();
		conn3.count();

		System.out.print(conn1.getCount());
	}
}

 

 

~ 면접 단골 질문 ~

  • 오버라이드 & 오버라이딩
  • 오버로드 & 오버로딩
  • 인터페이스
  • 상속
  • 정적 메소드

 

- 상속

package com.-----.inheritance;

// Animal 클래스에서 상속받음
public class Dog extends Animal {

	public Dog(String name, int age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}
}
package com.-----.inheritance;

// Animal 클래스에서 상속받음
public class Cat extends Animal {

	public Cat(String name, int age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}
}
package zoo;

class Mouse {
	String name;
	int age;
	String breed;
	int hp;
}

class Horse {
	String name;
	int age;
	String breed;
	int hp;
	
}

class Zookeeper {
	public void feed(Mouse mouse) { 		// 쥐가 들어오면
		mouse.hp++;
	}
	public void feed(Horse horse) {
		horse.hp++;
	}
}


public class Zoo {
	public static void main(String[] args) {
		
		Zookeeper keeper = new Zookeeper();
		Mouse mouse = new Mouse();
		Horse horse = new Horse();
		
		keeper.feed(horse);
		keeper.feed(mouse); 	// 개체수가 늘어날수록 코드가 길어진다... => 상속받자!
	}
}
// Animal에 변수 선언으로 통합 (부모 super)

package com.-----.inheritance;

public class Animal {

	String name;
	int age;
	String breed;
	int hp;
	
	public Animal(String name, int age) {
		System.out.println("동물이 태어납니다.");
		this.name = name;
		this.age = age;
	}
}

 

 

 

package com.-----.inheritance;

  상속 : 자식은 부모의 코드를 자신의 것처럼 사용함.


class A { 			// A = 부모 super
	int field1;
	void method1() {
		
	}
}

class B extends A { // B = 자식 sub
	int field2;
	void method2() {		
	}
}

class C extends B {
	
}

public class Inheritance {
	public static void main(String[] args) {
		
		A a = new A();
		B b = new B();
		
		b.field1 = 100;
		b.method1(); 		// A의 코드를 B가 상속했기 때문에 B에서 A코드를 사용 가능.
		
		C c = new C(); 		// 객체 생성
		
		Cat cat = new Cat(null, 0);
//		cat.  상속받아서 모두 사용 가능.
		Dog dog = new Dog(null, 0);
//		dog.  상속받아서 모두 사용 가능.
	
	}

}

 

 

 

package com.-----.inheritance;

class Mouse extends Animal {
	public Mouse(String name, int age) {
		super(name, age);	// 부모 생성자 호출, 첫 줄에 써야함.
		System.out.println("쥐 생성자입니다.");
	}
}


class Horse extends Animal {

	public Horse(String name, int age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}
}

class Zookeeper extends Animal {
	public Zookeeper(String name, int age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}

	public void feed(Animal animal) { 	// 중복코드 제거 Animal로 통합
		animal.hp++;

//		'오브젝트'로도 사용 가능 (= 최상위 클래스)
//		public void feed(Object obj) { 	
//		((animal) obj).hp++;
	}


public class Zoo {
	public static void main(String[] args) {
		
		Zookeeper keeper = new Zookeeper("사육사", 30);
		Cat cat = new Cat("kong", 1);
		Dog dog = new Dog("Daengi", 6);
		Mouse mouse = new Mouse("micky", 120);
		// 부모타입 형태로 자식 생성자 사용하기 (앞에 와야함)
        Animal horse = new Horse("candy", 13);		
		
		keeper.feed(cat);
		keeper.feed(dog);
		keeper.feed(mouse);
		keeper.feed(horse);
		
	}
}
반응형

댓글