반응형

package ch98;

 

public class Product {

 

int price; // 제품의 가격

int bonusPoint; // 제품구매시 제공하는 보너스 점수

 

Product(int price) {

this.price = price;

bonusPoint = (int) (price / 10.0); // 보너스 점수는 제품가격의 10% 제공

}

} // end of Product class

 

 

package ch98;

 

public class Tv1 extends Product{

Tv1() {

// 조상클래스(Product)의 생성자 Product(int price)를 호출

super(100); // TV가격을 100만원

}

// Object 클래스의 toString()을 오버라이딩

public String toString() {

return "Tv";

}

}

package ch98;

 

public class Computer extends Product {

 

Computer() {

super(200); // 컴퓨터의 가격을 200만원으로 한다.

}

// Object 클래스의 toString()을 오버라이딩

public String toString() {

return "Computer";

}

}

package ch98;

 

public class Buyer { // 고객

int money = 1000; // 가지고있는 금액

int bounsPoint = 0; // 가지고있는 보너스점수

 

void buy(Product p) {

if (money < p.price) {

System.out.println("잔액이 부족해 물건을 구매할 수 없습니다.");

return;

}

 

money -= p.price; // 가진돈에서 구입한 물건의 값을 뺀다

bounsPoint += p.bonusPoint; // 구입한 물건의 보너스점수를 추가

System.out.println(p + "을/를 구매하였습니다.");

}

}

package ch98;

 

public class MainTest {

 

public static void main(String[] args) {

Buyer b = new Buyer();

b.buy(new Tv1());

b.buy(new Computer());

 

System.out.println("현재 남은 돈은 " + b.money + "만원 입니다.");

System.out.println("현재 보너스 점수는 " + b.bounsPoint + "점 입니다.");

 

}

 

}

Tv을/를 구매하였습니다.

Computer을/를 구매하였습니다.

현재 남은 돈은 700만원 입니다.

현재 보너스 점수는 30점 입니다.

반응형
반응형

기본형 변수처럼 참조변수도 형변환이 가능하다.

단, 서로 상속관계에 있는 클래스 사이에서만 가능!

자손타입의 참조변수를 조상타입의 참조변수로, 조상타입의 참조변수를 자손타입의 참조변수로의 형변환만 가능하다.

 


class Phone { }
class IPhone extends Phone { }
class AndroidPhone extends Phone { }

예를 들어 Phone클래스가 있고 이를 상속받는 IPhone과 AndroidPhone 클래스가 있을때,

  • IPhone타입의 참조변수 i는 조상타입인 Phone으로 형변환이 가능하다.
  • IPhone과 AndroidPhone은 상속관계가 아니기 때문에 형변환이 불가능하다.

IPhone i = new IPhone();

 

Phone p = (Phone)i; // ok. 조상인 Phone 타입으로 자동형변환(생략가능)

IPhone i2 = (IPhone)p; // ok. 자손인 IPhone 타입으로 형변환(생략불가)

//AndroidPhone a = (AndroidPhone)i; // no. 상속관계가 아닌 클래스 간에는 형변환 불가, IPhone과 AndroidPhone은 상속관계가 아님.

기본형의 형변환과 달리 참조형의 형변환은 변수에 저장된 값(주소값)이 변환되는 것이 아니다.

Phone p = (Phone)i; // i의 값(객체의 주소)을 p에 저장

                                // 타입을 일치시키기 위해 형변환 필요(생략가능함)

i = (IPhone)p; // 조상타입을 자손타입으로 형변환하는 경우 생략불가함

 

 

instanceof 연산자
: 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용하는 연산자
  • 주로 조건문에 사용
  • (참조변수) instanceof (타입(클래스명))
  • 연산의 결과로 boolean 값인 true와 false 중 하나를 반환함
  • 연산의 결과로 true를 얻었다면 참조변수가 검사한 타입으로 형변환이 가능하다는 뜻이다.
반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA 다시보기] 자바기초  (1) 2023.09.19
문자열 자료형  (1) 2023.09.08
[JAVA] 인터페이스(interface)  (0) 2023.08.11
[JAVA] String 클래스  (0) 2023.08.10
[JAVA] 추상 클래스와 메서드  (0) 2023.08.10
반응형
인터페이스
  • 일종의 추상클래스
  • 추상클래스처럼 추상메서드를 갖지만 추상클래스보다 추상화 정도가 높다
  • 추상클래스와 달리 몸통을 갖춘 일반 메서드 or 멤버변수를 구성원으로 가질 수 없다.
  • 오직 추상메서드와 상수만을 멤버로 가질 수 있으며, 그 외에 어떠한 요소도 허용하지 않는다.

추상클래스 = 부분적으로 완성된 미완성 설계도
인터페이스 = 구현된 것이 없는 밑그림만 그려져 있는 '기본 설계도'

 

 

인터페이스 작성해보기
  • 인터페이스를 작성하는 것은 클래스 작성하는 것과 같다.
  • 클래스는 class라는 키워드를 사용하지만 인터페이스는 interface라는 키워드를 사용한다.
  • interface는 접근제어자로 public 또는 default만 사용할 수 있다. 

interface 인터페이스이름 {
          public static final 타입 상수이름 = 값;
          public abstract 메서드이름(매개변수목록);
}

인터페이스 멤버들은 다음과 같은 제약사항이 있다.

  • 모든 멤버변수는 public static final 이어야 하고, 이를 생략할 수 있다.
  • 모든 메서드는 public abstract 이어야 하고, 이를 생략할 수 있다. (단 static과 default는 예외 JDK1.8부터)

 

인터페이스의 상속

인터페이스는 인터페이스부터만 상속받을 수 있으며, 클래스와는 달리 다중상속, 즉 여러개의 인터페이스로부터 상속 받는 것이 가능하다.

 

[사운드효과 인터페이스]

package ch12;

 

public interface SoundEffect {

public abstract void notification();

 

}

[리모컨 인터페이스]

package ch12;

 

public interface RemoteController {

void turnOn();

void turnOff();

}

[장난감 로봇이 리모컨과 사운드 효과 인터페이스를 상속받음]

package ch12;

 

public class ToyRobot extends RemoteController, SoundEffect { }

클래스의 상속과 마찬가지로 자손 인터페이스(ToyRobot)는 조상 인터페이스(RemoteController, SoundEffect)에 정의된 멤버를 모두 상속받는다.

ToyRobot 자체에는 정의된 멤버가 하나도 없지만 조상 인터페이스로 부터 상속받는 두 개의 추상메서드를 멤버로 갖게된다.

 

인터페이스의 구현

인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없으며, 추상클래스가 상속을 통해 추상메서드를 완성하는 것처럼, 인터페이스도 자신에 정의된 추상메서드의 몸통을 만들어주는 클래스를 작성해야 하는데, 그 방법은 추상클래스가 자신을 상속받는 클래스를 정의하는 것과 다르지 않다.

다만 클래스는 extends키워드를 사용하지만 인터페이스는 구현한다라는 의미의 implements를 사용한다.

 

package ch12;

 

public class ToyRobot implements RemoteController, SoundEffect {

 

 

@Override

public void turnOn() {

System.out.println("장난감 로봇을 켭니다.");

}

 

@Override

public void turnOff() {

System.out.println("장난감 로봇을 끕니다.");

}

 

@Override

public void notification() {

System.out.println("뚜뚜두두두두~~");

 

}

 

}

왜 인터페이스를 사용할까?
: 인터페이스의 장점은 아래와 같다.

- 개발시간 단축
- 표준화가 가능
- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
- 독립적인 프로그래밍이 가능
반응형

'Java > Java 이론' 카테고리의 다른 글

문자열 자료형  (1) 2023.09.08
[JAVA] 참조변수의 형변환  (0) 2023.08.11
[JAVA] String 클래스  (0) 2023.08.10
[JAVA] 추상 클래스와 메서드  (0) 2023.08.10
[JAVA] 다형성  (0) 2023.08.10
반응형

문자열을 만들 때에는 두 가지 방법, 문자열 리터럴을 지정하는 방법과 String 클래스의 생성자를 사용해서 만드는 방법이 있다.


변경불가능한 클래스

String 클래스에서는 문자열을 저장하기 위해 문자형 배열 참조변수(char[ ]) value를 인스턴스 변수로 정의해놓고있다.

한번 생성된 String인스턴스가 갖고 있는 문자열은 읽어 올 수 만있고, 변경할 수는 없다.

예를 들어 + 연산자를 이용해서 문자열을 결합하는 경우 인스턴스 내의 문자열이 바뀌는 것이 아니라 새로운 문자열이 담긴 String 인스턴스가 생성되는 것이다.

String str1 = "반가워"; // 문자열 리터럴 "반가워"의 주소가 str1에 저장됨

String str2 = new String("반가워");  // 새로운 String인스턴스를 생성

String str3 = "반가워";  // 문자열 리터럴 "반가워"의 주소가 str3에 저장됨

  • String 클래스의 생성자를 이용한 경우에는 new 연산자에 의해 메모리 할당이 이루어지기 때문에 항상 새로운 String 인스턴스가 생성된다.
  • 문자열 리터럴은 이미 존재하는 것을 재사용하는 것이다.

이 때의 몇가지 시나리오를 확인해보자.

public static void main(String[] args) {

 

// String

// 문자열이라는 데이터를 보관이나 연산할때 사용

// static 영역, 데이터 영역, --> 상수 풀 영역

 

String str1 = "반가워";

String str2 = new String("반가워");

String str3 = "반가워";

 

System.out.println(str1);

System.out.println(str2);

// 시나리오 1

if(str1 == str2) { // str1은 상수풀 영역에, str2는 힙메모리 영역에 있어 주소값이 다름

System.out.println("주소가 같아요");

} else {

System.out.println("주소값이 달라요");

}

 

// 시나리오 2

// 리터럴 방식으로 생성한 문자열은 이미 생성한 값이 똑같다면 새로 만들지 않고 재활용한다.

if(str1 == str3) {

System.out.println("주소 같음");

} else {

System.out.println("주소 다름");

}

System.out.println("=============================");

// 시나리오 3

str3 = "반갑습니다"; // 값을 변경

if(str1 == str3) { //str3의 값을 변경하여 상수 풀 메모리에 새로 생성됨

System.out.println("주소 같음");

} else {

System.out.println("주소 다름");

}

System.out.println("=============================");

// 시나리오 4

// 문자열에 값을 비교하려면 equals를 반드시 사용

if(str1.equals(str2)) { // str1과 str2의 주소값을 비교하는 것이 아닌 문자열을 비교하므로 값은 "반가워"로 같으므로 같은 값입니다가 출력

System.out.println("같은 값입니다.");

} else {

System.out.println("다른 값입니다.");

}

[실행값]

주소값이 달라요

주소 같음

=============================

주소 다름

=============================

같은 값입니다.

반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA] 참조변수의 형변환  (0) 2023.08.11
[JAVA] 인터페이스(interface)  (0) 2023.08.11
[JAVA] 추상 클래스와 메서드  (0) 2023.08.10
[JAVA] 다형성  (0) 2023.08.10
[JAVA] 객체지향 언어  (0) 2023.08.09
반응형

추상클래스(abstract class) : 미완성 설계도

클래스를 설계도로 비유하면 추상클래스는 미완성 설계도라 볼 수 있다. 클래스가 미완성이라는 것은 멤버의 개수에 관계된 것이 아니라, 단지 미완성 메서드(추상 메서드)를 포함하고 있다는 의미이다.

  • 미완성 설계도이므로 인스턴스를 생성할 수 없다.
  • 미완성 메서드(추상 메서드)를 포함하고 있는 클래스

추상 클래스 사용법은 'abstract'를 붙이기만 하면 된다.


abstract class 클래스이름 {
         ....
}
 추상메서드

메서드는 선언부와 구현부로 구성되어 있다.

선언부만 작성하고 구현부는 작성하지 않은 채로 남겨둔 것이 추상메서드이다.

즉, 설계만 해놓고 실제 수행될 내용은 작성하지 않았기 때문에 미완성 메서드인 것이다.

왜 미완성으로 놔둔 것일까? 그 이유는 메서드의 내용이 상속받는 클래스에 따라 달라질 수 있기 때문에 조상 클래스에서 선언부만 작성해놓고, 주석을 덧붙여 어떤 기능을 수행할 목적으로 작성되었는지 알려주고, 실제 내용은 상속받는 클래스에서 구현하도록 비워두는 것이다.

  • 추상메서드 역시 'abstract'를 앞에 붙여주고, 추상메서드는 구현부가 없으로 괄호 대신 문장의 끝을 알리는 세미콜론(;)을 적어준다.

// 주석을 통해 어떤 기능을 수행할 목적으로 작성하였는지 알려준다.
abstract 리턴타입 메서드이름 ( ) ;

package ch07_1;

 

public abstract class Computer {  // 추상클래스

 

public abstract void display();

public abstract void typing();

public void trunOn() {

System.out.println("전원을 킵니다.");

}

public void turnOff() {

System.out.println("전원을 끕니다");

}

}

package ch07_1;

 

public class DeskTop extends Computer {

 

 

// 추상메서드 -> 구현메서드로 오버라이딩

@Override

public void display() {

System.out.println("모니터로 화면을 보여줍니다.");

 

}

 

@Override

public void typing() {

System.out.println("키보드로 타이핑을 합니다.");

 

}

 

}

반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA] 인터페이스(interface)  (0) 2023.08.11
[JAVA] String 클래스  (0) 2023.08.10
[JAVA] 다형성  (0) 2023.08.10
[JAVA] 객체지향 언어  (0) 2023.08.09
[JAVA] switch 문  (0) 2023.08.09
반응형

다형성(polymorphism)  : 여러 가지 형태를 가질 수 있는 능력

  • 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
  • 같은 코드에서 여러 다른 실행 결과가 나옴
  • 정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나
  • 다형성을 잘 활용하면 유연하고, 확장성있고, 유지보수가 편리한 프로그램을 만들 수 있음

이전까지 인스턴스 타입과 일치하는 타입의 참조변수만을 사용해왔지만

만약 두 클래스가 상속관계라면 다형성을 적용할 수 있다. 즉, 조상 클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조하는 것도 가능하다.

package ch06;

 

public class Animal {

 

public void makeSound() {

System.out.println("동물이 소리를 내고 있습니다.");

}

 

 

}

package ch06;

 

public class Brid extends Animal{

 

@Override

public void makeSound() {

System.out.println("새가 지저귀고 있습니다.");

}

 

public void fly() {

System.out.println("새가 날아갑니다.");

}

 

}


Bird b = new Brid ( ) ;   // 참조 변수와 인스턴스의 타입이 일치
Animal a = new Brid ( ); // 조상 타입(Animal) 참조 변수로 자손타입(Bird) 인스턴스 참조

Animal 타입의 참조변수로는 Bird 인스턴스 중에서 Animal 클래스의 멤버들(상속받은 멤버포함)만 사용할 수 있다.

따라서 생성된 Bird 인스턴스 멤버 중에서 Animal 클래스에 정의되지 않은 멤버 fly( )은 참조변수 a로 사용이 불가능하다.

즉, a.fly( )와 같이 할 수 없다는 것이다.

둘 다 같은 타입의 인스턴스지만 참조변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다.


반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수 있을까?

정답은 불가능하다 이다.

실제 인스턴스인 Animal의 멤버 개수보다 참조변수 b가 사용할 수 있는 멤버 개수가 더 많기 때문이다.

  • 조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 없다!
  • 반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다
반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA] String 클래스  (0) 2023.08.10
[JAVA] 추상 클래스와 메서드  (0) 2023.08.10
[JAVA] 객체지향 언어  (0) 2023.08.09
[JAVA] switch 문  (0) 2023.08.09
[JAVA] 상속 (2)  (0) 2023.08.08
반응형
객체지향 언어의 특징을 알아보자

1. 코드의 재사용성이 높다.
새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있다.
2. 코드의 관리가 용이하다.
코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경할 수 있다.
3. 신뢰성이 높은 프로그래밍을 가능하게 한다.
제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며,
코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다.
 클래스와 객체

클래스란 객체를 정의해놓은 것, 설계도 또는 틀 이라고 정의할 수 있다.

클래스는 객체를 생성하는데 사용되고, 객체는 클래스에 정의된 대로 생성된다.

 

객체란 실제로 존재하는 것을 의미한다.

예를 들어 휴대폰, 노트북, 책상, 의자 등등.... 같은 사물들이 객체라고 한다. 

사물과 같은 유형적인 것뿐만 아니라 개념이나 논리와 같은 무형의 것도 객체로 간주한다.

 

객체의 속성과 기능

객체는 속성과 기능의 두 종류의 구성요소로 이루어져 있으며, 일반적으로 객체는 다수의 속성과 기능을 갖는다.

객체는 속성과 기능의 집합이라 볼 수 있다.

클래스란 객체를 정의한 것이므로, 클래스에 정의된 속성과 기능을 가진 객체가 만들어지는 것이다.

이해하기 쉽게 예를 들어 휴대폰을 생각해보자.

휴대폰의 속성으로는 전원상태, 색상, 길이, 크기 등이 있으며, 기능으로는 전화걸기, 문자보내기, 볼륨 높이기 등이 있다.

 

객체지향 프로그래밍에서는 속성과 기능을 각각 변수, 메서드로 표현한다.

 

속성(property) ---> 멤버변수(variable)

기능(function) ---> 메서드(method)

 

한 파일에 여러 클래스 작성하기

하나의 소스파일에 하나의 클래스만을 정의하는 것이 보통, 하나의 소스파일에 둘 이상의 클래스를 정의하는 것도 가능하다. 이 때 주의해야 할 사항이 있는데, 소스파일의 이름은 public class의 이름과 일치해야한다는 것이다.

만일 소스파일 내에 public class가 없다면, 소스파일의 이름은 소스파일 내의 어떤 클래스 이름으로 해도 상관없다.

 

올바른 작성예시
Hello2.java
---------------------------------------
public class Hello2 { }
           class Hello3 { }
---------------------------------------
* public class가 있는 경우, 소스파일의 이름은 반드시 public class의 이름과 일치해야한다.
Hello2.java
---------------------------------------
class Hello2 { }
class Hello3 { }
---------------------------------------
* public class가 하나도 없는 경우, 소스파일의 이름은 Hello2.java / Hello3.java 둘 다 가능하다.
잘못된 작성 예시
Hello2.java
---------------------------------------
public class Hello2 { }
public class Hello3 { }
---------------------------------------
* 하나의 소스파일에 둘 이상의 public class가 존재하면 된다.
각 클래스를 별도의 소스파일에 나눠서 저장하거나 둘 중 한 클래스에 public을 붙이지 않아야 한다.
Hello3.java
---------------------------------------
public class Hello2 { }
           class Hello3 { }
---------------------------------------
* 소스파일의 이름이 public class와 일치하지 않는다. 소스파일의 이름을 Hello2.java로 변경해야한다.
hello2.java
---------------------------------------
public class Hello2 { }
           class Hello3 { }
---------------------------------------
* 소스파일의 이름과 public class의 이름이 일치하지 않는다.
대소문자를 구분하므로 대소문자까지 일치해야 한다.
반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA] 추상 클래스와 메서드  (0) 2023.08.10
[JAVA] 다형성  (0) 2023.08.10
[JAVA] switch 문  (0) 2023.08.09
[JAVA] 상속 (2)  (0) 2023.08.08
[JAVA] 상속  (0) 2023.08.08
반응형

배열을 어떻게 활용해야 할까?


활용예제 1) 총합과 평균 - 배열의 모든 요소를 더해서 총합과 평균을 구한다.

package ch01;

 

public class Ex5_2 {

 

public static void main(String[] args) {

int sum = 0; // 총합을 저장하기 위한 변수 선언과 초기화

float average = 0f; // 평균을 저장하기 위한 변수 선언과 초기화

 

int[] score = { 100, 88, 100, 100, 90 };

 

for (int i = 0; i < score.length; i++) { // 반복문을 이용해 배열에 저장되어있는 값들을 모두 더한다.

sum += score[i];

}

average = sum / (float) score.length; // 계산결과를 float타입으로 얻기위해 형변환

 

System.out.println("총합 : " + sum);

System.out.println("평균 : " + average);

 

} // end of main

 

} // end of class

 

[결과]

총합 : 478

평균 : 95.6

 

활용예제 2) 최대값과 최소값 - 배열의 요소 중에서 제일 큰 값과 제일 작은 값을 찾는다.

package ch01;

 

public class Ex5_3 {

 

public static void main(String[] args) {

int score[] = { 79, 88, 91, 33, 100, 55, 95 };

 

int max = score[0]; // 배열의 첫 번째 값으로 최대값을 초기화

int min = score[0]; // 배열의 첫 번째 값으로 최소값을 초기화

 

for (int i = 1; i < score.length; i++) { // 배열의 두번째 요소부터 읽기 위해 변수i 값을 1로 초기화

if (score[i] > max) {

max = score[i];

} else if (score[i] < min) {

min = score[i];

}

} // end of for

System.out.println("최대값 : " + max);

System.out.println("최소값 : " + min);

} // end of main

 

} // end of class

 

  • 배열의 첫 번째 요소 'score[0]'의 값으로 최대값을 의미하는 변수 max 최소값을 의미하는 변수 min을 초기화
  • 반복문을 통해 배열의 두 번째 요소 score[1]부터 max와 비교
  • 만일 배열에 담긴 값이 max에 저장된 값보다 크면 이 값을 max에 저장
  • 배열의 마지막까지 비교하고 나면 max에는 배열에 담긴 값 중 가장 큰 값이 저장

[결과]

최대값 : 100

최소값 : 33

 

활용예제 3) 섞기 - 배열의 요소의 순서를 반복해서 바꾼다. (숫자 섞기, 로또 번호 생성)

package ch01;

 

import java.util.Arrays;

 

public class Ex5_4 {

 

public static void main(String[] args) {

int[] numArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

System.out.println(Arrays.toString(numArr));

 

for(int i = 0; i < 100; i++) {

int n = (int)(Math.random() * 10); // 0~9 중의 한 값을 임의로 받는다.

int tmp = numArr[0];

numArr[0] = numArr[n];

numArr[n] = tmp; // numArr[0]과 numArr[n]의 값을 서로 바꾼다.

}

System.out.println(Arrays.toString(numArr));

 

} // end of main

 

} // end of class

 

  • 만약 random()을 통해 얻은 n값이 3이라면 아래와 같다.

 

package ch01;

 

public class Ex5_5 {

 

public static void main(String[] args) {

// 로또 번호 만들기

 

int[] ball = new int[45]; // 45개의 정수값을 저장하기 위한 배열 생성

 

// 배열의 각 요소에 1~45의 값을 저장

for(int i = 0; i < ball.length; i++) {

ball[i] = i + 1; // ball[0]에 1이 저장됨

}

 

int tmp = 0; // 두 값을 바꾸는데 사용할 임시변수지정

int j = 0; // 임의의 값을 얻어서 저장할 변수

 

// 배열의 i번째 요소와 임의의 요소에 저장된 값을 서로 바꿔서 값을 섞는다.

// 0번째 부터 5번째 요소까지 모두 6개만 바꾼다.

 

for(int i = 0; i < 6; i++) {

j = (int)(Math.random() * 45); // 0 ~ 44 범위의 임의의 값을 얻는다.

tmp = ball[i];

ball[i] = ball[j];

ball[j] = tmp; // ball[i] 와 ball[j]의 값을 서로 바꾼다.

}

 

// 배열 ball의 앞에서부터 6개의 요소를 출력

for(int i = 0; i < 6; i++) {

System.out.printf("ball[%d]=%d%n", i, ball[i]);

}

 

}

 

}

 

반응형
반응형

swith문에 대해 자세히 알아보자!


 

 

  • if 문의 경우 결과가 참, 거짓 두가지 밖에 없다.
  • 경우의 수가 많아 질 수록 else - if를 계속 추가해야해서 복잡하고, 처리시간도 길어진다.
switch 문
  • 단 하나의 조건식으로 많은 경우의 수를 처리
  • 표현도 간결해 알아보기가 쉽다.
  • 처리할 경우의 수가 많은 경우에는 if문 보다 switch문으로 작성하는 것이 좋다.
  • 단, switch문은 제약조건이 있기 때문에, 경우의 수가 많아도 어쩔 수 없이 if문으로 작성해야하는 경우가 있다.
  1. 조건식을 계산한다.
  2. 조건식의 결과와 일치하는 case문으로 이동한다.
  3. 이후의 문장들을 수행한다.
  4. break문이나 switch문의 끝을 만나면 switch문 전체를 빠져나간다.

  • 만약 조건식의 결과와 일치하는 case문이 하나도 없으면 default문으로 이동한다.
  • default문은 if 문의 else블럭과 같은 역할이라 생각하면 된다.
  • switch 문의 break 문은 각 case문의 영역을 구분하는 역할을 한다.
  • 만약 break문을 생략하게 된다면 case문 사이의 구분이 없어지는것과 같아, 다른 break 문을 만나거나 switch문 블럭{ } 끝을 만날때 까지 나오는 모든 문장들을 수행하게 된다.
  • 이러한 실수를 방지하기위해 break문을 빼먹지 않도록 주의해야한다.
switch 문의 제약조건

 

  • switch문의 조건식은 결과값이 반드시 정수이어야 한다.
  • 결과값과 일치하는 case문으로 이동하기 때문에 case문의 값 역시 정수이어야 한다.
  • case문의 값이 중복되지 않아야 한다. // 같은 값의 case문이 여러 개 이면 어디로 이동해야할지 모르기 때문!
  • case문의 값은 반드시 상수이어야 한다. // 변수나 실수는 case문의 값으로 사용할 수 없다!

public static void main(String[] args) {

int num, result;

final int ONE = 1;

 

 

switch (result) {

case '1' : // OK. 문자 리터럴(정수 49와 동일)

case ONE : // OK. 정수 상수

case "YES" : // OK. 문자열 리터럴. JDK 1.7부터 허용

case num : // 에러. 변수는 불가

case 1.0 : // 에러. 실수도 불가

 

}

switch문의 제약조건 예제
예제문은 [JAVA의 정석(기초편)_남궁성 지음] 책을 참고하였습니다.

package ch01;

 

import java.util.Scanner;

 

public class SwitchMainTest {

 

public static void main(String[] args) {

System.out.print("현재 월을 입력하세요.>");

 

Scanner sc = new Scanner(System.in);

 

int month = sc.nextInt(); // 화면을 통해 입력받은 숫자를 month에 지정

 

switch (month) {

case 3:

case 4:

case 5:

System.out.println("현재의 계절은 봄입니다.");

break;

case 6:

case 7:

case 8:

System.out.println("현재의 계절은 여름입니다.");

break;

case 9:

case 10:

case 11:

System.out.println("현재의 계절은 가을입니다.");

break;

default: // case 12: case 1: case 2:

System.out.println("현재의 계절은 겨울입니다.");

 

} // end of switch

 

} // end of main

 

} // end of class

 

* case문은 한 줄에 쓰던, 한 줄에 붙여서 쓰던 상관없음.

만약 예제의 switch 문을 if문으로 변경하면 다음과 같다.

if(month== 3 || month == 4 || month == 5) {

System.out.println("현재의 계절은 봄입니다.");

} else if (month== 6 || month == 7 || month == 8) {

System.out.println("현재의 계절은 여름입니다.");

} else if (month== 9 || month == 10 || month == 11) {

System.out.println("현재의 계절은 가을입니다.");

} else { // month == 12, 1, 2

System.out.println("현재의 계절은 겨울입니다.");

}

반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA] 다형성  (0) 2023.08.10
[JAVA] 객체지향 언어  (0) 2023.08.09
[JAVA] 상속 (2)  (0) 2023.08.08
[JAVA] 상속  (0) 2023.08.08
[JAVA] 배열  (0) 2023.08.04
반응형

위의 그래프를 참고하여 상속 구조로 클래스를 작성해보자

부모 클래스인 Hero 만들기

package ch03_1;

 

public class Hero {

 

String name;

int hp;

 

public Hero(String name, int hp) {

this.name = name;

this.hp = hp;

}

 

// 접근제어 지시자 - protected

// 상속을 받는 자식 클래스들은 접근할 수 있다.

 

protected void attack() {

System.out.println("기본 공격을 시작합니다.");

}

}

자식 클래스인 Warrior / Archer / Wizard 만들기

package ch03_1;

 

public class Warrior extends Hero {

 

// !! 부모 클래스에 사용자 정의 생성자가 있다면

// 자식 클래스에서 반드시 부모 생성자를 먼저 호출해야 한다.

public Warrior(String name, int hp) {

// super < -- 부모를 의미한다.

// System.out.println("asdasdasd"); << 부모가 태어나기 전에 먼저 일할 수 없다.

super(name, hp); // 부모 생성자를 먼저 호출해야한다.

}

 

public void comboAttack() {

System.out.println("전사가 2단 공격을 합니다.");

}

 

// 상속에서 오버라이드

@Override // 어노테이션

protected void attack() {

// super.attack(); // super.

System.out.println(super.name + "가 기본 공격을 합니다.");

// 부모(Hero)의 기능인 attack을 자식 클래스에서 재정의

}

}

package ch03_1;

 

public class Archer extends Hero {

 

public Archer (String name, int hp) {

super(name, hp);

}

 

// 메서드 오버라이드

@Override

protected void attack() {

// super.attack();

System.out.println(super.name + "가 기본 공격을 합니다.");

}

// 부모(Hero)의 기능인 attack을 자식 클래스에서 재정의

 

void fireArrow() {

System.out.println("불화살 공격을 합니다.");

}

}

package ch03_1;

 

public class Wizard extends Hero{

 

public Wizard (String name, int hp) {

super(name, hp);

}

 

// 메서드 오버라이드

@Override

protected void attack() {

// super.attack();

System.out.println(super.name + "가 기본공격을 합니다.");

}

// 부모(Hero)의 기능인 attack을 자식 클래스에서 재정의

 

 

void freezing() {

System.out.println("얼음공격을 합니다.");

}

}

기능 확인

public static void main(String[] args) {

Warrior war1 = new Warrior("전사", 100);

war1.attack();

war1.comboAttack();

 

Archer arc1 = new Archer("궁수", 80);

arc1.attack();

arc1.fireArrow();

 

Wizard wiz1 = new Wizard("마법사", 60);

wiz1.attack();

wiz1.freeZing();

}

실행결과

전사가 기본 공격을 합니다.

전사가 2단 공격을 합니다.

궁수가 기본 공격을 합니다.

불화살 공격을 합니다.

마법사가 기본공격을 합니다.

얼음공격을 합니다.

 

반응형
반응형
객체 지향 패러다임의 핵심

객체와 객체간의 상호작용 그리고 관계를 형성해 나가는 것

 

오버라이딩 : 상속에서는 부모메서드의 재정의가 가능하다.

조상클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 한다. 상속받은 메서드를 그대로 사용하기도 하지만, 자손 클래스 자신에 맞게 변경해야하는 경우도 존재한다. 이럴 때 조상의 메서드를 오버라이딩한다 라고 한다.

 

class Cal2 extends Cal {

 

public Cal2() {

System.out.println("Cal2() 생성자 호출 - 자식");

}

 

public int minus(int n1, int n2) {

return n1 - n2;

}

@Override // 어노테이션 이라 부른다.

public int mutiply(int n1, int n2) {

if(n1 == 0 || n2 == 0) {

System.out.println("0을 입력하였습니다.");

}

return n1 * n2;

} // 부모메서드를 재정의

위의 예시처럼 부모 클래스의 minus 메서드를 자식 클래스에서 재정의 한 것을 오버라이딩이라고 한다.

 

오버라이딩의 조건

오버라이딩은 메서드의 내용만을 새로 작성하는 것이므로 메서드의 선언부(메서드 이름, 매개변수, 반환타입)는 조상의 것과 완전히 일치해야한다.

다만, 접근 제어자와 예외는 제한된 조건 하에서만 다르게 변경할 수 있다.

 

오버로딩과 오버라이딩
  • 오버로딩 : 기존에 없는 새로운 메서드를 추가하는 것, new
  • 오버라이딩 : 조상으로 부터 상속받은 메서드의 내용을 변경하는 것, change, modify

package ch99;

 

public class Parent {

void parentMethod() {}

}

 

class Child extends Parent{

 

void parentMethod() { // 오버라이딩

// .....

}

void parentMenthod(int i) {} // 오버로딩

 

void childMethod() {}

void childMethod(int i) {} // 오버로딩

void childMethod() {} // 에러, 중복정의 됨

 

}

반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA] 객체지향 언어  (0) 2023.08.09
[JAVA] switch 문  (0) 2023.08.09
[JAVA] 상속  (0) 2023.08.08
[JAVA] 배열  (0) 2023.08.04
[JAVA] singleton 패턴  (0) 2023.08.03
반응형
객체 간의 상속은 어떤 의미일까?
상속?

기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다. 상속을 통해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이하다.

클래스 상속
  • 새로운 클래스를 정의할 때 이미 구현된 클래스를 상속(Inheritance)받아서 속성이나 기능을 확장하여 클래스를 구현함
  • 이미 구현된 클래스보다 더 구체적인 기능을 가진 클래스를 구현해야 할 때 기존 클래스를 상속함

  • 상속하는 클래스 : 상위 클래스, parent calss, super class
  • 상속받는 클래스 : 하위 클래스, child class, subclass
상속을 구현하는 경우
  • 상위 클래스는 하위 클래스 보다 더 일반적인 개념과 기능을 가짐
  • 하위 클래스는 상위 클래스 보다 더 구체적인 개념과 기능을 가짐
  • 하위 클래스가 상위 클래스의 속성과 기능을 확장(extends)한다는 의미

자바에서 상속을 구현하는 방법은 간단하다. 새로 작성하고자 하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 이름을 키워드 'extends'와 함께 써 주면 된다.

예를 들어 새로 작성하려는 클래스의 이름이 C이고 상속받고자 하는 기존 클래스의 이름이 A라면 다음과 같이 하면 된다.

class A {   }
class C extends A { 
         // .....
}

이 두 클래스는 서로 상속 관계에 있다고 하며, 상속해주는 클래스를 '조상 클래스'라 하고 상속 받는 클래스를 '자손 클래스'라고 한다.

예를 들어 Parent 클래스에 age라는 정수형 변수를 멤버변수로 추가하면, 자손 클래스는 조상의 멤버를 모두 상속 받기 때문에 Child 클래스는 자동으로 age라는 멤버변수가 추가된 것과 같은 효과를 얻는다.

반대로 자손인 Child클래스에 새로운 멤버로 play( ) 메서드를 추가하면

Child클래스에 새로운 코드가 추가되어도 조상인 Parent클래스에는 아무런 영향도 받지 않는다.

조상클래스가 변경되면 자손 클래스는 자동적으로 영향을 받게되지만, 자손 클래스가 변경되는것은 조상 클래스에 아무런 영향을 주지 못한다.

자손 클래스는 조상 클래스의 모든 멤버를 상속받으므로 항상 조상 클래스보다 같거나 많은 멤버를 갖는다.

  • 자손 클래스는 조상클래스의 모든 멤버를 상속 받는다. (단, 생성자와 초기화 블럭은 상속되지 않는다.)
  • 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
반응형

'Java > Java 이론' 카테고리의 다른 글

[JAVA] switch 문  (0) 2023.08.09
[JAVA] 상속 (2)  (0) 2023.08.08
[JAVA] 배열  (0) 2023.08.04
[JAVA] singleton 패턴  (0) 2023.08.03
[JAVA] static 변수  (0) 2023.08.03

+ Recent posts