포스코DX X 비트교육센터 6기 - 자바 객체지향


클래스 복습

package chapter03;

public class Song {
	private String title;
	private String album;
	private String composer;
	private String artist;
	private int track;
	private int year;

	public Song() {
	}

	public Song(String title, String album, String composer, String artist, int track, int year) {
		super();
		this.title = title;
		this.album = album;
		this.composer = composer;
		this.artist = artist;
		this.track = track;
		this.year = year;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getAlbum() {
		return album;
	}

	public void setAlbum(String album) {
		this.album = album;
	}

	public String getComposer() {
		return composer;
	}

	public void setComposer(String composer) {
		this.composer = composer;
	}

	public String getArtist() {
		return artist;
	}

	public void setArtist(String artist) {
		this.artist = artist;
	}

	public int getTrack() {
		return track;
	}

	public void setTrack(int track) {
		this.track = track;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public void show() {
		System.out.println(
				artist + " " + title + "(" + album + ", " + year + ", " + track + "번 track, " + composer + " 작곡)");
	}

}

package chapter03;

public class SongTest {
	public static void main(String[] args) {
		Song song1 = new Song();
		song1.setTitle("좋은날");
		song1.setArtist("아이유");
		song1.setAlbum("Real");
		song1.setComposer("이민수");
		song1.setTrack(3);
		song1.setYear(2010);
		
		song1.show();
	}
}

생성자 생성 시,

Song song2 = new Song("좋은날", "아이유", "Real", "이민수", 3, 2010);

생성자

  • 기본 생성자 : public, 매개변수 없음
    • 모든 클래스에는 반드시 하나 이상의 생성자가 있어야 한다.

생성자의 오버로딩

package chapter03;

public class Goods {
	String name;
	int price;
	int countStock;
	int countSold;

	//생성자의 오버로딩
	public Goods() {
	}

	public Goods(String name, int price, int countStock, int countSold) {
		this.name = name;
		this.price = price;
		this.countSold = countSold;
		this.countStock = countStock;
	}
	
}
package chapter03;

public class GoodsApp3 {
	public static void main(String[] args) {
		
		Goods tv = new Goods("TV", 40000, 10, 20);

		Goods phone = new Goods(); // 이를 위해 기본 생성자도 넣어주어야 함.
		
	}
}

생성자를 이용하여 코드 중복을 줄이는 방법

	public Song() {
	}

	public Song(String title, String album, String composer, String artist, int track, int year) {
		super();
		this.title = title;
		this.album = album;
		this.composer = composer;
		this.artist = artist;
		this.track = track;
		this.year = year;

		System.out.println(".... some code1");
		System.out.println(".... some code2");
		System.out.println(".... some code3");
		System.out.println(".... some code4");
		System.out.println(".... some code5");
		
	}

	public Song(String title, String artist) {
		/**
		super();
		this.title = title;
		this.artist = artist;

		System.out.println(".... some code1");
		System.out.println(".... some code2");
		System.out.println(".... some code3");
		System.out.println(".... some code4");
		System.out.println(".... some code5");**/
		
		//코드 중복을 피할 수 있는 방법
		this(title, null, null, artist, 0, 0);
	}

다형성 - 오버로딩

package print;

public class Main {
	public static void main(String[] args) {
		Point point1 = new Point();
		point1.setX(10);
		point1.setY(20);
		
		Point point2 = new Point(20,30);
		
		drawPoint(point1);
		drawPoint(point2);
		//point1.disappear();
		point1.show(false);
	}
	public static void drawPoint(Point point) {
		point.show();
	}
}

	public void show() {
		System.out.println("점[x=" + x + ",y=" + y + "]을 그렸습니다.");
	}

	public void show(boolean visible) {
		if (visible) {
			show();
		} else {
			System.out.println("점[x=" + x + ",y=" + y + "]을 지웠습니다.");
		}
	}

	// public void disappear() {
	// System.out.println("점[x=" + x + ",y=" + y + "]을 지웠습니다.");
	// }

상속, 부모자식

image

  • 자식 생성자에 super();를 넣지 않아도 자동으로 컴파일러가 넣어준다.
  • super() 는 맨 앞에다가 넣어주어야 한.
package chapter03;

public class Person {
	
	public Person() {
		System.out.println("Person" + "() called");
	}
}

package chapter03;

public class Student extends Person {
	public Student() {
		// 자식 생성자에서 부모 생성자를 명시적으로 호출하지 않으면
		// 자동으로 부모의 기본 생성자를 자식 생성자 코드 맨 앞에 호출한다.
		super(); //자동 생성되기 때문에 안 넣어도 문제없이 돌아간다.
		System.out.println("Student() called");
	}

}
package chapter03;

public class StudentTest {

	public static void main(String[] args) {
		new Student();
		/**
		 * 부모가 먼저 불린다.
		 * Person() called 
		 * Student() called
		 **/
	}
}

상속 - 다운캐스팅, 업캐스팅

package chapter03;

public class StudentTest02 {

	public static void main(String[] args) {
		Student s1 = new Student();
		
		Person p = s1; //upcasting(암시적, Implicity)
		Student s2 = (Student)p; //downcasting(명시적, Explicity)
	}
}

오버라이딩

package print;

public class Main {
	public static void main(String[] args) {
		Point point1 = new Point();
		point1.setX(10);
		point1.setY(20);
		
		Point point2 = new Point(20,30);
		
		drawPoint(point1);
		drawPoint(point2);
		//point1.disappear();
		point1.show(false);
		
		Point point3 = new ColorPoint(); //업캐스팅 (암시)
		point3.setX(30);
		point3.setY(30);
		
		//ColorPoint p = (ColorPoint)point3; //다운캐스팅 (명시)
		((ColorPoint)point3).setColor("red"); //다운캐스팅
		drawPoint(point3);
		
		
	}
	public static void drawPoint(Point point) {
		point.show();
	}

}

package print;

public class Point {
	protected int x;
	protected int y;

	public Point() {
	}

	public Point(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public void show() {
		System.out.println("점[x=" + x + ",y=" + y + "]을 그렸습니다.");
	}

	public void show(boolean visible) {
		if (visible) {
			show();
		} else {
			System.out.println("점[x=" + x + ",y=" + y + "]을 지웠습니다.");
		}
	}

	// public void disappear() {
	// System.out.println("점[x=" + x + ",y=" + y + "]을 지웠습니다.");
	// }

}
	
package print;

public class ColorPoint extends Point{

	private String color;

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
	
	//annotation = marking = tag : 컴파일러가 오류인지 확인해줌. + 개발자가 이해가 쉽다.
	@Override
	public void show() {
		System.out.println("점[x=" + x + ",y=" + y + ",color=" + color + "]을 그렸습니다.");
	}
	
	

}

점[x=10,y=20]을 그렸습니다.
점[x=20,y=30]을 그렸습니다.
점[x=10,y=20]을 지웠습니다.
점[x=30,y=30,color=red]을 그렸습니다.
  • protected 로 부모가 설정하면, 자식이 사용 가능하다. show()에서 getX, getY가 아니라, x와 y로…

추상 클래스, 인터페이스 ex. paint예제

package paint;

public class Main {
	public static void main(String[] args) {
		Point point1 = new Point();
		point1.setX(10);
		point1.setY(20);
		
		Point point2 = new Point(20,30);
		
		//drawPoint(point1);
		draw(point1);
		//drawPoint(point2);
		draw(point2);
		//point1.disappear();
		point1.show(false);
		
		Point point3 = new ColorPoint(); //업캐스팅 (암시)
		point3.setX(30);
		point3.setY(30);
		
		//ColorPoint p = (ColorPoint)point3; //다운캐스팅 (명시)
		((ColorPoint)point3).setColor("red"); //다운캐스팅
		//drawPoint(point3);
		draw(point3);
		
		Rect rect = new Rect();
//		drawRect(rect);
		//drawShape(rect);
		draw(rect);
		
		Triangle triangle = new Triangle();
		//drawShape(triangle);
		draw(triangle);
		
		Circle circle = new Circle();
		//drawShape(circle);
		draw(circle);
		
		draw(new GraphicText("Hello world"));
	}
	/**
	private static void drawShape(Shape shape) {
		shape.draw();
		
	}
	public static void drawPoint(Point point) {
		point.show();
	}
	
	public static void drawRect(Rect rect) {
		rect.draw();
	}
	**/
	public static void draw(Drawable drawable) {
		drawable.draw();
	}

}

package paint;

public class ColorPoint extends Point{

	private String color;

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
	
	//annotation = marking = tag : 컴파일러가 오류인지 확인해줌. + 개발자가 이해가 쉽다.
	@Override
	public void show() {
		System.out.println("점[x=" + x + ",y=" + y + ",color=" + color + "]을 그렸습니다.");
	}
	
	

}

package paint;

public class Point implements Drawable {
	protected int x;
	protected int y;

	public Point() {
	}

	public Point(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public void show() {
		System.out.println("점[x=" + x + ",y=" + y + "]을 그렸습니다.");
	}

	public void show(boolean visible) {
		if (visible) {
			show();
		} else {
			System.out.println("점[x=" + x + ",y=" + y + "]을 지웠습니다.");
		}
	}

	@Override
	public void draw() {
		show();
	}

	// public void disappear() {
	// System.out.println("점[x=" + x + ",y=" + y + "]을 지웠습니다.");
	// }

}

package paint;

public abstract class Shape implements Drawable{
	private String lineColor;
	private String fillColor;
	public String getLineColor() {
		return lineColor;
	}
	public void setLineColor(String lineColor) {
		this.lineColor = lineColor;
	}
	public String getFillColor() {
		return fillColor;
	}
	public void setFillColor(String fillColor) {
		this.fillColor = fillColor;
	}
	
}

package paint;

public class Rect extends Shape{
	private int x1, y1;
	private int x2, y2;
	private int x3, y3;
	private int x4, y4;

	public int getX1() {
		return x1;
	}

	public void setX1(int x1) {
		this.x1 = x1;
	}

	public int getY1() {
		return y1;
	}

	public void setY1(int y1) {
		this.y1 = y1;
	}

	public int getX2() {
		return x2;
	}

	public void setX2(int x2) {
		this.x2 = x2;
	}

	public int getY2() {
		return y2;
	}

	public void setY2(int y2) {
		this.y2 = y2;
	}

	public int getX3() {
		return x3;
	}

	public void setX3(int x3) {
		this.x3 = x3;
	}

	public int getY3() {
		return y3;
	}

	public void setY3(int y3) {
		this.y3 = y3;
	}

	public int getX4() {
		return x4;
	}

	public void setX4(int x4) {
		this.x4 = x4;
	}

	public int getY4() {
		return y4;
	}

	public void setY4(int y4) {
		this.y4 = y4;
	}

	@Override
	public void draw() {
		System.out.println("사각형을 그렸습니다.");
	}


}

package paint;

public class Triangle extends Shape {

	private int x1, x2, x3;

	public int getX1() {
		return x1;
	}

	public void setX1(int x1) {
		this.x1 = x1;
	}

	public int getX2() {
		return x2;
	}

	public void setX2(int x2) {
		this.x2 = x2;
	}

	public int getX3() {
		return x3;
	}

	public void setX3(int x3) {
		this.x3 = x3;
	}

	@Override
	public void draw() {
		System.out.println("삼각형을 그렸습니다.");
	}

}

package paint;

public class Circle extends Shape {
	
	private int x1, y1;
	private int radius;
	
	@Override
	public void draw() {
		System.out.println("원을 그렸습니다.");
	}
}

package paint;

public interface Drawable {
 void draw();
           
}

package paint;

public class GraphicText implements Drawable {
	private String text;

	public GraphicText(String text) {
		this.text = text;
	}

	@Override
	public void draw() {
		System.out.println("텍스트 '" + text + "'를 그렸습니다.");
	}
}

상속 vs 인터페이스

상속으로만 확장을 위해 이용한다면, 굳이 필요없는 것 까지도 모두 자식에게 내려오는 경우가 발생할 수 있다.

그럴 때, 인터페이스를 이용하여 필요한 것 하위레벨에 구현되도록 돕는다.

instanceof 연산자

//instanceof 연산자 Test
		System.out.println(circle instanceof Object);
		System.out.println(circle instanceof Shape);
		System.out.println(circle instanceof Circle);
		
		//오류: 연산자 우측항이 클래스인 경우, 
		//     레퍼런스 하고 있는 class 타이브이 hierachy상의 하위와 상위만 instanceof 연산자를 사용할 수 있다.
		// System.out.println(circle instanceof Rect);
		
		//연산자 우측항이 인터페이스인 경우, 
		// hierachy 상관없이 instanceof 연산자를 사용할 수 있다.
		System.out.println(circle instanceof Drawable);
		System.out.println(circle instanceof Runnable); //false 출력

객체가 특정 클래스나 인터페이스의 인스턴스인지를 확인하는 데 사용됩니다. 주로 객체 지향 언어에서 런타임에 타입 체크를 수행하는 데 활용됩니다.

package 사용 - 소문자!!

  • import는 class 파일이 커지는 것이 아니라, 컴파일할 때, 이 내용을 참조하려고 하는 것이다. 모든 class는 method area에 적재된다.

  • package 용도?

  1. 클래스의 식별

a 패키지의 A 클래스 b 패키지의 A 클래스

a.A a1 = new a.A();
b.A a2 = new b.A();
  1. 구조적 분리

ex. paint 프로그램

com.poscodx.paint.i // 인터페이스
com.poscodx.paint.point
com.poscodx.paint.shape //도형
com.poscodx.paint.text
com.poscodx.paint.main

image

예외 처리

  1. checkedException
    • try-catch
package exception;

public class ExceptionTest {
	public static void main(String[] args) {

		int a = 10;
		int b = 10 - a;

		// int result = (1 + 2 + 3) / b; //오류 발생 : 0으로 나누기

		System.out.println("Some Code1");
		try {
			System.out.println("Some Code2");
			int result = (1 + 2 + 3) / b;

			// 예외 발생 후 바로 catch 실행이 되며, code3은 출력되지 않음.
			System.out.println("Some Code3");
		} catch (ArithmeticException ex) {
			/* 예외 처리 */
			// 1. 로깅 - 파일로 남김
			System.out.println("예외발생: " + ex);

			// 2. 사과
			System.out.println("미안합니다...");

			// 3. 정상종료 - 이게 있으면 code4가 출력이 안됨.
			// System.exit(1);
			// or return;
		} finally { // 옵션. 자원정리를 위함.
			System.out.println("자원정리: file close, socket close, ...");
		}

		// 원칙적으로 가급적 여기에 코드를 적지 말아야함.
		System.out.println("Some Code4");
	}
}


package exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileTest {
	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("hello.txt");

			int data = fis.read();

			System.out.println((char) data);
		} catch (FileNotFoundException e) {
			System.out.println("error:" + e);
		} catch (IOException e) {
			System.out.println("error:" + e);
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

  1. uncheckedException
public class UncheckedException {

	public static void main(String[] args) {
		int[] a = { 1, 2, 3, 4, 5 };
		// logical Error
		for (int i = 0; i <= a.length; i++) {
			System.out.println(a[i]);
		}
	}
}

프로그램이 돌아가는 때 나는 에러에 대한 예외.

image