패키지
하나의 클래스 안에서 같은 이름의 클래스들을 사용하기 위한 방법
경로 \org\opentutorials\javatutorials\object\
패키지 이름 package org.opentutorials.javatutorials.object;
package org.opentutorials.javatutorials.packages.example1;
public class A {}
package org.opentutorials.javatutorials.packages.example2;
import org.opentutorials.javatutorials.packages.example1.A;//example1의 A클래스를 가져옴
public class B {
public static void main(String[] args) {
A a = new A();
}
}
import org.opentutorials.javatutorials.packages.example1.*;//exam
ple1의 모든 클래스를 로드함
프로젝트 디렉토리 -> javac src/org/opentutorials/javatutorials/packages/example3/*.java
-d bin
컴파일된 결과를 bin디렉토리 하위에
import 하고 있는 두개의 패키지에 클래스 B가 존재하는 경우
public class D {
public static void main(String[] args) {
B b = new B();
}
}
//The type B is ambiguous
org.opentutorials.javatutorials.packages.example2.B b = new org.opentutorials.javatutorials.packages.example2.B();
와 같이 생성하여 해결
API
System.out.println(1);
System->클래스
println->메소드
out->클래스 변수, static이기 때문에 인스턴스를 만들지 않고 접근가능할 것
import java.lang.*;
즉 System은 java.lang 내의 클래스이다
API란 자바 시스템을 제어하기 위해서 자바에서 제공하는 명령어들을 의미한다.
기본 패키지들
java.lang
자바 프로그래밍을 위한 가장 기본적인 패키지와 클래스를 포함하고 있다.
java.util
프로그램을 제어하기 위한 클래스와 데이터를 효율적으로 저장하기 위한 클래스들을 담고 있다.
java.io
키보드, 모니터, 프린터, 파일등을 제어할 수 있는 클래스들의 모음
java.net
통신을 위한 기능들을 담고 있다
접근 제어자
클래스 멤버들의 접근 권한 지정
package org.opentutorials.javatutorials.accessmodifier;
class A {
public String y(){
return "public void y()";
}
private String z(){
return "public void z()";
}//클래스 내부적으로 사용하기 위함
public String x(){
return z();
}//같은 클래스 멤버인 z를 호출할 수 있음
}
public class AccessDemo1 {
public static void main(String[] args) {
A a = new A();
System.out.println(a.y());
// 아래 코드는 오류가 발생한다.
//System.out.println(a.z());
System.out.println(a.x());
}
}
클래스 멤버의 접근 제어자
public protected default private
같은 패키지, 같은 클래스 허용 허용 허용 허용
같은 패키지, 상속 관계 허용 허용 허용 불용
같은 패키지, 상속 관계 아님 허용 허용 허용 불용
다른 패키지, 상속 관계 허용 허용 불용 불용
다른 패키지, 상속 관계 아님 허용 불용 불용 불용
클래스의 접근 제어자 - default, public
public: 다른 패키지의 클래스에서 사용 가능
default: 같은 패키지에서만 사용 가능
*public 클래스가 포함된 소스코드는 public 클래스의 클래스 명과 소스코드의 파일명이 같아야 한다. -> 하나의 소스 코드에는 하나의 public 클래스가 존재할 수 있다.
abstract 추상 클래스 - 반드시 상속해서 사용하도록 강제하는 것
추상 메소드 : 메소드의 시그니처만이 정의된 비어있는 메소드
abstract class A{//추상 클래스
public abstract int b();
//public abstract int c(){System.out.println("Hello")}//본체가 있는 메소드는 abstract 키워드를 가질 수 없음
public void d(){//추상 메소드 아님
System.out.println("world");
}
}
public class AbstractDemo {
public static void main(String[] args) {
A obj = new A();//A의 인스턴스를 생성할 수 없음!!->에러
}
}
//추상 메소드의 구체적인 구현은 하위 클래스에서 오버라이딩 해야 한다
추상 클래스의 상속
: 하위 클래스를 만들고 추상 메소드를 오버라이드하여 기능을 구현
abstract class A{
public abstract int b();//추상 메소드
public void d(){
System.out.println("world");
}
}
class B extends A{
public int b(){return 1;}//오버라이딩
}
final
static final double PI = 3.14; // 변경 불가능
class A{
final void b(){}
}
class B extends A{
void b(){}//final 메소드 상속 불가능-> error!!
}
final class C{
final void b(){}
}
class D extends C{}//final 클래스 상속 불가능 -> error!!
인터페이스
: 어떤 객체가 있고 그 객체가 특정한 인터페이스를 사용한다면 그 객체는 반드시 인터페이스의 메소드들을 구현해야 한다.
interface I{
public void z();
}
class A implements I{//인터페이스 I를 구현함
public void z(){}//반드시 존재해야 함
}
실질적 쓰임 -협업자 상호간의 구체적인 약속
인터페이스의 규칙
: 하나의 클래스가 여러 개의 인터페이스를 구현할 수 있다.
인터페이스도 상속이 된다.
인터페이스의 멤버는 반드시 public이다.
다형성
: 다형성이란 동일한 조작방법으로 동작시키지만 동작방법은 다른 것을 의미한다.
ex) 오버로딩
class A{}
class B extends A{}
public class PolymorphismDemo1 {
public static void main(String[] args) {
A obj = new B();//A형 클래스에 B를 대입-->가능!
}
}
class A{
public String x(){return "x";}
}
class B extends A{
public String y(){return "y";}
}
public class PolymorphismDemo1 {
public static void main(String[] args) {
A obj = new B();//B가 마치 A인 것처럼 동작
obj.x();//실행 O
obj.y();//실행 X
}
}
class A{
public String x(){return "A.x";}
}
class B extends A{
public String x(){return "B.x";}
public String y(){return "y";}
}
public class PolymorphismDemo1 {
public static void main(String[] args) {
A obj = new B();
System.out.println(obj.x());//B.x 출력
}
}
//클래스 B를 클래스 A의 데이터 타입으로 인스턴스화 했을 때 클래스 A에 존재하는 맴버만이 클래스 B의 맴버가 된다. 동시에 클래스 B에서 오버라이딩한 맴버의 동작방식은 그대로 유지한다.
하나의 클래스(Calculator)가 다양한 동작 방법(ClaculatorDecoPlus, ClaculatorDecoMinus)을 가지고 있는데 이것을 다형성이라고 할 수 있겠다.
인터페이스와 다형성
interface father{}
interface mother{}
interface programmer{
public void coding();
}
interface believer{}
class Steve implements father, programmer, believer{
public void coding(){
System.out.println("fast");
}
}
class Rachel implements mother, programmer{
public void coding(){
System.out.println("elegance");
}
}
public class Workspace{
public static void main(String[] args){
programmer employee1 = new Steve();
programmer employee2 = new Rachel();
employee1.coding();//오버로딩 -> fast
employee2.coding();//오버로딩 -> elegance
}
}
예외
문법 -
class Calculator{
int left, right;
public void setOprands(int left, int right){
this.left = left;
this.right = right;
}
public void divide(){
try {
System.out.print("계산결과는 ");
System.out.print(this.left/this.right);
System.out.print(" 입니다.");
} catch(Exception e){
System.out.println("오류가 발생했습니다 : "+e.getMessage());
}//0으로 나누려고 할 때 오류 메세지 출력
}
}
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOprands(10, 0);
c1.divide();
Calculator c2 = new Calculator();
c2.setOprands(10, 5);
c2.divide();
}
}
try...catch 문법
try{
예외의 발생이 예상되는 로직
}catch(예외클래스 인스턴스){
예외가 발생했을 때 실행되는 로직
}
catch (Exception e) java.lang 소속
메소드를 호출하듯이 catch를 호출하면서 그 인자로 Exception 클래스의 인스턴스를 전달하는 것
e.getMessage() e의 메소드 중 하나. 오류의 원인을 리턴
뒷수습의 방법
public void divide(){
try {
System.out.print("계산결과는 ");
System.out.print(this.left/this.right);
System.out.print(" 입니다.");
} catch(Exception e){
System.out.println("\n\ne.getMessage()\n"+e.getMessage());//오류에 대한 기본적인 내용
System.out.println("\n\ne.toString()\n"+e.toString());//java.lang.ArithmeticException: / by zero
//더 자세한 예외 정보
System.out.println("\n\ne.printStackTrace()");//리턴값 없는 메소드, 내부적으로 예외 결과를 화면에 출력, 가장 자세함
e.printStackTrace();
}
}
같은 로직이지만 상황에 따라서 다른 예외가 발생할 수 있다 -->
try {
System.out.println(arr[first] / arr[second]);
} catch(ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsException");
} catch(ArithmeticException e){
System.out.println("ArithmeticException");
} catch(Exception e){//포괄적인 예외를 의미, 마지막에 위치해야 함
System.out.println("Exception");
}
finally -> 예외와 관계없이 실행되는 로직
try {
System.out.println(arr[first] / arr[second]);
} catch(ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsException");
} catch(ArithmeticException e){
System.out.println("ArithmeticException");
} catch(Exception e){
System.out.println("Exception");
} finally {
System.out.println("finally");
}
예외 던지기
public class CheckedExceptionDemo {
public static void main(String[] args) {
BufferedReader bReader = new BufferedReader(new FileReader("out.txt"));
//out.txt파일을 읽어야 하는데 파일이 없는 경우(FileNotFoundException)에 대한 예외처리가 필요함
String input = bReader.readLine();
//readLine메소드에서 IOException이 발생할 수 있음
System.out.println(input);
}
}
public static void main(String[] args) {
BufferedReader bReader = null;
String input = null;
try {
bReader = new BufferedReader(new FileReader("out.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try{
input = bReader.readLine();
} catch (IOException e){
e.printStackTrace();
}
System.out.println(input);
}
throw 사용 - 예외처리를 다음 사용자에게 넘김
class B{
void run(){
}
}
class C{
void run(){
B b = new B();
b.run();
}
}
public class ThrowExceptionDemo {
public static void main(String[] args) {
C c = new C();
c.run();//->main이 c.run()을 사용 -> c.run()이 b.run()을 사용
}
}
//
class B{
void run(){
BufferedReader bReader = null;
String input = null;
try {
bReader = new BufferedReader(new FileReader("out.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try{
input = bReader.readLine();
} catch (IOException e){
e.printStackTrace();
}
System.out.println(input);
}//B.run() 에서 직접 예외 처리
}
class C{
void run(){
B b = new B();
b.run();
}
}
public class ThrowExceptionDemo {
public static void main(String[] args) {
C c = new C();
c.run();
}
}
//
class B{
void run() throws IOException, FileNotFoundException{//예외의 처리를 사용자에게 위임
BufferedReader bReader = null;
String input = null;
bReader = new BufferedReader(new FileReader("out.txt"));
input = bReader.readLine();
System.out.println(input);
}
}
class C{
void run(){
B b = new B();
try {//b.run()의 실행에 대한 예외 처리
b.run();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ThrowExceptionDemo {
public static void main(String[] args) {
C c = new C();
c.run();
}
}
//main에게 위임하기
class B{
void run() throws IOException, FileNotFoundException{
BufferedReader bReader = null;
String input = null;
bReader = new BufferedReader(new FileReader("out.txt"));
input = bReader.readLine();
System.out.println(input);
}
}
class C{
void run() throws IOException, FileNotFoundException{
B b = new B();
b.run();
}
}
public class ThrowExceptionDemo {
public static void main(String[] args) {
C c = new C();
try {
c.run();//c.run()의 실행에 대한 예외 처리
} catch (FileNotFoundException e) {
System.out.println("out.txt 파일은 설정 파일 입니다. 이 파일이 프로잭트 루트 디렉토리에 존재해야 합니다.");
} catch (IOException e) {
e.printStackTrace();
}
}
}//엔드유저인 사용자가 out.txt를 잘 위치시켜야 하는 문제 -> main으로 책임을 넘김
예외 - 만들기
나누기 할때 0으로 나누게 되는 문제에 대한 조치
1. setOprands의 두번째 인자로 0이 들어오면 예외를 발생시킨다.
2. 메소드 divide를 실행할 때 right의 값이 0이라면 예외를 발생시킨다.
class Calculator{
int left, right;
public void setOprands(int left, int right){
if(right == 0){
throw new IllegalArgumentException("두번째 인자의 값은 0이 될 수 없습니다.");
//throw new ArithmeticException("0으로 나누는 것은 허용되지 않습니다.");
//에러 메세지로 처리됨
}
this.left = left;
this.right = right;
}
public void divide(){
try {
System.out.print("계산결과는 ");
System.out.print(this.left/this.right);
System.out.print(" 입니다.");
} catch(Exception e){
System.out.println("\n\ne.getMessage()\n"+e.getMessage());
System.out.println("\n\ne.toString()\n"+e.toString());
System.out.println("\n\ne.printStackTrace()");
e.printStackTrace();
}
}
}
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOprands(10, 0);
c1.divide();
}
}
예외 사용해야 할 상황
IllegalArgumentException 매개변수가 의도하지 않은 상황을 유발시킬 때
IllegalStateException 메소드를 호출하기 위한 상태가 아닐 때
NullPointerException 매개 변수 값이 null 일 때
IndexOutOfBoundsException 인덱스 매개 변수 값이 범위를 벗어날 때
ArithmeticException 산술적인 연산에 오류가 있을 때
예외의 여러가지 상황들
IOException만 try..catch 또는 throw 하여야 한다.
class E{
void throwArithmeticException(){
throw new ArithmeticException();
}
void throwIOException1(){
try {
throw new IOException();
} catch (IOException e) {
e.printStackTrace();
}
}
void throwIOException2() throws IOException{//예외처리 강제
throw new IOException();
}
}
/*
ArithmeticException 클래스는 Exception 클래스의 하위 클래스였던 것이다. 그렇기 때문에 Exception 클래스가 더 많은 예외 상황을 포괄하는 것이고 ArithmeticException 클래스는 더 구체적인 상황을 특정하는 것이다.
*/
java.lang.Throwable 클래스 - 던질 수 있는 클래스는 반드시 Throwable 클래스를 상속받아야 함
예외의 종류
Throwable
Error - 가상 머신의 문제, ex- 메모리가 부족한 경우
Exception
checked예외 - RuntimeException제외한 Exception의 하위 클래스 : 반드시 예외 처리
unchecked예외 - RuntimeException의 하위 클래스 : 예외 처리 안 해도 됨
직접 예외 만들기
??나중에 다시 볼 것
Object 클래스
모든 클래스는 Object를 상속받는다
toString메소드 - 객체를 문자로 표현
System.out.println(인스턴스);
=> 패키지이름.클래스이름@인스턴스정보
System.out.print로 객체를 호출하면 자동으로 toString이 호출됨
class C1{
int a,b;
C1(){
a=5; b=3;
}
public String toString() {
return "a:"+a+" b:"+b;
//a:5 b:3
}//toSTring메소드 오버로딩
}
public class ObjectClass {
public static void main(String[] args) {
C1 c1=new C1();
System.out.println(c1);
c1.toString();
}
}
equals메소드
package opentutorials.objectclass;
class Student{
String name;
Student(String name){
this.name=name;
}
public boolean equals(Object obj) {
Student _obj=(Student)obj;//obj를 Student형으로 형변환
return this.name==_obj.name;//주의 ==연산자는 원시 데이터형을 비교할 때만 사용(byte,int,double,char,,,)
}
}
public class EqualsClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student std1=new Student("호랑이");
Student std2=new Student("토끼");
Student std3=new Student("호랑이");
System.out.println(std1.equals(std2));//false
System.out.println(std1.equals(std3));//true
}
}
finalize - 객체가 소멸할 대 호출되기로 약속한 메소드
//garbage collection : 쓰지 않은 (인스턴스)데이터를 삭제
clone 메소드 : 객체를 복제해준다
Cloneable 인터페이스의 실제 코드
public interface Cloneable {}
//사실 잘 이해하지 못함
package opentutorials.clone;
class Student implements Cloneable{//Cloneable 인터페이스를 구현
String name;
Student(String name){
this.name = name;
}
protected Object clone() throws CloneNotSupportedException{
System.out.println(super.clone().getClass());//Student 클래스
return super.clone();//자기자신과 동일한 object를 반환
}
}
class ObjectDemo {
public static void main(String[] args) {
Student s1 = new Student("egoing");
try {
Student s2 = (Student)s1.clone();//s1.clonse() Object를 생성 -> Student형 변환하여 s2에 대입
System.out.println(s1.name);
System.out.println(s2.name);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
'JAVA' 카테고리의 다른 글
JAVA 플레이 그라운드 (0) | 2019.06.22 |
---|---|
자바 - 파일 입출력 (0) | 2019.05.30 |
자바 - 나무보다 숲을 보자(3) (0) | 2019.05.24 |
자바 - 나무보다 숲을 보자(2) (0) | 2019.05.21 |
자바 - 나무보다 숲을 보자(1) (0) | 2019.05.19 |