=> 클래스 전역으로 공유해서 사용해야 하는 변수나 상수에 적합함.
클래스, 인스턴스 변수는 초기화를 하지 않아도 변수 타입에 맞게 자동으로 초기화됨.
지역변수는 초기화 하지 않으면 컴파일러가 오류를 발생시킴.
class Car {
static int modelOutput; // 클래스 변수
String modelName; // 인스턴스 변수
void method() {
int something = 10; // 지역 변수
}
}\
클래스메소드(static method)와 인스턴스 메소드(instance method)로 구분됨.
클래스 메소드는 인스턴스를 생성하지 않고도 바로 사용할 수 있음. => 클래스 메소드는 내부에서 인스턴스 변수를 사용 할 수 없음.
메소드 내부에서 인스턴스 변수나 메소드를 사용하지 않을 때 클래스 메소드로 정의하는 것이 일반적임. => 매개변수만으로 동작하는 메소드를 정의할 때
예를들어, 반복되는 코드를 추상화하는 과정이라던지, 공통적으로 사용하는 로직을 묶는 역할을 함
인스턴스 메소드는 인스턴스 변수에 접근해야할 때 사용함.
class Car {
boolean door; // 인스턴스 변수
void openDoor() { // 인스턴스 메소드
door = true;
}
static void toggleDoor(boolean d) { // 클래스 메소드
return !d;
}
}
초기화 방법 3가지 => 명시적 초기화, 생성자를 이용한 초기화, 초기화 블록을 이용한 초기화
초기화 블록 => 증괄호 블록임(생성자보다 먼저 호출됨, 복잡한 초기화를 해야할 때 유용하게 사용함.)
초기화 순서
클래스 변수 : 기본값 → 명시적 초기화 → 클래스 초기화 블록
인스턴스 변수 : 기본값 → 명시적 초기화 → 인스턴스 초기화 블록 → 생성자
class Field {
static int classVar = 10; // 클래스 변수의 명시적 초기화
int instanceVar = 20; // 인스턴스 변수의 명시적 초기화
{ // 인스턴스 초기화 블록 => 인스턴스 변수 초기화
this.currentSpeed = 0;
}
static { // 클래스 초기화 블록을 이용한 초기화=> 클래스 변수 초기화
classVar = 10;
}
}
부모클래스의 접근제어자가 private이나 default일때 => 자식클래스에서 상속받지만 접근 불가능함.
단일상속만 가능, 모든 클래스는 Object 클래스를 상속받음.
super => 부모로부터 상속받은 필드나 메소드를 자식클래스에서 참조하는데 사용하는 참조변수임.
super 키워드를 통해 => 부모클래스의 멤버에 접근가능, 인스턴스 메소드에서만 사용가능함. 클래스 메소드에서는 사용 불가능.
class Parent {
int a = 10;
}
class Child extends Parent {
int a = 20;
void display() {
System.out.println(a);
System.out.println(this.a);
System.out.println(super.a);
}
}
public class Inheritance03 {
public static void main(String[] args) {
Child ch = new Child();
ch.display();
}
}
class Parent {
int a;
Parent() { a = 10; }
Parent(int n) { a = n; }
}
class Child extends Parent {
int b;
Child() {
① //super(40); // 호출시 a === 40
b = 20;
}
void display() {
System.out.println(a);
System.out.println(b);
}
}
public class Inheritance04 {
public static void main(String[] args) {
Child ch = new Child();
ch.display();
}
}
오버로딩(overloading)은 새로운 메소드를 정의하는 것입니다. => 서로 다른 시그니처를 갖는 여러 메소드를 하나의 이름으로 정의하는 것이었습니다.(이름은 동일하지만, 파라미터 return type이 다름)
하지만 오버라이딩(overriding)은 상속받은 기존의 메소드를 재정의하는 것입니다.
(메소드 덮어쓰기)
class Parent {
void display() { System.out.println("부모 클래스의 display() 메소드입니다.");
}
}
class Child extends Parent {
// 오버라이딩된 display() 메소드
void display() { System.out.println("자식 클래스의 display() 메소드입니다."); }
void display(String str) { System.out.println(str); } // 오버로딩된 display() 메소드
}
public class Inheritance06 {
public static void main(String[] args) {
Child ch = new Child();
ch.display();
ch.display("오버로딩된 display() 메소드입니다.");
}
}```
하나의 객체가 여러가지 타입을 가질 수 있다. => 타입변환 가능
부모클래스 타입의 참조변수가 자식 클래스 타입의 인스턴스를 참조 할 수 있다.
class Parent { ... }
class Child extends Parent { ... }
Parent pa = new Parent(); // 허용
Child ch = new Child(); // 허용
Parent pc = new Child(); // 허용
Child cp = new Parent(); // 오류 발생.
자바에서는 참조 변수도 다음과 같은 조건에 따라 타입 변환을 할 수 있습니다.
서로 상속 관계에 있는 클래스 사이에만 타입 변환을 할 수 있습니다.
자식 클래스 타입에서 부모 클래스 타입으로의 타입 변환은 생략할 수 있습니다.
하지만 부모 클래스 타입에서 자식 클래스 타입으로의 타입 변환은 반드시 명시해야 합니다.
abstract method => 자식메소드에서 반드시 오버라이딩 해야 사용가능. => 사용목적 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함입니다.
예를 들면 모듈처럼 중복되는 부분이나 공통적인 부분은 미리 다 만들어진 것을 사용하고, 이를 받아 사용하는 쪽에서는 자신에게 필요한 부분만을 재정의하여 사용함으로써 생산성이 향상되고 배포 등이 쉬워지기 때문입니다
구현부에서 상황에 맞게 모듈화 작성가능함.
추상클래스 => 하나이상의 추상 메소드를 포함하는 클래스임. => 반드시 사용되어야 하는 메소드들을 추상메소드로 선언해놓으면 추상메소드를 상속받는 클래스에서는 반드시 이를 재정의해야함.
추상메소드를 재정의하지 않으면 인스턴스 생성 불가능함.
다중상속을 지원하지 않는 Java에서 다중 상속을 지원하기 위해 존재함.
여러 인터페이스를 구현해서 사용가능함, 추상메소드와 상수만을 포함함.
모든 필드는 public static final, 모든 메소드는 public abstract여야함.
접근제어자 interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
...
public abstract 메소드이름(매개변수목록);
...
}
interface Animal { public abstract void cry(); }
interface Pet { public abstract void play(); }
class Cat implements Animal, Pet {
public void cry() {
System.out.println("냐옹냐옹!");
}
public void play() {
System.out.println("쥐 잡기 놀이하자~!");
}
}
class Dog implements Animal, Pet {
public void cry() {
System.out.println("멍멍!");
}
public void play() {
System.out.println("산책가자~!");
}
}
public class Polymorphism04 {
public static void main(String[] args) {
Cat c = new Cat();
Dog d = new Dog();
c.cry();
c.play();
d.cry();
d.play();
}
}
interface Animal { public abstract void cry(); }
interface Cat extends Animal { public abstract void cry(); }
interface Dog extends Animal { public abstract void cry(); }
class MyPet implements Cat, Dog {
public void cry() {
System.out.println("멍멍! 냐옹냐옹!");
}
}
public class Polymorphism05 {
public static void main(String[] args) {
MyPet p = new MyPet();
p.cry();
}
}
ref) TCP SCHOOL JAVA 37~46강 : http://www.tcpschool.com/java/java_inheritance_overriding
정보 감사합니다.