위 글은 해당 카테고리의 수업 강의 자료와 Power Java Compact 책을 정리한 내용입니다.
http://www.yes24.com/Product/Goods/59190885
Power JAVA Compact - YES24
자바는 현재 전 세계 개발자들이 가장 많이 사용하는 언어이기 때문에 컴퓨터 공학도라면 반드시 알고 지나가야 하는 중요한 주제이다. 이 책의 가장 큰 목표는 입문자들이 쉽게 이해할 수 있는
www.yes24.com
객체 구성 요소
객체: 속성과 기능의 집합으로 속성과 기능을 객체의 멤버라고 함
- 속성은 필드
- 기능은 메소드
클래스: 객체를 정의, 객체를 생성하는데 사용
인스턴스: 객체는 인스턴스의 의미로 객체가 메모리에 할당되어 실제 사용될 때 인턴스라고 부름
인스턴스화: 클래스로부터 인스턴스를 생성하는 것
캡슐화
- 객체의 실제 구현된 내용을 외부에 감추는 것
- 외부에서 공개된 필드와 메소드만 접근 가능
- 접근 제한자를 사용해서 객체의 필드와 메소드의 사용범위를 제한하게 됨
상속
- 이미 만든 객체와 비슷하나 필드와 메소드가 약간 차이가 나는 객체를 생성하는 경우
- 기존의 클래스에서 필드와 메소드를 상속(즉 ,재사용)하고 더 필요한 필드와 메소드를 추가함
- 상속의 개념은 코드를 간결하게 하고 코드의 재사용성을 높임
다형성
- 하나의 메소드나 클래스를 다양한 구현으로 사용 가능하게 하는 개념
- 오버로드와 오버라이드를 통해 구현
클래스의 구조
// 클래스 헤더
public class Car {
// 필드(멤버변수): 객체의 데이터, 상태를 저장하는 변수
private String name;
private int speed;
// 생성자: 클래스 이름과 같은 메소드
public Car(){
}
public Car(String name, int speed){
this.name = name;
this.speed = speed;
}
// 메소드
public void SetName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
접근자
- 주로 객체에 대한 정보(멤버변수와 메소드)의 접근을 제한하기 위해 사용
- 캡슐화 정보은닉을 위한 방법
- public > protected > default > private
메소드: 객체의 기능 또는 행동을 정의하는 함수
Getter와 Setter 메소드
(이클립스 단축키: 오른쪽키 Source)
- 클래스를 정의할 때 필드는 private로 하여 객체 내부의 정보를 보호하고(정보은닉) 필드에 대한 Setter와 Getter를 두어 객체의 값을 변경하고 참조하는 것이 좋음
- 외부에서 읽기만 가능하게 하기 위해선 Getter만 작성
- 외부에서 쓰기만 가능하게 하기 위해선 Setter만 작성
- Getter와 Setter가 없으면 객체 내부 전용 변수가 됨
생성자
- 클래스로부터 객체를 생성할 때 호출되고 객체의 초기화를 담당
- 생성자를 실행시키지 않고 클래스로부터 객체를 만들 수 없음
- 모든 클래스에는 반드시 하나 이상의 생성자가 있어야 함
- 생성자의 이름은 클래스와 같아야 함
- 생성자는 리턴 값이 없고 void를 쓰지 않음
접근자 클래스이름(파라미터){
// 인스턴스 생성시 수행할 코드 (주로 인스턴스 변수 초기화 코드)
}
public class Goods{
// 매개변수가 없는 생성자
public Goods() {
// 초기화 코드
}
// 매개변수가 있는 생성자
public Goods(String name, int price){
// 초기화 코드
}
}
- 기본 생성자
- 매개변수가 없는 생성자
- 클래스에 생성자가 한 개도 정의되어 있지 않으면 컴파일러가 기본 생성자를 추가
- 생성자가 한 개라도 있으면 기본 생성자를 추가하지 않음
- 여러 개의 생성자를 사용할 수 있음 ➡️ 생성자 오버로딩
public class Goods{
public Goods() {
// 초기화 코드
}
}
this 참조변수
- 현재 객체(메소드 호출을 받는 객체)를 가리키는 참조변수
- 현재 사용중인 객체 그 자체를 의미
- 컴파일러가 자동으로 생성
- 클래스의 한 생성자에서 다른 생성자를 호출할 때 사용 가능
public class Circle{
int radius;
public Circle(int radius){
this.radius = radius;
// this.radius = 필드, radius = 매개변수
}
double calcArea(){
return 3.14*radius*radius;
}
}
메소드 오버로딩 (메소드 중복 정의)
- 하나의 클래스에 같은 이름의 메소드가 여러 개 존재할 수 있음
- 매개변수의 타입, 개수, 순서가 다른 형태로 구별
- 동일한 이름(메소드 이름)의 상이한 시그니처
- 메소드 시그니처: 메소드 인자의 타입, 개수, 순서
정적변수와 인스턴스변수, 지역변수
- 인스턴스 변수
- 동일한 클래스를 이용하여 많은 객체들이 생성될 때 각각의 객체(인스턴스)들은 자신만의 필드를 가짐
- 각 인스턴스의 개별적인 저장 공간 인스턴스마다 다른 값 저장 가능
- 이들 필드는 인스턴스마다 별도로 생성되어 인스턴스 변수라고 함
- 인스턴스 생성 후 참조변수.인스턴스 변수명 으로 접근
- 인스턴스를 생성할 때 생성되고 참조변수가 없을 때 가비지 컬렉터에 의해 자동 제거
- 동일한 클래스를 이용하여 많은 객체들이 생성될 때 각각의 객체(인스턴스)들은 자신만의 필드를 가짐
- 클래스(정적) 변수
- 클래스 당 하나만 생성되는 변수
- 하나의 클래스에 하나만 만들어지고 동일한 클래스의 모든 객체들은 하나의 정적 변수를 공유
- 같은 클래스의 모든 인스턴스들이 공유하는 변수
- 객체(인스턴스) 없이도 사용 가능 클래스이름.static변수명 으로 접근
- 클래스가 로딩될 때 생성되고 프로그램이 종료될 때 소멸
- 지역변수
- 메소드 내에 선언되며 메소드의 종료와 함께 소멸
인스턴스 변수와 클래스(정적)변수의 차이점
- 인스턴스 변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값 유지 가능
- 클래스(정적) 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로 항상 공통된 값을 가짐
클래스(정적) 메소드
- 전역변수와 전역함수를 만들 때 사용
- 모든 클래스에서 공유하는 전역 변수나 전역 함수를 만들어 사용 가능
- 객체를 생성하지 않고 접근 가능
- static 메소드에서는 this 사용 불가
- static 메소드내 는 static 멤버만 접근할 수 있음
상속: 부모 클래스에 정의된 필드와 메소드를 자식 클래스가 물려 받는 것
상속의 필요성
- 클래스 사이의 멤버 중복 선언 불필요
- 필드, 메소드 재사용으로 클래스가 간결
- 클래스간 계층적 분류 및 관리
자바 상속의 특징
- 자바에서는 다중 상속을 지원하지 않음
- 자바에서는 상속의 횟수에 제한 두지 않음
- 자바에서 계층구조의 최상위에 있는 클래스는 java.lang.Object
상속 선언:extens 키워드 사용
public class Person {
public void tell()
public void eat()
public void walk()
public void speed()
}
public class Student extends Person {
public void study()
}
상속과 생성자
- 자식 생성자에서 특별한 지시가 없으면 부모 클래스의 기본 생성자가 선택됨
- 부모 클래스의 특정 생성자를 호출해야 할 경우에는 super()를 이용하여 명시적으로 부모 클래스의 생성자를 호출
- 부모의 필드나 메소드에 접근시에는 super 키워드를 사용
- super를 사용하여 부모 클래스 멤버 접근
class Parent{
public void print(){
System.out.println("부모 클래스의 print 메소드");
}
}
class Child extends Parent{
// 슈퍼 클래스의 메소드 호출
public void print(){
super.print(); // 메소드 오버라이드
System.out.println("자식 클래스의 print 메소드");
}
}
public class ChildApp{
public static void main(String[] args){
Child obj = mew Child();
obj.print();
}
}
메소드 오버라이딩(메소드 재정의)
- 자식 클래스의 메소드가 부모 클래스의 메소드를 재정의
- 부모 클래스와 자식 클래스의 메소드 사이에서 발생하는 관계
- 부모 클래스의 메소드를 동일한 이름으로 재작성(같은 이름, 같은 리턴 타입, 같은 시그니처)
- 부모 클래스 메소드 무시하기
class Animal {
private void eat(){
System.out.println("동물이 먹고 있습니다");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("강아지가 먹고 있습니다");
}
}
public class DogApp{
public static void main(String[] args){
Dog d = new Dog();
d.eat();
}
}
상속과 다형성
- 업캐스팅(Up Casting)
- 자식 클래스가 부모 클래스 타입으로 변환되는 것
- 부모 클래스 참조 변수로 자식 클래스 객체를 참조할 수 있음
- 명시적으로 타입 변환을 하지 않아도 됨
- 다운캐스팅(Down Casting)
- 업캐스팅된 것을 원래대로 되돌리는 것
- 업캐스팅 서브 클래스 객체가 형변환에 의해 슈퍼 클래스 참조변수에 의해 참조되는 경우 원래 상태로 만들 수 있음
- 명시적으로 타입 변환을 해야 함
class Shape{
protected int x, y;
public void draw(){
System.out.println("Shape Draw");
}
}
class Rectangle extends Shape{
private int with, height;
public void draw(){
System.out.println("Rectangle Draw");
}
}
class Triangle extends Shape{
private int base, height;
public void draw(){
System.out.println("Rectangle Draw");
}
}
class Circle extends Shape{
private int radius;
public void draw(){
System.out.println("Circle Draw");
}
}
public class ShapeApp{
public static void main(String arg[]){
Shape s1, s2;
s1 = new Shape(); // 당연히 가능
s2 = new Rectangle(); // 가능할까?
}
}
Rectangle 객체가 생성되어서 Shape 참조 변수에 대입되는 문장은 오류로 볼 수 있으나 자식 클래스 객체 안에는 부모 클래스 부분이 있기 때문에 부모 클래스 객체처럼 취급될 수 있다
즉, 부모 클래스 참조변수로 자식 클래스 객체를 참조 할 수 있음
➡️ 이를 업캐스팅(상향 형변환)이라 함
여기서 s2를 통해 자식 클래스의 모든 멤버를 사용할 수 있을까? 는 아님
자식 클래스 중에서 부모 클래스로부터 상속받은 부분만을 s2를 통해 사용할 수 있고 나머지는 사용 못함
즉, s2 = new Rectangle(); 문장이 실행되면 Rectangle 객체 중에서 Shape로부터 상속 받은 부분은 s2를 통해 사용할 수 있지만 Rectangle 객체의 다른 부분은 s2를 통해서 사용할 수 없음
➡️ 근본적으로 s2는 Shape의 참조변수이기 때문
Animal ani = new Cat(); // 업캐스팅
Cat c = (Cat)ani; // 다운캐스팅
정리를 해도 3년 전처럼 별로 안와닿네...
참고할 자료... https://onepinetwopine.tistory.com/488
자바 Java ] 다형성 Polymorphism
다형성 다형성이란? 같은 함수를 불러도, 객체의 타입에 따라 다른 결과를 얻는 것입니다. 이는 형변환과 관련이 있습니다. 상향 형변환 동물을 상속받는 개, 고양이, 다람쥐 클래스가 있을 때,
onepinetwopine.tistory.com
추상화: 객체들이 가지고 있는 속성과 기능 중에 중요한 것들을 남기고 필요 없는 것은 없애는 것 또는 객체들간의 공통되는 특성을 추출하는 것
추상 클래스
- 실체 클래스의 공통적인 특성들을 추출해서 선언한 클래스
- 실체 클래스를 만들기 위한 부모 클래스로만 사용되는 클래스 (객체를 직접 생성해서 사용할 수 없음)
- 확장만을 위한 용도로 사용
- 하나 이상의 추상 메소드를 가져야 함
- 속성(필드)와 기능(메소드)를 정의할 수 있음
추상 클래스의 선언: abstract 키워드를 붙임
추상 클래스의 상속
- 추상 클래스의 상속에도 extends 키워드를 붙여야 함
- 추상 클래스를 상속하는 클래스는 반드시 추상 클래스의 추상 메소드를 구현해야 함
추상 클래스의 활용: 여러 클래스들이 상당수 공통점을 가지고 있으나 부분적으로 그 처리 방식이 다를 경우, 부모 클래스를 추상 클래스로 정의하여 자식 클래스들이 각각 해당 메소드를 구현
추상 메소드
- 몸체가 없는 메소드
- 항상 세미콜론으로 종료되어야 함
- 추상 클래스를 상속받는 자식 클래스에서는 반드시 추상 메소드를 재정의해야 함
- 구현이 불가능한 메소드로 선언만 함
- 추상 메소드는 추상 클래스에만 존재함
public abstract class Animal{
public abstract void move(); // 추상 메소드 정의 (세미콜론으로 종료 해야함)
}
public class Lion extends Animal{
public void move(){
System.out.println("사자의 move 메소드입니다.");
} // 추상 클래스를 상속받으면 추상 메소드를 구현해야 함
}
예시
abstract class Shape{ // 추상 클래스로 Shape를 선언, 추상 클래스로는 객체를 생성할 수 없음
int x,y;
public void move(int x, int y){ // 추상 메소드라도 추상 메소드가 아닌 보통 메소드도 가질 수 있음
this.x=x;
this.y=y;
}
public abstract void draw(); // 추상 메소드를 선언
// 추상 메소드를 하나라도 가지면 추상 클래스가 됨
// 추상 메소드를 가지고 있는데도 abstract를 class 앞에 붙이지 않으면 컴파일 오류가 발생함
};
class Rectangle extends Shape{
int width, height;
public void draw(){ // 추상 메소드 구현
// 자식 클래스 Rectangle에서 부모 클래스의 추상 메소드 draw()를 실제 메소드로 구현함
// 자식 클래스에서 추상 메소드를 구현하지 않으면 컴파일 오류가 발생함
System.out.println("사각형 그리기 메소드");
}
};
class Circle extends Shape{
int radius;
public void draw(){ // 추상 메소드 draw()를 실제 메소드로 구현함
System.out.println("원 그리기 메소드");
}
};
인터페이스 개념
- 서로 관계가 없는 물체들이 상호작용을 하기 위해서 사용하는 장치나 시스템
- 클래스 구조상의 관계와 상관 없이 클래스들에 의해 구현되어질 수 있는 규약
인터페이스 목적: 클래스들 사이의 유사한 특성을 부자연스러운 상속 관계를 설정하지 않고 얻어냄
인터페이스 활용
- 하나 또는 그 이상의 클래스들에서 똑같이 구현되어질법한 메소드를 선언하는 경우
- 클래스 자체를 드러내지 않고 객체의 프로그래밍 인터페이스를 제공하는 경우
인터페이스 선언: class 키워드를 사용하지 않고 interface 사용
public interface 인터페이스명{
// 추상 메소드 (abstract 키워드를 지정하지 않아도 됨)
}
인터페이스 구현
- 인터페이스만으로는 객체를 생성할 수 없음
- 인터페이스는 다른 클래스에 의해 구현될 수 없음
- 인터페이스를 구현한다 = 인터페이스에 정의된 추상 메소드의 몸체를 정의함
- 클래스가 인터페이스를 구현하기 위해서는 implements 키워드를 사용
public class Point implements 인터페이스명{
// 추상 메소드 구현 (abstract 키워드를 지정하지 않아도 됨)
}
예시 (Circle 클래스가 Drawable 인터페이스를 구현)
interface Drawable{
void draw();
}
class Circle implements Drawable{
int radius;
public void draw(){
System.out.println("Circle Draw");
}
}
public class TestInterface1{
public static void main(String args[]){
Drawable obj = new Circle();
obj.draw();
}
}
Circle은 Drawable 인터페이스를 구현하고 있음
따라서 다른 클래스들은 Circle이 draw() 메소드를 가지고 있음을 확신할 수 있음
즉, draw() 메소드를 호출할 수 있는 것
➡️ 인터페이스는 클래스와 클래스 사이의 상호작용을 정의하는 역할
- 상속과 동시에 인터페이스를 구현할 수 있음
public class Point implements Drawable, Resizeable{
}
예시 (Circle은 Shape 클래스를 상속받으면서 동시에 Drawable 인터페이스를 구현)
class Shape{
protected int x, y;
}
interface Drawable{
void draw();
}
class Circle extends Shape implements Drawable{
int radius;
public void draw(){
System.out.println("Circle Draw");
}
}
public class TestInterface2{
public static void main(String args[]){
Drawable obj = new Circle();
obj.draw();
}
}
- 인터페이스는 다중 상속을 지원하지 않는 자바에서 다중 상속의 장점을 활용하기 위해 도입됨
interface Printable{
void print();
}
interface Drawable{
void draw();
}
public class Circle implements Printable, Drawable{
public void print(){
System.out.println("프린트로 원을 출력합니다");
}
public void draw(){
System.out.println("화면에 원을 출력합니다");
}
public static void main(String args[]){
Circle obj = new Circle();
obj.print();
obj.draw();
}
}
예외처리
예외(Exception)
- 프로그램이 실행되는 동안 발생할 수 있는 비정상적인 조건
- 번역시의 에러가 아닌 실행시 에러를 예외라 함
자바에서 예외처리
- 예외처리를 위한 Exception 클래스 정의
- 기본적인 예외는 자바에 미리 정의된 예외를 통해 처리 가능
- 사용자가 필요한 예외를 직접 정의할 수 있음
- 예상되는 예외는 미리 처리해주면 무조건적인 프로그램의 종료를 피할 수 있음
- 예외처리의 사용은 프로그램의 신뢰성을 높여줌
try-catch-finally 구문
try{ // (0)
// 예외가 발생할 가능성이 있는 실행문(1)
} catch (처리할 예외 타입 선언){
// 예외 처리문(2)
} finally{
// 생략 가능
// 예외 발생 여부와 상관 없이 무조건 실행되는 문장(3)
} // (4)
try 블록에서 예외가 발생한 경우: 0 ➡️ 1 ➡️ 2 ➡️ 3 ➡️ 4
try 블록에서 예외가 발생하지 않는 경우: 0 ➡️1 ➡️ 3 ➡️ 4
예외 클래스
예외(Exception)의 구분
- Checked Exception: 컴파일 할 때 확인되는 예외로 예외처리가 필요함
- Unchecked Exception: 실행시점에 확인되는 예외로 예외처리를 하지 않아도 컴파일 됨
예외처리가 유용할 경우
- 파일을 다루는 경우
- 해당 파일이 존재하지 않거나 다른 프로세스에 의해 사용 중인 경우 예외 발생
- 입출력을 다루는 경우
- 이미 닫힌 입출력 스트림에 대해 작업하려 할 경우 예외 발생
- 네트워크를 통한 데이터 통신
- 서버나 클라이언트 한 쪽에서 응답이 없는 경우
- 네트워크 상태가 안좋아서 정해진 시간동안 데이터를 받지 못하는 경우
메소드 정의시 예외처리
- 해당 메소드를 호출하는 메소드에서 예외를 처리하도록 명시
- throws 키워드를 사용하여 예외의 종류를 적어줌
public class ThrowsExepApp{
public static void main( String[] args ) {
ThrowsExep exep= new ThrowsExep();
// IO exception발생
exep.executeExcept();
}
}
public class ThrowsExep {
public void executeExcept() throws IOException {
System.out.println( “강제예외발생” );
throw new IOException(); //강제로 예외 발생
}
}
'강의 > KOSTA' 카테고리의 다른 글
[Java] IOStream (Day8) (0) | 2022.03.15 |
---|---|
[Java] Collection Framework (Day7~8) (0) | 2022.03.14 |
[Java] Basic API (Day7) (0) | 2022.03.14 |
[Java] 부록(1) 객체지향 프로그래밍 연습문제 (0) | 2022.03.14 |
[Java] Introduction to Java (Day1~3) (0) | 2022.03.10 |