[Java] 객체지향 프로그래밍 (1)

당당·2023년 4월 21일
0

Java

목록 보기
16/20

📔설명

메소드를 다른 컴퓨터 언어에서는 function, subroutine, procedural 이라고 한다.
절차지향 언어들에는 C언어가 있다.

메소드만으로 프로그램을 만드는 것에 한계를 느낀 프로그래머들이
서로 연관된 메소드와 변수들을 그룹핑하고 그곳에 이름을 붙인게 class 이다. 그리고 클래스 중심으로 프로그램을 만드는 것을 객체지향 프로그래밍이라고 한다!


🙄다른 이의 클래스와 인스턴스

Math 클래스


public class OthersOOP {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(Math.PI);
        System.out.println(Math.floor(1.8));
        System.out.println(Math.ceil(1.5));
	}

}

Math.PI에서 Math라는 클래스의 PI라는 변수가 있는 것이고, 그 변수 안에 수(3.14...)가 저장되어있는 것이다.
Math.floor()에서 floor()는 내림을 해주는 Math의 메소드이다.
Math.ceil()에서 ceil()은 올림을 해주는 메소드이다.

FileWriter 클래스

import java.io.FileWriter;
import java.io.IOException;

public class OthersOOP {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		System.out.println(Math.PI);
		System.out.println(Math.floor(1.8));
		System.out.println(Math.ceil(1.5));
		
		FileWriter f1=new FileWriter("data.txt");
		f1.write("Hello");
		f1.write(" java");
		f1.close();
	}

}

이번에는 FileWriter라는 클래스를 살펴보자. 파일에 쓰기를 할 때 쓰는 클래스이다. 해당 코드를 실행시키면 아래와 같은 결과가 출력된다.

FileWriter는 new 를 붙여서 f1이라는 복제본을 생성하였다.

위의 소스코드에 아래 내용을 추가해보자.

		FileWriter f2=new FileWriter("data2.txt");
		f2.write("Hello");
		f2.write(" java2");
		f2.close();


실행시키면 data2.txt가 생성되고, 그 안의 내용은 위와 같다.

Math 클래스처럼 일회용으로 작업을 하는 애들은 그냥 바로 클래스로 접근하면 되지만, FileWriter처럼 계속 사용하는 애들은 클래스를 복제해서 사용하는 것이다.

여기서 참고로, System도 클래스이다!

class : System, Math, FileWriter
instance : f1, f2

🤭나의 클래스와 인스턴스

변수와 메소드


public class MyOOP {

	public static void main(String[] args) {
		//..
		System.out.println("----");
		System.out.println("A");
		System.out.println("A");
		//..
		System.out.println("----");
		System.out.println("A");
		System.out.println("A");
		//..
	}

}

여기서, 반복되는 것을 메소드로 묶자.
그리고, printB()라는 메소드도 만들자!


public class MyOOP {

	public static void main(String[] args) {
		//..
		printA();
		printA();
		
		printB();
		printB();
	}

	public static void printA() {
		System.out.println("----");
		System.out.println("A");
		System.out.println("A");
	}
	
	public static void printB() {
		System.out.println("----");
		System.out.println("B");
		System.out.println("B");
	}

}

그런데, 또 모종의 이유로 구분자를 다르게 해서 출력하고 싶어졌다고 생각하자.
같은 메소드를 여러번 반복하는 것은 비효율적이기 때문에, 매개변수도입을 생각할 수 있다.


public class MyOOP {

	public static void main(String[] args) {
		//..
		printA("----");
		printA("----");
		printB("----");
		printB("----");
		
		printA("****");
		printA("****");
		printB("****");
		printB("****");
	}

	public static void printA(String delimiter) {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public static void printB(String delimiter) {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}

}

그런데 만약 구분자를 주는 메소드가 1억줄이 넘는다고 생각해보자..
끔찍하다! 그러므로 변수를 도입하자.


public class MyOOP {

	public static void main(String[] args) {
		String delimiter="----";
		printA(delimiter);
		printA(delimiter);
		printB(delimiter);
		printB(delimiter);
		
		delimiter="****";
		printA(delimiter);
		printA(delimiter);
		printB(delimiter);
		printB(delimiter);
	}

	public static void printA(String delimiter) {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public static void printB(String delimiter) {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}

}

이전과 출력은 똑같으면서, 한번에 구분자를 변경할 수 있는 폭발적인 효과를 가져올 수 있다.
하지만, 인자를 주는 것이 싫다고 가정해보자.


public class MyOOP {
	
	public static void main(String[] args) {
		delimiter="----";
		printA();
		printA();
		printB();
		printB();
		
		delimiter="****";
		printA();
		printA();
		printB();
		printB();
	}
	public static String delimiter="";
	public static void printA() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public static void printB() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}

}

delimiter 변수를 이용하였다! 전역변수로 선언하여 메소드에서도 사용할 수 있도록 하였고, 또 printA()의 인자도 없앴다.

클래스

delimiterprintA(), printB()Print클래스로 묶고, Print.A()또는 Print.B()로 호출해보자.

class Print{
	public static String delimiter="";
	public static void A() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public static void B() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
}
public class MyOOP {
	
	public static void main(String[] args) {
		Print.delimiter="----";
		Print.A();
		Print.A();
		Print.B();
		Print.B();
		
		Print.delimiter="****";
		Print.A();
		Print.A();
		Print.B();
		Print.B();
	}
	

}

Print 클래스를 통해 접근할 수 있다!
결과는 이전과 똑같지만 코드는 훨씬 더 단정해졌다.
클래스 안의 변수, 메소드를 통틀어서 멤버라고 한다.
지금 Print클래스의 멤버는 delimiter, A(),B() 이다.


해당 소스코드를 저장하면, 이클립스에서는 위처럼 MyOOP.classPrint.class가 생성된다.

생성했던 Print클래스는 다른 .java파일로 옮길 수 있다.

이사를 해주자!


public class MyOOP {
	
	public static void main(String[] args) {
		Print.delimiter="----";
		Print.A();
		Print.A();
		Print.B();
		Print.B();
		
		Print.delimiter="****";
		Print.A();
		Print.A();
		Print.B();
		Print.B();
	}
	

}
public class Print{
	public static String delimiter="";
	public static void A() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public static void B() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
}

이렇게 구분하고, 실행시켜도 잘 동작한다!

이것도 메소드나 변수랑 마찬가지로 이클립스에서 지원해주는 Refactor기능을 통해 Move Type To New File을 통해 Print.java파일을 한번에 생성할 수 있다! 완전 신기..

인스턴스

인스턴스는 위에 다른 이의 클래스와 인스턴스에서 FileWriter f1에서 f1에 해당한다.

public class MyOOP {
	
	public static void main(String[] args) {
		Print.delimiter="----";
		Print.A();
		Print.A();
		Print.B();
		Print.B();
		
		Print.delimiter="****";
		Print.A();
		Print.A();
		Print.B();
		Print.B();
		
		Print.delimiter="----";
		Print.A();
		Print.delimiter="****";
		Print.A();
		Print.delimiter="----";
		Print.A();
		Print.delimiter="****";
		Print.A();
	}
	

}

이렇게 변경해야 하는 일이 생겼다고 가정하자.
너무 비효율적이다! 이럴때 인스턴스를 사용한다.

인스턴스를 생성할 때는
클래스명 인스턴스명 = new 클래스명();
으로 생성한다.

https://velog.io/@dangdang/Java-메소드-2

이전에 메소드(2)에서 static 은 클래스 소속이라고 하였다.
그러니, 인스턴스를 사용할 때는 static을 다 없애주자!


class Print{
	public String delimiter="";
	public void A() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public void B() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
}

Print.java에서 static을 다 없애버리자!

그리고 MyOOP.java도 마찬가지로 수정해주자.

public class MyOOP {
	
	public static void main(String[] args) {
		
		Print p1=new Print();
		p1.delimiter="----"; //instance's delimiter
		p1.A();
		p1.A();
		p1.B();
		p1.B();
		
		Print p2=new Print();
		p2.delimiter="****"; //instance's delimiter
		p2.A();
		p2.A();
		p2.B();
		p2.B();
		
		
		p1.A();
		p2.A();
		p1.A();
		p2.A();
	}
	

}

소스코드가 아주 간결해졌다!
실행결과는 위에서 인스턴스 안썼을 때랑 똑같지만, 더 간결하다!

profile
MySQL DBA 신입 지원

0개의 댓글