package com.test.memo;
import java.util.Scanner;
class Practice2 {
public static void main(String[] args) {
String user = null;
Scanner sc = new Scanner(System.in);
System.out.print("16진수 입력:");
user = sc.next().toUpperCase();
if (!validHex(user)) {
int decimal = Integer.parseInt(user, 16);
System.out.println(Integer.toBinaryString(decimal));
} else
System.out.println("16진수가 아닙니다.");
}
private static boolean validHex(String user) {
for (int i = 0; i < user.length(); i++) {
if (!((user.charAt(i) >= '0' && user.charAt(i) <= '9') || (user.charAt(i) >= 'A' && user.charAt(i) <= 'F')))
return true;
}
return false;
}
}
package com.test.memo;
class Practice {
public static void main(String[] args) {
SutdaCard card1 = new SutdaCard(3, false);
SutdaCard card2 = new SutdaCard();
System.out.println(card1.info());
System.out.println(card2.info());
}
}
class SutdaCard {
private int num;
private boolean isKwang;
SutdaCard(int num, boolean isKwang) {
this.num = num;
this.isKwang = isKwang;
}
SutdaCard() {
this(1, true);
}
public String info() {
return num + (isKwang ? "k" : " ");
}
}
package com.test.memo;
import java.util.Scanner;
public class Practice1 {
public static void main(String[] args) {
morseCode();
}
private static void morseCode() {
String[] morse = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
"-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." };
String user = null;
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("종료하고 싶으시면 finish 라고 입력하세요.");
System.out.print("문자열을 입력하세요: ");
user = sc.nextLine().toLowerCase();
for (int i = 0; i < user.length(); i++) {
char ch = user.charAt(i);
if (ch == ' ') {
System.out.print(" ");
} else if (user.contains("finish")) {
System.out.println("모스 부호 번역 프로그램을 종료합니다.");
break;
} else if (ch >= 'a' && ch <= 'z') {
int idx = ch - 'a';
System.out.print(morse[idx] + " ");
} else
System.out.println("올바른 입력이 아닙니다. 다시 입력해주세요.");
}
System.out.println();
if (user.contains("finish")) {
break;
}
}
}
}
package com.test.memo;//1번 문
class Practice {
public static void main(String[] args) {
System.out.println(calculation(args));
}
private static int calculation(String[] s) {
int num1 = Integer.parseInt(s[0]);
int num2 = Integer.parseInt(s[2]);
String operator = s[1];
switch (operator) {
case "+":
return num1 + num2;
case "-":
return num1 - num2;
case "x":
return num1 * num2;
case "/":
return num1 / num2;
default:
System.out.println("지원하지 않는 연산자입니다.");
}
}
}

package com.test.memo;//2번 문제
import java.awt.Component.BaselineResizeBehavior;
import java.util.Scanner;
class Practice2 {
public static void main(String[] args) {
int[][] score = { // 5행 3열
{ 100, 100, 100 },
{ 20, 20, 20 },
{ 30, 30, 30 },
{ 40, 40, 40 },
{ 50, 50, 50 }
};
result(score);
}
private static void result(int[][] score) {
int[][] resultScore = new int[score.length][score[0].length + 3];// 5행6열
int total1 = 0, total2 = 0, total3 = 0;
for (int i = 0; i < score.length; i++) {
for (int j = 0; j < score[i].length; j++) {
resultScore[i][0] = i + 1;// 학생 번호 저장
resultScore[i][j + 1] = score[i][j];// score배열 새로운 배열에 넣기
resultScore[i][score[0].length + 1] += score[i][j];// 가로 총점 구하는
resultScore[i][score.length] = resultScore[i][score[0].length + 1] / (score[i].length);
}
total1 += score[i][1];// 세로 총점 구하는
total2 += resultScore[i][2];
total3 += resultScore[i][3];
}
System.out.println("번호\t국어\t영어\t수학\t총점\t평균");
System.out.println("==========================================");
for (int i = 0; i < resultScore.length; i++) {
for (int j = 0; j < resultScore[i].length-1; j++) {
System.out.print(resultScore[i][j] + "\t");
}
System.out.printf("%.1f\n", resultScore[i][resultScore[i].length - 1]); // 평균 출력
System.out.println();
}
System.out.println("==========================================");
System.out.printf("총점:\t%d\t%d\t%d\n", total1, total2, total3);
System.out.println();
}
}

평균 double로 만들기 실패
문자열 자체가 int인데.. double로 바꾸자니 평균을 제외한 나머지는 다 int고..
double문자배열이면 Math.round를 이용해서 int로 가능하고 int가 문자배여리면 Math.ceil을 이용해서 double 로 출력 가능한데 평균값만 따로 빼지를 못하겠다...
위는 int형 배열이여서 밑에처럼 해줬지만 double이면 Math.round로 값 출려가고 평균은 안쪽 for문 나와서 출력후 개행해주면 된다.
System.out.printf("%.1f\n", resultScore[i][resultScore[i].length - 1]); // 평균 출력 이 코드를 이용해서 출력해줬다.
배열을 출력할 때도 printf로 %f로 출력하면 소수점으로 보여준다는것을 알았다.

class ArrayEx19 {
public static void main(String[] args) {
int[][] score = {
{ 100, 100, 100}
, { 20, 20, 20}
, { 30, 30, 30}
, { 40, 40, 40}
, { 50, 50, 50}
};
// 과목별 총점
int korTotal = 0;
int engTotal = 0;
int mathTotal = 0;
System.out.println("번호 국어 영어 수학 총점 평균 ");
System.out.println("=============================");
for(int i=0;i < score.length;i++) {
int sum = 0; // 개인별 총점
float avg = 0.0f; // 개인별 평균
korTotal += score[i][0];
engTotal += score[i][1];
mathTotal += score[i][2];
System.out.printf("%3d", i+1);
for(int j=0;j < score[i].length;j++) {
sum += score[i][j];
System.out.printf("%5d", score[i][j]);
}
avg = sum/(float)score[i].length; // 평균계산
System.out.printf("%5d %5.1f%n", sum, avg);
} //%5.1f는 총 5자리 공간이 있고 양수니까 우측정렬로 값을 삽입하고 소수점 이하 한자리만 보여준다.
System.out.println("=============================");
System.out.printf("총점:%3d %4d %4d%n", korTotal, engTotal, mathTotal);
}
}

import java.util.Scanner;//3번 문
class Practice {
public static void main(String[] args) {
String user = null;
final int SIZE = 10;
int x = 0, y = 0;
char[][] board = new char[SIZE][SIZE];
byte[][] shipBoard = {
// 1 2 3 4 5 6 7 8 9
{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1
{ 1, 1, 1, 1, 0, 0, 1, 0, 0 }, // 2
{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 3
{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 4
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 5
{ 1, 1, 0, 1, 0, 0, 0, 0, 0 }, // 6
{ 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // 7
{ 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // 8
{ 0, 0, 0, 0, 0, 1, 1, 1, 0 }, // 9
};
for (int i = 1; i < SIZE; i++) {
board[0][i] = board[i][0] = (char) (i + '0');
}
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("좌표를 입력하세요.(종료는 00): ");
user = sc.next();
if (user.length() == 2) {// 두 글자를 입력해야 비교하게끔
x = user.charAt(0) - '0';// 좌표 인덱스를 반환하는
y = user.charAt(1) - '0';
// if(x == 0 && y == 0) {
// System.out.println("종료합니다.");
// break;
// }이거랑 이 밑에 둘다 가능
if (user.contains("00")) {
System.out.println("종료합니다.");
break;
}
if (user.length() != 2 || x <= 0 || y <= 0 || x >= SIZE || y >= SIZE) {
System.out.println("잘못된 입력입니다. 다시 입력해주세요.");// 이거 왜 출력안되지..
continue;
}
board[x][y] = shipBoard[x - 1][y - 1] == 1 ? 'O' : 'X';
for (int i = 0; i < board.length; i++) {
System.out.println(board[i]);
}
System.out.println();
}
}
}
}
board[0][i]: 이는 배열의 첫 번째 행의 값을 설정합니다. 할당된 값은 (char)(i + '0')로, 정수 i를 해당하는 문자 표현으로 변환합니다.board[i][0]: 이는 배열의 첫 번째 열의 값을 설정합니다. 할당된 값 역시 (char)(i + '0')로 동일합니다.- 0,0 은 빈 공백으로 둔다.
char[][] 은 행 주소값만 줘도 그 행의 열들을 다 출력해주는데 int[][]은 출력이 되지 않는다.


import java.util.*;
class MultiArrEx2 {
public static void main(String[] args) {
final int SIZE = 5;
int x = 0 , y = 0;
int num = 0;
int[][] bingo = new int[SIZE][SIZE];
Scanner scanner = new Scanner(System.in);
// 배열의 모든 요소를 1부터 SIZE*SIZE까지의 숫자로 초기화
for(int i=0;i<SIZE;i++) {
for(int j=0;j<SIZE;j++) {
bingo[i][j] = i*SIZE + j + 1;//숫자가 겹치지 않고 차례로 채워지게 > 숫자가 1부터 시작해서 +1
}
}
// 배열에 저장된 값을 뒤섞는다.(shuffle)
for(int i=0;i<SIZE;i++) {
for(int j=0;j<SIZE;j++) {
x = (int)(Math.random() * SIZE);//0~4사이의 난수
y = (int)(Math.random() * SIZE);
// bingo[i][j]와 임의로 선택된 값(bingo[x][y])을 바꾼다.
int tmp = bingo[i][j];
bingo[i][j] = bingo[x][y];//만약 난수를 인덱스값보다 오바되게 한다면 오류난다(배열이 오버플로우같이 되서)
bingo[x][y] = tmp;
}
}
do {
for(int i=0;i<SIZE;i++) {//SIZE = 5
for(int j=0;j<SIZE;j++)
System.out.printf("%2d ", bingo[i][j]); //배열의 행하나를 출력하고 안쪽 for문 벗어나서 개
System.out.println();
}
System.out.println();
System.out.printf("1~%d의 숫자를 입력하세요.(종료:0)>", SIZE*SIZE);
String tmp = scanner.nextLine(); // 화면에서 입력받은 내용을 tmp에 저장
num = Integer.parseInt(tmp); // 입력받은 문자열(tmp)를 숫자로 (int)변환
// 입력받은 숫자와 같은 숫자가 저장된 요소를 찾아서 0을 저장
outer:
for(int i=0;i<SIZE;i++) {
for(int j=0;j<SIZE;j++) {
if(bingo[i][j]==num) {//사용자에게 입력받은 숫자가 배열에 존재한다면
bingo[i][j] = 0;//해당 인덱스의 값을 0 으로 바꿔준다.
break outer; // 2중 반복문을 벗어난다.
}
}
}
} while(num!=0); //0을 입력받으면 종료되게끔
} // main의 끝
}
숫자의 범위: 1부터 SIZE * SIZE까지의 숫자는 배열의 크기에 맞는 범위의 숫자를 의미합니다. 만약 SIZE가 5라면, 1부터 25까지의 숫자가 차례로 배열에 할당됩니다.
중복되지 않는 숫자: 숫자가 겹치지 않고 차례로 채워져야 하는데, i*SIZE + j + 1을 통해 각 요소에 순차적인 숫자가 할당됩니다. 여기서 i와 j는 배열의 인덱스이며, 숫자는 1부터 시작하므로 +1을 해줍니다
%05d 라고하면 5칸을 두고 우측정렬을 하는데 앞에 빈공간을 0으로 채워준다.문법적으로는 extends를 사용해 상속시킬 수 있지만, 논리적으로 상속관계: ~은 ~이다. is-a 관계가 아니면 상속시키지 않는다.
이미 만들어져 있는 클래스를 재사용할 수 있기 때문에 효율적이고, 중복된 코드가 줄어 코드가 간결해진다.
공통적인 기능을 부모 클래스에 추가해주면 상속받은 여러 개의 클래스에서 사용이 가능 > 확장성 + 유지보수 용이 + 재사용 가능
부모 클래스의 private 접근 제한을 갖는 필드 및 메소드는 자식이 물려받을 수 없다.
부모와 자식 클래스가 서로 다른 패키지에 있다면, 부모의 default접근 제한을 갖는 필드 및 메소드도 자식이 물려받을 수 x - public/protected 만 접근 가능
extends라는 키워드를 통해 상속
자식 클래스는 부모 클래스로부터 메소드와 필드를 물려받아 사용 / 부모 클래스는 자식 클래에서 정의한 메소드나 필드를 사용하지 x (자식 = 자신 + 부모 / 부모 = 자신)
자바는 다중 상속X > 단일 상속만 가능하다. > extends 키워드 뒤에 하나의 부모 클래스만 올 수 있다.
여러 자식 클래스에게 상속은 가능
class AAA{//상위 클래스 <> 부모 클래스
private int age = 10;
//public int getAge()
//return age;
}
class BBB extends AAA{//하위 클래스 <> 자식 클래스
public String name = "Hong";
public void whoAmI() {
System.out.println(age + " " + name);//XXXXXX 상속관계여도 private인 age를 가지고 있을 수 없다.
System.out.println(getAge() + " " + name); //이제 위 주석에 대입한다면 가능
}
}
상속관계여도 private인 변수까지 가지고 올 수는 없다.
class ParentCafe {
String coffee;
int price;
public void printMenu() {
System.out.println(coffee + "는 " + price + "원입니다.");
}
}
class ChildCafe extends ParentCafe {
// 생성자
// ChildCafe 가 ParentCafe 의 필드를 상속받아 사용할 수 있다.
ChildCafe(String coffee, int price) {
this.coffee = coffee;
this.price = price;
}
}
class Organize {
public static void main(String[] args) {
ChildCafe child = new ChildCafe("아메리카노", 4100);
child.printMenu();
}
}
출력값은 아메리카노는 4100원이다. 라고 출력된다.
만약 ParentCafe에서 printMenu()메소드가 private 접근제어자를 사용했다면 오류가 난다.
class AAA{
public void hi(){
syso("Hi");
}
class BBB extends AAA{
public void bye(){
syso("Bye");
}
class ABMain{
public static void main(String[] args){
AAA aaa = new BBB();
aaa.bye(); //오류 > 자바는 aaa가 AAA클래스에 bye라는 메서드가 없는데 호출한다고 인식해서 오류를 낸다. 실질적으로는 상속받아서 존재하는데
((BBB)aaa).bye(); //그래서 aaa를 BBB로 형변환을 시켜서 호출해줘야한다.
}
}
super 키워드는 자식 클래스에서 부모 클래스의 생성자를 호출할 때 사용하는 키워드이다.(바로 위 뿐 아니라 부모의 부보, 부모의 부모의 부모의 생성자까지 모두 호출)
this()연산자는 자기 자신의 생성자를 호출한다.자식 클래스의 생성자 선언 내부에 맨 첫줄에 super(매개값, 매개값, ...)과 같이 선언해야한다.
컴파일러는 기본 생성자만 담당해 주기 때문이다.
class AAA{//생성자를 따로 두지 않으면 java에서 자동으로 AAA(){}형태로 삽입된다.
AAA(int num){
System.out.println("AAA" + num);
}
}
class BBB extends AAA{//BBB(){super();} 생성자안에 super(); 로 자동 삽입
BBB(){
super(10);//매개변수가 있다면 따로 호출을 해줘야한다.(아니면 에러)
System.out.println("BBB");
//만약 지금 super(10);이 출력문보다 아래에 있다면 에러가 난다 무조건 제일 위에 있어야한다.
}
}
class ABMain{
public static void main(String[] args){
AAA a2 = new BBB();
}
}//AAA10이 출력되고BBB출
상위 클래스로부터 상속받은 메서드의 내용을 하위 클래스에서 재정의 하는것
오버로딩은 기존에 없는 새로운 메소드를 추가하는 것이지만, 오버라이딩은 상위클래스로부터 상속받은 메소드의 내용을 변경하는 것이다.
하위클래스에서 같은 이름의 메소드를 다시 만들면 상속받은 상위 클래스의 메소드는 무시된다.
부모에게서 물려받은 자원을 그대로 사용해도 되지만, 조금 변형시켜 사용하고자 할 때 자원을 override 하여 사용한다.
재정의할 부모의 메소드와 동일한 메소드명, 매개변수 타입과 개수, 리턴타입로 작성해야 한다.
접근제어자는 상클래스의 메소드와 같거나 넓은 범위로 변경 가능하다.(final, static, private 는 오버라이딩 X)
부모의 메소드가 public 이면, 자식이클래스에서는 public 또는 protected로 변경 가능
부모의 메소드가 protected라면 이를 오버라이딩하는 자손 클래스의 메소드는 접근 제어자가 protected 또는 public이어야 한다.( 대부분은 같은 범위의 접근 제어자를 사용한다. )
예외 처리도 동일해야한다.
package com.test.memo;
class Car // 기본 연료 자동차
{
int gasolineGauge;
public Car(int gasolineGuage) {
this.gasolineGauge = gasolineGuage;
}
}
class HybridCar extends Car // 하이브리드 자동차
{
int electricGauge;
public HybridCar(int gasolinGuage, int electricGuage) {
super(gasolinGuage);
this.electricGauge = electricGuage;
}
}
class HybridWaterCar extends HybridCar // 하이브리드 워터카
{
private int waterGauge;
public HybridWaterCar(int gasolinGuage, int electricGuage, int waterGuage) {
super(gasolinGuage, electricGuage);
this.waterGauge = waterGuage;
}
public void showCurrentGauge() {
System.out.println("잔여 가솔린 : " + gasolineGauge);
System.out.println("잔여 전기량 : " + electricGauge);
System.out.println("잔여 워터량 : " + waterGauge);
}
}
class Organize {
public static void main(String[] args) {
HybridWaterCar hybridWaterCar = new HybridWaterCar(50, 30, 20);
hybridWaterCar.showCurrentGauge();
}
}
package com.test.memo;
class Car // 기본 연료 자동차
{
private int gasolineGauge;
public Car(int gasolineGuage) {
this.gasolineGauge = gasolineGuage;
}
public int getGasolin() {
return gasolineGauge;
}
}
class HybridCar extends Car // 하이브리드 자동차
{
private int electricGauge;
public HybridCar(int gasolinGuage, int electricGuage) {
super(gasolinGuage);
this.electricGauge = electricGuage;
}
public int getElectric() {
return electricGauge;
}
}
class HybridWaterCar extends HybridCar // 하이브리드 워터카
{
private int waterGauge;
public HybridWaterCar(int gasolinGuage, int electricGuage, int waterGuage) {
super(gasolinGuage, electricGuage);
this.waterGauge = waterGuage;
}
public int getWater() {
return waterGauge;
}
public void showCurrentGauge() {
System.out.println("잔여 가솔린 : " + getGasolin();
System.out.println("잔여 전기량 : " + getElectric());
System.out.println("잔여 워터량 : " + getWater();
}
}
class Organize {
public static void main(String[] args) {
HybridWaterCar hybridWaterCar = new HybridWaterCar(50, 30, 20);
hybridWaterCar.showCurrentGauge();
}
}
class Car // 기본 연료 자동차
{
private int gasolineGauge;
Car(int gasolineGauge)
{
this.gasolineGauge = gasolineGauge;
}
public void showCurrentGauge()
{
System.out.println("잔여 가솔린 : " + gasolineGauge);
}
}
class HybridCar extends Car // 하이브리드 자동차
{
private int electricGauge;
HybridCar(int gasolineGauge, int electricGauge)
{
super(gasolineGauge);
this.electricGauge = electricGauge;
}
public void showCurrentGauge()
{
super.showCurrentGauge();
System.out.println("잔여 전기량 : " + electricGauge);
}
}
class HybridWaterCar extends HybridCar // 하이브리드 워터카
{
private int waterGauge;
HybridWaterCar(int gasolineGauge, int electricGauge, int waterGauge)
{
super(gasolineGauge, electricGauge);
this.waterGauge = waterGauge;
}
public void showCurrentGauge()
{
super.showCurrentGauge();
System.out.println("잔여 워터량 : " + waterGauge);
}
}
class CarMain2
{
public static void main(String[] args)
{
HybridWaterCar hwCar = new HybridWaterCar(100, 200, 300);
hwCar.showCurrentGauge();
}
}
class Adder
{
public static int val=0;//static인거 인지하기
public void add(int num)
{
val+=num;
}
}
class AdderFriend extends Adder
{
public void friendAdd(int num)
{
val+=num;
}
public void showVal()
{
System.out.println(val);
}
}
class StaticInheritance
{
public static void main(String[] args)
{
Adder ad=new Adder();
AdderFriend af=new AdderFriend();
ad.add(1);
af.friendAdd(3);
AdderFriend.val+=5;//하위클래스의 클래스 이름으로 상위클래스의 변수로 접급 가능하다는것을 보여
af.showVal();
}
}
class Speaker
{
private int volumeRate;
public void showCurrentState()
{
System.out.println("볼륨 크기: "+ volumeRate);
}
public void setVolume(int vol)
{
volumeRate=vol;
}
}
class BaseEnSpeaker extends Speaker
{
private int baseRate;
public void showCurrentState()
{
super.showCurrentState();
System.out.println("베이스 크기: "+baseRate);
}
public void setBaseRate(int base)
{
baseRate=base;
}
}
class Overriding
{
public static void main(String[] args)
{
Speaker sb = new BaseEnSpeaker();
sb.setBaseRate(20); //에러가 난다 > ((BaseEnSpeaker)sb).setBaseRate로 형변환 필요
BaseEnSpeaker bs=new BaseEnSpeaker();
bs.setVolume(10);
bs.setBaseRate(20);
bs.showCurrentState();
}
}
sb.setBaseRate 자바 컴파일러가 Speaker에는 setBaseRate 클래스에는 해당 메서드가 없다고 인식해서 에러가 난다. 실질적으로는 존재하므로 형변환 시켜야한다. > 그러나 좋은 코딩법은 아님 class AAA
{
public void rideMethod(){System.out.println("AAA's Method");}
public void loadMethod(){System.out.println("void Method");}
}
class BBB extends AAA
{
public void rideMethod(){System.out.println("BBB's Method");}
public void loadMethod(int num){System.out.println("int Method");}
}
class CCC extends BBB
{
public void rideMethod(){System.out.println("CCC's Method");}
public void loadMethod(double num){System.out.println("double Method");}
}
class RideAndLoad
{
public static void main(String[] args)
{
AAA ref1=new CCC();
BBB ref2=new CCC();
CCC ref3=new CCC();
ref1.rideMethod();//3개 다 CCC's Method 출력된다. > 오버라이딩
ref2.rideMethod();
ref3.rideMethod();
ref3.loadMethod();//오버로딩으로 매개변수의 자료형에 따라 각각 출력된
ref3.loadMethod(1);
ref3.loadMethod(1.2);
ref1.loadMethod();//voidMethod 출력 > 메소드 오버라이딩
ref1.loadMethod(1);//컴파일 에러
ref1.loadMethod(1.2);//컴파일 에러 > 형변환을 이용해 출력
}
}
메소드 오버라이딩은 최종적으로 메소드 오버라이딩된 애가 호출이 되서 위처럼 출력결과가 나온다.
ref1, ref2, ref3는 다형성을 이용하고 있습니다.
ref1은 AAA 자료형이지만 실제로는 CCC 객체를 참조하고 있습니다. 이렇게 부모 클래스의 참조 변수가 자식 클래스의 객체를 참조할 수 있는 것이 다형성입니다. 따라서 런타임 시에 실제 객체의 메소드가 호출됩니다.
ref2도 비슷한데, 부모 클래스의 참조 변수가 자식 클래스의 객체를 참조하고 있기 때문에 실제 객체의 메소드가 호출됩니다.
ref3는 자신이 참조하는 객체가 CCC이므로 CCC의 메소드가 호출됩니다.
코드를 더 명시적으로 작성하고 싶다면 ref1, ref2, ref3의 자료형을 CCC로 통일해도 됩니다. 그러면 각각의 참조 변수가 실제로 CCC 객체를 가리키고 있기 때문에 런타임 시에 실제 객체의 메소드가 호출됩니다.
class AAA
{
public int num=2;
}
class BBB extends AAA
{
public int num=5;
}
class CCC extends BBB
{
public int num=7;
}
class ValReDecle
{
public static void main(String[] args)
{
CCC ref1=new CCC();
BBB ref2=ref1;
AAA ref3=ref2;
System.out.println("CCC's ref: "+ref1.num);
System.out.println("BBB's ref: "+ref2.num);
System.out.println("AAA's ref: "+ref3.num);
}
}
자바에서는 참조 변수의 타입에 따라 참조할 수 있는 멤버 변수가 결정된다.
CCC ref1은 CCC 타입이므로 num이라는 멤버 변수는 CCC 클래스에서 정의된 것을 참조하고,
BBB ref2는 ref1을 참조하고 있지만, 여전히 BBB 타입이기 때문에 num 멤버 변수는 BBB 클래스에서 정의된 것을 참조하게 된다.
AAA ref3도 마찬가지로 num 멤버 변수는 AAA 클래스에서 정의된 것을 참조한다.
instanceof()연산자는 자바에서 객체의 타입을 확인하기 위한 연산자
- 객체가 특정 클래스 또는 인터페이스의 인스턴스인지를 확인 > 비교 연산자x > 주로 조건문에서 사용되어 객체의 타입을 확인하는데 활용
class Box
{
public void simpleWrap(){System.out.println("simple wrap");}
}
class PaperBox extends Box
{
public void paperWrap() {System.out.println("paper wrap");}
}
class GoldPaperBox extends PaperBox
{
public void goldWrap() {System.out.println("gold wrap");}
}
class InstanceOf
{
public static void wrapBox(Box box)//Box형 객체가 들어온것
{
if(box instanceof GoldPaperBox)//만약 형변환이 가능하면 true; 아니면 false;
((GoldPaperBox)box).goldWrap();
else if(box instanceof PaperBox)
((PaperBox)box).paperWrap();
else
box.simpleWrap();
}
public static void main(String[] args)
{
Box box1=new Box();
PaperBox box2=new PaperBox();
GoldPaperBox box3=new GoldPaperBox();
wrapBox(box1);//객체를 생성해 매개 변수로 넣어줬다.
wrapBox(box2);
wrapBox(box3);
}
}
class Box {
public void Wrap() {
System.out.println("simple wrap");
}
}
class PaperBox extends Box {
public void Wrap() {
System.out.println("paper wrap");
}
}
class GoldPaperBox extends PaperBox {
public void Wrap() {
System.out.println("gold wrap");
}
}
public class Practice1 {
public static void wrapBox(Box box) {
box.Wrap();
}
public static void main(String[] args) {
Box box1 = new Box();
PaperBox box2 = new PaperBox();
GoldPaperBox box3 = new GoldPaperBox();
wrapBox(box1);
wrapBox(box2);
wrapBox(box3);
}
}
객체를 생성할 때 각 객체의 타입은 다르지만, 이들이 서로 상속 관계에 있을 경우, 메소드 호출 시 동적 디스패치가 발생한다.
box1,2,3 객체가 들어오면 각 객체가 무슨 클래스의 참조변수인지 나와있으니까 오버라이딩인 메서드이름들을 Wrap으로 변경시키고,
wrapBox메서드에서 box.Wrap(); 으로 코딩시켜주면 해당 클래스를 찾아 호출해 출력할것이다.
오버라이딩은 참조하는 클래스를 이용해서 연결시킬 수 있구나잉..
부모가 없는 클래스는 자동적으로 object클래스를 상속 받게된다.
모든 클래스는 object클래스에 정의된 11개의 메소드를 상속 받는다.
toString(), equals(Object obj), hashCode(), ...
- 객체가 기본적으로 갖춰야 할 변수와 메서드를 제공한다.
- 주요 메서드
- toString() : 클래스이름과 인스턴스 ID를 리턴한다.
=> 프로그램을 실행할 때 인스턴스의 내부 값을 간단히
살펴볼 수 있도록 서브 클래스들이 이 메서드를 재정의
하기도 한다.
- equals() : 인스턴스의 주소를 비교하여 true/false 값을 리턴한다.
=> 인스턴스 내부의 값을 비교하도록 서브 클래스에서 이
메서드를 재정의하기도 한다.
- hashCode() : 인스턴스를 구별할 때 사용하는 4 byte 숫자로 된 ID 값.
=> 인스턴스 변수의 값이 같을 때 같은 ID 값을 리턴
하도록 서브 클래스에서 이 메서드를 재정의하기도 한다.
- getClass() : 클래스 설계도를 리턴한다.
- finalize() : 쓰레기 수집기(garbage collector)가 가비지를 메모리에서
제거하기 전에 호출하는 메서드이다.
=> 쓰레기 수집기가 언제 호출되는지 알 수 없기 때문에
자주 쓰이지는 않는다.
public String toString(){ return name + "/" + age;}
class Person {
private String name;
private int age;
Person(String name, int age){ // 메서드 오버로딩
this.name = name;
this.age = age;}
public String toString() {
return name +"/"+ age;}
}
class Employee extends Person{
private String workspace;
private String part;
Employee(String name, int age, String workspace, String part){ // 메서드 오버로딩
super(name, age);
this.workspace = workspace;
this.part = part;}
public String toString() { // 오버라이딩으로 toString 메서드 선언.
return super.toString() +"/"+ workspace +"/"+ part;}
}
class Teacher extends Employee{ // ★1
private String subject;
Teacher(String name, int age, String workspace, String part, String subject){
super(name, age, workspace, part); // ★2
this.subject = subject;}
public String toString() { // 오버라이딩으로 toString 메서드 선언.
return super.toString() +"/"+ subject; // ★3
}
}
public class Ex04_상속_상속 {
public static void main(String[] args) {
Person p = new Person("박세리", 50);
Employee e = new Employee("윤아", 30, "쌍용", "연구부");
Teacher t = new Teacher("릴리", 28, "신흥고", "1학년부", "지구과학");
System.out.println(p); // ★4
System.out.println(p.toString());
System.out.println(e);
System.out.println(t);
}
}
★1:
Employee를 상속받으면 Person에 들어있는 멤버변수/메서드까지 사용가능함.
★2:
이중상속일 때의 super 메서드는 바로 위 부모클래스로만 갈 수 있음.
★3:
super.toString은 한번만 입력했지만, 알아서 할아버지 클래스까지 타고 올라가서 작동함.
★4:
toString 메서드는 따로 p.toString()으로 호출하지 않고 p 로만 호출해도 사용가능.
오직 toString 메서드만 이런 방식으로 동작함.
public static void main(String[] args) {
// Student 클래스가 정말 Object의 서브 클래스인지 확인해보자
// 서브 클래스라면 수퍼클래스의 기능을 이용할 수 있어야 할 것이다.
Student1 s1 = new Student1();
s1.name = "홍길동";
s1.age = 20;
Student2 s2 = new Student2();
s2.name = "임꺽정";
s2.age = 30;
System.out.println(s1.toString()); // 오리지널 toString() 호출
System.out.println("------------------------");
System.out.println(s2.toString()); // 재정의한 toString() 호출
}
}
package com.test.memo;
import java.util.Arrays;
import java.util.Scanner;
class School{//자식에게 상속 해주는 부모클래스
public String school_name = "Bundang";
public String school_class = "Middle School";
private String[][] class_Student_name = {
{"홍석", "준혁"},//1반 학생
{"지수", "현지"},//2반 학생
{"민석", "석이"} //3반 학생
};
private String[] class_teacher_name = {
"전은호",//1반 담임
"오한결",//2반 담임
"박요한"//3반 담임
};
public void school() {
System.out.println(school_name + " " + school_class);
}
public String getBan(String name) {//사용자에게 이름을 입력받으면 반을 찾아준다.
for(int i = 0; i < class_Student_name.length; i++) {
for(int j = 0; j < class_Student_name[i].length; j++) {
if(class_Student_name[i][j].equals(name)) {
return (i+1)+ "";//배열 중 사용자가 입력한 이름과 같으면 몇반인지 반환 > 인덱스가 0부터니까 +1해줌
}
}
}
return null;
}
public String getTeacherName(String student_name) {//사용자에게 이름을 받으면 담당 선생님을 찾아준다.
for(int i = 0; i < class_Student_name.length; i++) {
for(int j = 0; j < class_Student_name[i].length; j++) {
if(class_Student_name[i][j].equals(student_name)) {
return class_teacher_name[i]; //i 인덱스가 몇반인지 알려주는 역할
}
}
}
return null;
}
public String[] getFriends(String student_name) {
for(int i = 0; i < class_Student_name.length; i++) {
for(int j = 0; j < class_Student_name[i].length; j++) {
if(class_Student_name[i][j].equals(student_name)) {
return class_Student_name[i];
}
}
}
return null;
}
}
class Teacher extends School{
public Teacher() {
System.out.println("반 확인 프로그램");
}
public String getBan(String name) {
return super.getBan(name)+ "반";//super 키워드를 통해 상위 클래스 메서드 호출
}
}
class Student extends Teacher{
private String name;
Student() {
super();
start();//메인 메서드에서 Student 클래스 호출하면 생성자를 통해 시작되게끔
}
private void start() {
Scanner sc = new Scanner(System.in);
System.out.print("당신의 이름을 입력하세요: ");
name = sc.next();
if(super.getBan(name) == null) {//여기도 마찬가지로 super 키워드를 통해 상위 클래스 메서드 호출
System.out.println("당신은 우리 학교 학생이 아닙니다.");
}
System.out.println("당신의 담임: " + super.getTeacherName(name));
System.out.println("당신의 반: " + super.getBan(name));
String[] friends = super.getFriends(name);
System.out.print("반 친구들 : ");
System.out.println(Arrays.toString(friends));
sc.close();
}
}
public class Practice1 {
public static void main(String[] args) {
Student st = new Student();
}
}
( 계좌 생성, 입출력 프로그램 만들기)
import java.util.Scanner;
class Member{
private String name; // 계좌주 이름
private int age; // 계좌주 나이
Member(){}
Member(String name, int age){
this.name = name;
this.age = age;}
public String getName() {
return name;}
public int getAge() {
return age;}
}
class Account_01 extends Member{
private String accountN; // 계좌번호
private int balance; // 잔고
Account_01(){}
Account_01(String name, int age, String accountN, int balance){
super(name, age);
this.accountN = accountN;
this.balance = balance;}
public void setBalance(int balance) {
this.balance = balance;}
public String getAccountN() {
return accountN;}
public int getBalance() {
return balance;}
public String toString() {
return getAccountN() +"\t"+ super.getName() +"\t"+ super.getAge() +"\t"+ getBalance();}
}
public class Ex11_ {
static Scanner sc = new Scanner(System.in);
static Account_01[] account = new Account_01[100];
static int menu, i, money, age, balance, member=0;
static String enteredAN, accountN, name;
static boolean run = true;
public static void main(String[] args) { // main 메서드 시작
while(true) {
if(run == false) {
break;}
System.out.println("===========================================");
System.out.println("1.계좌생성 | 2.계좌목록 | 3.예금 | 4.출금 | 5.종료");
System.out.println("===========================================");
System.out.print("선택> ");
menu = sc.nextInt();
System.out.println();
switch(menu) {
case 1:
menu01();
break;
case 2:
if(account[0] == null) {
System.out.println("계좌생성부터 진행해주십시오."); break;}
menu02();
break;
case 3:
if(account[0] == null) {
System.out.println("계좌생성부터 진행해주십시오."); break;}
menu03();
break;
case 4:
if(account[0] == null) {
System.out.println("계좌생성부터 진행해주십시오."); break;}
menu04();
break;
case 5:
System.out.println("** 시스템을 종료합니다. **");
run = false;
break;
default :
System.out.println("1~5 사이의 숫자만 입력 가능합니다.");
System.out.println();
break;
}
}
} // main의 끝
static public void menu01() { // 계좌생성
System.out.print("계좌번호: ");
accountN = sc.next();
System.out.print("계좌주: ");
name = sc.next();
System.out.print("나이: ");
age = sc.nextInt();
System.out.print("초기입금액: ");
balance = sc.nextInt();
account[member] = new Account_01(name, age, accountN, balance);
member++;
System.out.println("결과: 계좌가 생성되었습니다.");
System.out.println();
}
static public void menu02() { // 계좌목록
System.out.println("------");
System.out.println("계좌목록");
System.out.println("------");
System.out.println("계좌번호\t계좌주\t나이\t잔액");
for(i=0; i<account.length; i++) {
if(account[i] == null) {
break;
} else {
System.out.println(account[i]);
}
}
System.out.println();
}
static public void menu03() { // 입금하기
System.out.print("계좌번호: ");
enteredAN = sc.next();
System.out.print("입금액: ");
money = sc.nextInt();
if(money<0) {
System.out.println("금액을 잘못 입력하셨습니다.");
} else {
for(i=0; i<account.length; i++) {
if(account[i] == null) {
System.out.println("존재하지 않는 계좌입니다.");
break;
} else if (account[i].getAccountN().equals(enteredAN)) {
account[i].setBalance(account[i].getBalance()+money);
break;
}
}
System.out.println();
}
}
static public void menu04() { // 출금
System.out.print("계좌번호: ");
enteredAN = sc.next();
System.out.print("출금액: ");
money = sc.nextInt();
if(money<0) {
System.out.println("금액을 잘못 입력하셨습니다.");
} else {
for(i=0; i<account.length; i++) {
if(account[i] == null) {
System.out.println("존재하지 않는 계좌입니다.");
break;
} else if(account[i].getAccountN().equals(enteredAN)) {
if(money>account[i].getBalance()) {
System.out.println("예금액 이상은 출금할 수 없습니다.");
break;
} else {
account[i].setBalance(account[i].getBalance()-money);
break;
}
}
}
System.out.println();
}
}
}
