하드웨어 메모리에 접근 성능향상
C언어에서, int n =10;일 때
int p=n; 이면 p라는 변수에 n의 값(10)이 들어가는데
int p = &n; 이면 n이 가진 주소를 p포인터가 가리킨다.
print(n); // 10
print(p); // #100
print(p); // 10
배열의 경우, 배열의 이름은 주소로 &없이 이름만 사용한다.
int arr[3] = {1,2,3};
int p = arr;
print(arr[0]); // 1
print((p+0)); // 1
print(*(p+1)); // 2
int p → p가 가리키는 곳에 가면 int형 자료가 있을 것이다.
int:4byte(32bits), ascii: 7bit, char:java는 2byte c는 1byte
p가 int크기(4byte)만큼 스캔
→ 아래처럼 선언이 가능하지만 4번(1byte씩)을 스캔해야함.
int arr[3] = {1,2,3};
char *p = arr;
int k = *p; 포인터가 읽은 값 저장

int k = 0x12345678; 에서 좌측 숫자가 제일 큰 숫자, 메모리에는 작은 수부터 저장된다. → 리틀엔디안
저장할 때 상위 바이트. 큰 쪽을 먼저 저장
저장할 때 하위 바이트. 작은 쪽을 먼저 저장
ex) 컴퓨터에 int 형 4byte 데이터 0x01020304를 저장한다고 했을 때,
빅 엔디안은 첫 번째 주소에 가장 큰 값인 0x01을 먼저 저장
리틀 엔디안은 첫 번째 주소에 가장 작은 값인 0x04를 저장
부모에게서 자식이 상속받은 후, 특성에 따라 매개변수/함수가 추가된다.
→ 부모 < 자식 → 스캔할 자료형에 대한 고민필요

Class A
package ex0331;
public class A {
int n;
public A() {
System.out.println("A생성자 실행");
}
void fa() {
System.out.println("fa함수 실행");
}
}
Class B
package ex0331;
public class B extends A{
int k;
public B() {
System.out.println("B생성자 실행");
}
void fb() {
System.out.println("fb함수 실행");
}
}

B생성자를 만들기 위해 A생성자를 먼저 만든다.
b에서는 A클래스에 있는 n과 fa()를 사용할 수 있다.
A클래스에 static int sa;를 해주고,
a.sa=2; b.sa=1;로 해주니 결과값으로는 1이 나온다.
static으로 선언되면 B클래스에서도 A클래스의 static을 조작할 수 있다.


A 타입의 참조변수를 B생성자로 생성할 경우
A a = new A();
// 왼쪽의 선언부와 생성부가 타입이 일치
A ab = new B();
// 에러 안남 B extends A
B ba = new A();
// 에러남
ab는 결국 A클래스 자료형으로 생성된다.
그래서 A클래스의 필드의 내용만 쓸 수 있다.

B 타입의 참조변수를 활용하면, 사용가능하다.
B bb = (B)ab;
ab를 (B)로 형변환해줘야 함.

다른 예제
Student s1 = new Student();
Worker w1 = new Worker();
Person p1 = new Student();
p1.gender='M';
p1.name="John";
Student s2 = (Student)p1;
s2.num=2;
→ 서로 다른 타입을 배열로 저장할 수 있다.
Person 배열[n] 객체만으로는 Student 필드(num)에 접근할 수 없다.

그래서 또다른 형변환이 필요함

부모와 자식 클래스에 시그니처가 동일한 메소드가 있을 경우 자식 메소드로 실행
→부모의 것을 오버라이드함.

[예제]
고양이, 호랑이, 강아지 클래스를 만드시오.
각 클래스 별로 cry()함수를 만드시오.
동물이라는 클래스와 상속관계로 처리하고, cry()함수를 동물에 "동물이 웁니다."를 출력하게 작성
main에서 각 동물 별 인스턴스를 만들고, cry() 실행
동물별 울음 소리를 낼 수 있게 오버라이딩
반복문을 사용해서 동물들의 울음소리를 출력하시오.
→ 자식(cat,tiger,dog)는 모두 타입이 다르지만,
부모인 Animal 타입의 배열을 생성해서,
자식(cat, tiger, dog) 타입의 인스턴스를 저장할 수 있다.
그리고 해당 배열 인덱스에 저장된 인스턴스의 함수도 호출할 수 있다.
재정의한 메서드에 오류를 방지하기 위해 @Override 표시를 해준다.
package ex0331;
public class AnimalTest {
public static void main(String[] args) {
Animal a1 = new Animal();
Cat c1 = new Cat();
Tiger t1 = new Tiger();
Dog d1 = new Dog();
Animal[] a = new Animal[4];
a[0] = a1;
a[1] = c1;
a[2] = t1;
a[3] = d1;
for(int i=0; i<a.length; i++)
a[i].cry();
}
}
Dog.java
package ex0331;
public class Dog extends Animal{
@Override
public void cry() {
System.out.println("멍멍");
}
}

Animal a2 = new Dog();
a2.cry(); // 부모참조변수를 사용했지만 자식클래스의 메소드를 호출
결과: 멍멍
부모클래스의 기본생성자가 없이 매개변수를 받아야하는 생성자만 있을 경우에는,(필수)
자식클래스의 기본생성자를 작성하면 에러가 난다.

super(매개변수); 를 사용하면 에러를 해결할 수 있으며
자식클래스 생성자 함수에서 가장 위에 있어야 한다.
왜냐하면 부모클래스가 생성된 후 자식클래스가 생성되기 때문!

B클래서 생성시 매개변수를 super에 부여하는 것도 가능하다.

A의 필수생성자가 없다면, B에서 n을 지정해주는 것도 가능하다.

[예제]
클래스 만들기: 사각형, 삼각형, 원
사각형(quad)의 면적 = 가로x세로
삼각형(triangle)의 면적 = 가로x세로/2
원(circle) = 2πr
실행클래스에서 반복문을 사용해서 세 클래스 인스턴스의 면적을 구하기
방법1(area 함수마다 override)

방법2(도형 이름도 입력받기)

처음부터 상속을 고려하지 않고, 작업하다가 공통사항이 발견되면 그 때 부모클래스를 만들어도 된다.
면적 구하는 메서드를 하나의 클래스로 만든다.
a instanceof b : a가 b로부터 나온 것인지?
figure f 가 Triangle로부터 나온 것이라면
Triangle로 f를 형변환 하여 h, v를 가지고 올 수 있음
void calcArea(Figure f) {
if(f instanceof Triangle) { // figure가 triangle로부터 나온 것이냐?
area = ((Triangle) f).h * ((Triangle)f).v;
System.out.println(f.name + " 면적: "+area);
}
else if(f instanceof Quadangle) {
area = ((Quadangle)f).h * ((Quadangle)f).v;
System.out.println(f.name + " 면적: "+area);
}
else {
area = 2*3.14*((Circle)f).r;
System.out.println(f.name + " 면적: "+area);
}
}
방법1: CalcArea의 생성자를 활용

방법2: CalcArea의 멤버함수(메소드)를 활용

방법3: CalcArea의 멤버함수(메소드)를 static으로 활용
