자식타입 변수 = (자식타입) 부모타입 ;
양
(+)의 허용 범위가 short 타입보다 더 큼 (O)System.out.printf("이름: %1$s, 나이: %2$d", "김자바", 25);
package p07;
class Cat{
// 필드 입력
String name;
int age;
// 생성자 입력
public Cat(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Cat 생성자");
}
}//end Cat
class Test3{
// 메서드 입력
// call by value
public void a(int n) {
n = 100;
}
/* call by value reference
public void a(int[] arr, int index, int value) {
arr[index] = value;
}
*/
// call by value reference
public void b(Cat x) {
x.age = 20;
}
}
// 핸들링 클래스
public class TestMain {
public static void main(String[] args) {
// 필드 입력
int num = 10;
//기본형 처리
System.out.println("메서드 호출전, 원본 값 출력:" + num); // 10
// 메소드 호출 위한 객체 생성
Test3 t = new Test3();
t.a(num); // call by value ( 원본에 영향이 없다. )
System.out.println("메서드 호출후, 원본 값 출력:" + num); // 10
//####################################################################
// 메소드 호출 위한 객체 생성
// 참조형
Cat c = new Cat("야옹이", 2);
//참조형 처리
System.out.println("메서드 호출전, Cat의 age 값 출력:" + c.age); // 2
t.b(c); // call by value reference ( 파라미터에 참조형 변수(주소)를 전달)
System.out.println("메서드 호출후, Cat의 age 값 출력:" + c.age); // 20
}
}
package p02;
public class Cat {
String name;
int age;
String sex;
public Cat() {
this("야옹",2); //반드시 첫라인
System.out.println("Cat 기본생성자");
}
public Cat(String name, int age) {
// 오버로딩 생성자 호출 this( 인자리스트)
// Cat 클래스의 생성자 중에서 이름, 나이, 성별을 모두 인자로 받는 다른 생성자를 호출하는 코드
this(name, age, "암컷"); //반드시 첫라인
System.out.println("Cat (String name, int age) 생성자");
}
public Cat(String name, int age, String sex) {
//인스터스 변수 이름과 로컬 변수 이름이 동일한 경우 → this.변수명
this.name = name;
this.age = age;
this.sex = sex;
//System.out.println("String name, int age, String sex");
}
}
package exam02;
public class ArrayTest6 {
public static void main(String [] args) {
for (String s : args) {
System.out.println(s);
}
// 2차원 배열 출력 실습
int[][] arr;
arr = new int [][] {{1, 2}, {3, 4}, {5, 6}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
System.out.println();
int[][] arr2;
arr2 = new int [][] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for (int[] i2 : arr2) {
for (int j2 : i2 ) {
System.out.print(j2 + " ");
}
System.out.println();
}
}
}
package p05;
public class TestPet2 {
public static void main(String[] args) {
// 배열
Pet [] pets = {
new Cat("야옹1", "암컷", 2),
new Dog("망치1","암컷",4, "불독"),
new Cat("야옹2", "암컷", 2),
new Dog("망치2","암컷",1, "치와와"),
new Cat("야옹3", "암컷", 2)
};
for (Pet pet : pets) {
System.out.println(pet.getPet()); // 동적바인딩
}
System.out.println();
//고양이만 출력하시오? ==> (변수 instanceof 타입) 연산자
for (Pet pet : pets) {
if(pet instanceof Cat) {
System.out.println("Cat:" + pet.getPet());
}
}
System.out.println();
//고양이의 age 만 출력하시오 ? ==> instanceof + 형변환
for (Pet pet : pets) {
if(pet instanceof Cat) {
Cat c = (Cat)pet;
System.out.println("Cat 나이:" + c.getAge());
}
}
/////////////////////////////////////////////////////////////
System.out.println();
// 고양이만 출력 다른 표기
for (Pet pet : pets) {
if (pet instanceof Cat) { // x가 Cat 클래스의 인스턴스인지 확인
System.out.println("Cat:" +((Cat) pet ).getPet()); // Cat 타입으로 캐스팅하여 getPet() 사용
}
}
System.out.println();
// 고양이의 age 만 출력 다른 표기
for (Pet pet : pets) {
if (pet instanceof Cat) { // x가 Cat 클래스의 인스턴스인지 확인
System.out.println("Cat 나이:" +((Cat) pet ).age); // Cat 타입으로 캐스팅하여 age 필드 사용
}
}
}
}
Cat c = (Cat) pet;
형 변환 이유 public class ArrayTest09 {
public static void main(String[] args) {
int[] arr3 = new int[5];
int randNum = 0;
int sum = 0; // 총합계산을 위한 변수
// continue를 이용한 방법
top :
for(int i =0 ; i < 5; ) {
randNum = (int)(Math.random()*10 +1);
//같은 값이 들어있는지 비교하기 위한 for
for (int j = 0; j <= i; j++) {
//같은 값이 있으면 다시 난수 발생시킨다.
if(randNum == arr3[j]) {
continue top;
}
}
//같은 값 없으면 배열에 값 넣어줌
//넣어주고 다음 배열 위치로 넘어감
arr3[i] = randNum;
i++;
}
// 결과의 출력
for(int k : arr3) {
System.out.print(k + " ");
sum += k;
}
System.out.println();
System.out.println("sum = " + sum);
System.out.println("avg = " + ( (double)sum/ arr3.length ) );
}
}
//다음과 같이 제공된 배열에서 최대값과 최소값을 구하는 코드 작성.
// int [] score= {99,34,67,22,11,9};
import java.util.Random;
import java.util.Scanner;
public class ArrayTest07 {
public static void main(String[] args) {
Random ran = new Random();
Scanner scan = new Scanner(System.in);
System.out.println("키의 최댓값을 구합니다.");
System.out.print("사람 수 : ");
int num = scan.nextInt();
int[] height = new int[num];
for (int i = 0; i < num; i++) {
height[i] = 100 + ran.nextInt(90);
System.out.println("사람 " + (i+1)+": " + height[i]);
}
int max = height[0];
for (int i = 1; i < height.length; i++)
if (height[i] > max) {
max = height[i];
}
System.out.println("최댓값은 " + max + "입니다.");
}
}
public class ArrayTest05 {
public static void main(String[] args) {
int[][] arr = { { 20, 30, 10 }, { 50, 40, 60 }, { 80, 80, 90 } };
for (int i = arr.length - 1; i >= 0; i--) {
for (int j = arr[i].length - 1; j >= 0; j--) {
System.out.print(arr[i][j] + " ");
}
}
}
}
import java.util.Scanner;
Scanner scanner = new Scanner(System.in);
//추가 기능에 해당되는 메서드 지정
//검증 작업
// 은닉화(encapsulation)
private boolean ageCheck(int age) {
boolean result = false;
if(age > 0 && age < 20) {
result = true;
}
return result;
}
public void setAge(int age) {
//검증작업
if(ageCheck(age)) {
this.age = age;
}else {
System.out.println("입력 age 값 다시 확인 필요");
}
}
package p01;
class Outer{
public int n = 10;
protected int n2 = 20;
int n3 = 30;
private int n4 = 40;
static int n5 = 50;
public void a() {
Inner inner = new Inner(); // 로컬 클래스
inner.b();
}
// 인스턴스 멤버 클래스
// Member Inner Class
class Inner{
int x = 10;
//static int k = 10; // static 사용 불가
public void b() {
System.out.println(n);
System.out.println(n2);
System.out.println(n3);
System.out.println(n4); // private 접근 가능
System.out.println(n5);
System.out.println(x);
}
}//end Inner
}//end Outer
public class TestMain {
public static void main(String[] args) {
// Inner 사용 방법 1 - Outer생성하고 outer의 메서드 이용해서 Inner를 사용할 수 있다.
Outer outer = new Outer();
// 로컬 클래스 객체 생성을 위한 메소드 호출 (메소드 실행해야만 사용)
outer.a();
System.out.println();
// Inner 사용 방법 2 - 직접 호출
Outer outer2 = new Outer();
// 인스턴스 멤버 클래스 객체 생성 (Outer 객체 생성해야만 사용)
Outer.Inner inner = outer2.new Inner();
inner.b();
}
}
package p02;
class Outer{
public int n = 10;
protected int n2 = 20;
int n3 = 30;
private int n4 = 40;
static int n5 = 50;
public void a() {}
//Member Inner Class
static class Inner{
int x = 10;
static int k = 10; // static 사용 불가
public void b() {
// System.out.println(n);
// System.out.println(n2);
// System.out.println(n3);
// System.out.println(n4); // private 접근 가능
System.out.println(n5);
System.out.println(x);
}
}//end Inner
}//end Outer
public class TestMain {
public static void main(String[] args) {
// Outer 생성할 필요가 없음.
Outer.Inner inner = new Outer.Inner();
inner.b();
}
}
package p03;
interface Flyer{
public abstract void a();
}
//이름있는 클래스
class Bird implements Flyer{
@Override
public void a() {
System.out.println("Bird.a()");
}
}
public class TestMain {
public static void main(String[] args) {
//이름있는 클래스
Flyer f = new Bird();
f.a();
//익명 클래스 (이름없는 클래스, anonymous class)
Flyer f2 = new Flyer(){
@Override
public void a() {
System.out.println("Anonymous.a()");
}
};
f2.a();
Flyer f3 = new Flyer() {
@Override
public void a() {
System.out.println("Anonymous22.a()");
}
};
f3.a();
}
}
package p01;
@FunctionalInterface
interface Flyer{
public abstract void a();
}
@FunctionalInterface
interface Flyer2{
public abstract void b(int n, int n2);
}
@FunctionalInterface
interface Flyer3{
public abstract int c();
}
@FunctionalInterface
interface Flyer4{
public abstract int d(int n , int n2);
}
public class TestMain {
public static void main(String[] args) {
// 익명 클래스
Flyer f1 = new Flyer() {
@Override
public void a() {
System.out.println("Flyer.a()");
}
};
f1.a();
//람다 표현식(lambda expression ,arrow expression)
// 자바스크립트: => , 자바: ->
Flyer ff1 = ()->{
System.out.println("람다1 Flyer.a()");
};
ff1.a();
Flyer fff1 = ()->System.out.println("람다2 Flyer.a()");
fff1.a();
//////////////////////////////////////////////////////
Flyer2 f2 = new Flyer2() {
@Override
public void b(int n, int n2) {
System.out.println("Flyer2.b()"+n+"\t"+n2);
}
};
f2.b(10, 20);
System.out.println();
//람다표현식-1
Flyer2 ff2 = (int n, int n2)->{
System.out.println("람다표현식1 Flyer2.b()"+n+"\t"+n2);
};
ff2.b(10, 20);
//람다표현식-2
Flyer2 fff2 = (n,n2)->System.out.println("람다표현식2 Flyer2.b()"+n+"\t"+n2);
fff2.b(10, 20);
//###################################
// 익명 클래스
Flyer3 f3 = new Flyer3() {
@Override
public int c() {
return 100;
}
};
System.out.println(f3.c());
//람다표현식-1
Flyer3 ff3 = ()->{
return 100;
};
System.out.println(ff3.c());
//람다표현식-2 ( 익숙해져야 된다. )
Flyer3 fff3 = ()-> 100;
System.out.println(fff3.c());
System.out.println();
// #################################
Flyer4 f4 = new Flyer4() {
@Override
public int d(int n, int n2) {
return n+n2;
}
};
System.out.println(f4.d(100, 200));
//람다 표현식 1
Flyer4 ff4 = (int n, int n2)->{
return n+n2;
};
System.out.println(ff4.d(100, 200));
//람다 표현식 2 ( 매우 중요하다. 익숙해져야 된다. )
Flyer4 fff4 =(n,n2)-> n+n2;
System.out.println(fff4.d(100, 200));
}//end main
}
※ 상속의 특징
부모의 멤버( 변수 · 메서드 )를 자식이 선언없이 사용가능하다.
⇒ 하지만 부모의 생성자와 private로 선언된 객체에 대해서는 상속이 불가능하다.
부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메서드만 접근이 가능하다
비록 변수는 자식 객체를 참조하지만, 변수로 접근 가능한 멤버는 부모 클래스 멤버로만 한정된다
메소드가 자식 클래스에서 재정의되었다면 자식 클래스의 메소드가 대신 호출된다. (다형성과 관련된 성질)
작은 크기의 자료형이, 큰 크기의 자료형으로 형 변환되었듯, 하위 클래스가 상속하는 상위 클래스로 자동 형변환이 가능하고, 이럴 경우 핸들링 메서드에서는 상위 클래스의 메서드만 호출 가능하다
자식 타입이 부모 타입으로 자동 타입 변환하면, 부모에 선언된 필드와 메서드만 사용 가능하다는 제약 사항이 따른다.
추상 클래스, 인터페이스 비교
클래스는 필드, 생성자, 메소드를 구성 멤버로 가지는 데 비해 인터페이스는 상수 필드와 추상 메소드만을 구성멤버로 가진다.
인터페이스는 객체로 생성할 수 없기 때문에 (추상 클래스와 공통점) 생성자를 가질 수 없다.
인터페이스 타입으로 자동 타입 변환된 매개값을 메소드 내에서 다시 구현 클래스 타입으로 강제 타입 변환해야 한다면 반드시 매개 값이 어떤 객체인지 instanceof 연산자로 확인하고 안전하게 강제 타입 변환을 해야 한다.
객체(인스턴스)는 힙에 할당되고, 참조형 변수는 해당 객체(인스턴스)의 주소를 참조하기 때문에 스택에 할당된다.
인스턴스 변수: 힙 영역 (Heap) 할당