프로그래밍/- java
class ,객체,메소드,생성자,상속,super , 추상, interface
즐겁게 하하하
2022. 2. 3. 08:29
728x90
★ 가비지 컬렉터 :: 사용하지 않는 불필요한 메모리를 회수하는 청소부
★ class(설계도)
=> 객체를 생성하기 위해사용 ( 제품 만들려고 )
=> 인스턴스화 =>
인스턴스(삼성 TV) , 인스턴스(LG TV)
=> 객체가 가진 속성(변수)과 기능(메서드)를 사용하기 위해
★ 메서드 :: 기능( 크기, 높이 색상.. )
Class Tv { // TV인스턴스
boolean power; // 변수( 속성 )
void power(){ power = !power; } // 메서드
}
## ===================================================================
★ class 이름은 대소문자를 구분한다.
★ public class 는 없어도 된다.
★ 하나의 소스 파일에는 하나의 public class 만 가능
★ 소스 파일 이름 != public class 이름 => 에러
★ 소스 파일 이름과 같은 class 안에 Main이 있어야 실행이 된다.
class Hello2 { // 파일명 Hello2.java
public static void main(String[] args){ }
}


★ 인스턴스(객체) 참조
ⓐ TV t; //참조변수 선언
ⓐ t = new TV(); // 인스턴스 생성 :: 생성자TV
ⓑ TV t = new TV();
## ======================================
ⓐ TV[] arr = new TV[3]; // 객체 배열
arr[0] = new TV(); // 필수
arr[1] = new TV();
arr[2] = new TV();
ⓑ TV[] arr = { new TV() , new TV() , new TV() } //초기화
## ======================================
★ 배열 변수 선언( 복습 )
int[] aa = new int[] {1,2,3,4,5};
int[] bb = {1,2,3,4};
int[] cc = new int[3];
## ======================================
★ 변수 => 배열(같은 타입) => 클래스
class Variables{ // 선언문만 가능한 class 영역
int iv; // 인스턴스 변수( 인스턴스가 생성될때 생성 , 객체 생성 필요 )
static int cv; // 클래스 변수( static, 공유변수, 객체 생성 필요없음 )
void method(){ // 메소드 정의( 하나의 메서드는 하나의 기능만 하도록 한다. )
int lv = 0; //지역변수( 변수 선언문이 수행 되었을때 )
}
}



★ 호출 스택 :: 메서드 수행에 필요한 메모리가 제공되는 공간
메서드가 호출되면 스택에 메모리 할당, 종료시 해제
★ 기본형 매개변수 ( readonly )
void change( int x ){}
★ 참조형 매개변수 ( read , write )
Date2 d = new Date2();
change(d);
static void change( Date2 d ){ d.x = 1000 }
★ 참조형 반환타입
=> 아래 캡쳐 참조.
## ======================================
★ static 메소드 / 인스턴스 메소드
static : A1.method(); // 객체 만들지 않고 호출 가능
인스턴스 : A1 d1 = new A1(); d1.method();
static : 메소드 내에서 인스턴스 변수(iv) X
인스턴스 : 메소드 내에서 인스턴스 변수(iv) O
## ======================================
★ 접근 제어자
public : 제한없다.
protected : 같은 패키지 내, 다른 패키지의 자손 클래스 에서 접근 가능
(default) : 같은 패키지 내에서만 접근이 가능하다.
private : 같은 클래스 내에서만 접근 가능
## ======================================
★ final :: 마지막의, 변경될 수 없는
final class FinalTest {
final int max_size = 10 // 값 변경 불가능(상수)
final void getMaxSize(){ // 오버 라이딩 불가
final int lv = max_size; // 값 변경 불가능(상수)
}
} // 조상이 될 수 없는 클래스
## ======================================





★ 오버로딩 : 기존에 없는 새로운 메서드를 정의
int add( int a , int b){}
int add( int a , long b){}
long add( long a , long b){}
int add( int a , int b , int c ){}
int add( int[] a ){}
___________________________________________________________
★ 오버 라이딩 ( 덮어쓰다 ) : 상속받은 메소드의 내용을 변경
=> 선언부 변경 불가 , 선언부가 조상 클래스의 메소드와 일치해야 한다.
=> 내용만 변경 가능
=> 접근 제어자( public , private )을 조상보다 좁은 범위로 할 수 없다.
=> 예외 선언시 조상의 메소드 보다 많이 선언 할 수 없다.
class Parent { void parentMethod() throw IOException , SQLException {} }
class Child extends Parent { void parentMethod() throw IOException {} }


★ 생성자
=> 모든클래스는 하나의 생성자를 반드시 가져야 한다.
=> 생성자의 경우 항상 반환값이 없어서 void를 안쓴다.
=> 생성자가 하나도 없을때만 컴파일러가 기본생성자를 자동으로 생성한다.


★ 상속 class Child extends Parent {}
자손은 모든 맴버를 상속받음 ( 생성자 , 초기화블럭 제외 )
자손의 맴버 개수는 조상보다 같거나 많다.
자손의 변경은 조상과 관계없다.
java는 단일 상속만을 허용한다. class TvDVD extends TV , DVD { // XX 오류
=> 따라서 비중이 높은 하나의 클래스만 상속하고 나머지는 포함 관계로 한다.
class TvDVD extends TV { DVD dvd = new DVD(); }
=> 부모가 없는 clsss는 자동으로 objcet 클래스(컴파일러 자동추가)를 상속받는다.
Object 클래스(조상클래스) 에 정의된 11개의 메소드를 상속받는다.
toString(); / equals() / hashCode() 등
class TV extends Object { }
=> 생성자의 첫줄엔 반드시 생성자를 호출해야 한다.
Parent ( int x , int y ) { super(); // object() }
Child ( int x , int y , int z ) {
super(); this.x = x; this.y = y; this.z = z;
}
## ======================================
★ Super
super.x : 조상의 맴버를 자신의 맴버와 구분할때 이용
조상의 생성자를 호출 할 때 사용
조상의 맴버는 조상의 생성자를 호출해서 초기화 super()




★ 패키지
.jar 은 클래스들을 압축한 파일 ( JDK 설치경로\jre\lib 에 위치 )
★ import 패키지명.클래스명
패키지와 클래스 선언 사이에 위치한다.
import java.util.*
★ (static) :: import static 패키지명.클래스명
import static java.lang.Math.random; (클래스 이름을 생략할 수 있게 해준다.)
system.out.println( Math.random() ); => system.out.println( random() )
★ 다형성
=> 참조 변수와 인스턴스 타입이 일치
SmartTv s = new SmartTv();
조상과 자손의 참조 변수 모두 사용가능
=> 참조 변수와 인스턴스 타입이 불일치( 조상 타입 참조 변수로 자손 타입 인스턴스 참조 가능 )
Tv t = new SmartTv(); // (조상::리모컨) t = new (자손::기능) (OK)
// (자손) t = new 조상 (Error)
조상의 참조 변수만 사용 가능
=> 참조 변수의 형변환( 상속 관계일때만 가능 )
사용할 수 있는 맴버의 갯수를 조절하는것
조상, 자손 관계의 참조변수는 서로 형변환 가능
=> instanceof 연산자
참조변수의 형변환 가능여부 확인 ( 가능하면 true 반환 )
void doWork( FireEngine fe ){
if( fe instanceof Car ){ // Car c = (Car) fe :: true ??
Car c = (Car) fe
c.water();
}
}
FireEngine fe = new FireEngine();
Car ca = new Car();
System.out.println( fe instance of Object ); //true :: Object obj = (Object) fe;
System.out.println( fe instance of Car ); //true :: Car c = (Car) fe;
System.out.println( ca instance of FireEngine ); //fale :: FireEngine fe = (FireEngine) ca
★ abstract :: 추상적인 , 미완성의
=> abstract 리턴타입 메서드 이름();
=> 추상 메서드 :: {} 구현부가 없는 메서드.
=> 추상 클래스 :: 추상메서드를 가지고 있는 클래스
=> 추상클래스를 상속받는 하위클래스는
반드시 abstract 메서드를 오버라이딩 해야된다. => 강제성
=> 추상클래스는 인스턴스 생성 불가( 미완성 설계도 )
Player p = new Player(); ( x ) // 인스턴스 생성 불가
=> 추상클래스를 상속받아서 완전한 클래스를 만든후에 사용
abstract class Player { // 추상 클래스
abstract void play(); // 추상 메소드 :: 구현부가 없는 메소드
abstract void stop();
}
abstract class AbstractPlayer extends Player {
void play(); // 모두 구현하지 않은경우 class에 abstract 붙여야 한다.
}
class AudioPlayer extends Player { // 추상클래스 상속받아 사용.
void play() {/* 내용 */}
void stop() {/* 내용 */} // 모두 구현되면 abstract 안붙여도 된다.
}
AudioPlayer ap = new AudioPlayer(); // 사용 가능
Player ap = new AudioPlayer(); // 다형성
/** ============ 참조 변수의 형 변환 ============ */
package ch001;
abstract class Player {
abstract void play( int pos );
abstract void stop();
}
//추상 클래스는 상속을 통해 객체 생성
class AudioPlayer extends Player{
void play(int pos) {System.out.println( pos + " 위치부터 play 합니다.");}
void stop() {System.out.println("종료합니다.");}
}
public class Hello1 {
public static void main(String[] args) {
//Player p = new Player();// 추상클래스 인스턴스 생성 불가
/** 묵시적 형변환 *************
* 상위(부모) 클래스 타입 = 하위(자식) 클래스 타입
* 부모타입은 자식타입을 포함
* 자신 클래스에 정의된 변수와 메소드만 사용이 가능
* 단, 하위클래스에서 오버라이딩 했을 경우 하위클래스에 선언된 메소드가 호출
* *************************/
Player ap = new AudioPlayer(); // 다형성
ap.play( 100 );
ap.stop();
AudioPlayer ap2 = new AudioPlayer();
Player pl = (Player) ap2; // (Player) 생략가능
pl.play( 200 );
pl.stop();
/** 명시적 형변환 *************
* 하위클래스 타입 = (하위클래스타입) 상위 클래스 타입
* 부모의 클래스가 묵시적 형변환이 되어 있어야 한다.
* Player ap3 = new AudioPlayer();
* *************************/
Player ap3 = new AudioPlayer(); //묵시적 형변환
AudioPlayer pl2 = (AudioPlayer) ap3; //명시적 형변환
pl2.play( 300 );
pl2.stop();
}
}
class Product2 {
int price; // 제품의 가격
int bonusPoint; // 제품구매 시 제공하는 보너스점수
Product2() {} // 기본 생성자
Product2(int price) {
this.price = price;
bonusPoint = (int)(price/10.0);
}
}
class Tv2 extends Product2 {
Tv2() { super(100); }
public String toString() { return "Tv"; }
}
class Computer2 extends Product2 {
Computer2() { super(200); }
public String toString() { return "Computer"; }
}
class Audio2 extends Product2 {
Audio2() { super(50); }
public String toString() { return "Audio"; }
}
class Buyer2 { // 고객, 물건을 사는 사람
int money = 1000; // 소유금액
int bonusPoint = 0; // 보너스점수
Product2[] cart = new Product2[10]; // 구입한 제품을 저장하기 위한 배열
int i =0; // Product배열에 사용될 카운터
void buy(Product2 p) {
if(money < p.price) {
System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
return;
}
money -= p.price; // 가진 돈에서 구입한 제품의 가격을 뺀다.
bonusPoint += p.bonusPoint; // 제품의 보너스 점수를 추가한다.
cart[i++] = p; // 제품을 Product[] cart에 저장한다.
System.out.println(p + "을/를 구입하셨습니다.");
}
void summary() { // 구매한 물품에 대한 정보를 요약해서 보여 준다.
int sum = 0; // 구입한 물품의 가격합계
String itemList =""; // 구입한 물품목록
// 반복문을 이용해서 구입한 물품의 총 가격과 목록을 만든다.
for(int i=0; i<cart.length;i++) {
if(cart[i]==null) break;
sum += cart[i].price;
itemList += cart[i] + ", ";
}
System.out.println("구입하신 물품의 총금액은 " + sum + "만원입니다.");
System.out.println("구입하신 제품은 " + itemList + "입니다.");
}
}
class Ex7_9 {
public static void main(String args[]) {
Buyer2 b = new Buyer2();
b.buy(new Tv2());
b.buy(new Computer2());
b.buy(new Audio2());
b.summary();
}
}
package ch001;
abstract class Unit {
int x , y;
abstract void move( int x , int y ); // 구현부{} 없는경우 abstract 붙여야함.
void stop() {}
}
class Marine extends Unit{
void move(int x , int y) { System.out.println("마린 이동"); }
void stimPack() {}
}
class Tank extends Unit{
void move(int x , int y) { System.out.println("Tank 이동"); }
void changeMode() {}
}
class Dropship extends Unit{
void move(int x , int y) { System.out.println("드랍쉽 이동"); }
void load() {}
void unload() {}
}
public class Hello {
public static void main(String[] args) {
// Unit[] group = new Unit[3];
// group[0] = new Marine();
// group[1] = new Tank();
// group[2] = new Dropship();
Unit[] group = { new Marine() , new Tank() , new Dropship() };
for (int i = 0; i < group.length; i++) {
group[i].move(100 , 200);
}
}
}
★ 인터페이스( 구현된게 없는 설계도 )
=> 추상 메서드의 집합 이고 모두 public
=> default 메서드 추가 가능( 추가된 기능 )
=> static 메서드 추가 가능( 추가된 기능 )
=> 인터페이스 조상은 인터페이스만 가능( object가 최고 조상 아님 )
interface abcInterface{
public static final int name = 1; // 변하지 않는 수(상수) 가능
public abstract String method(); // public abstract 생략 가능
}
=> 다중 상속 가능 :: interface C extends A , B {} // 총돌해도 관계X
=> 구현
:: class C implements A , B { /* 추상 메소드 모두 구현 */ }
:: abstract class C implements A , B { /* 추상 메소드 일부만 구현 */ }
:: class C extends B implements A {} // B 상속받고 , A 인터페이스를 구현하는 C
=> 매개변수가 인터페이스 :: 인터페이스를 구현한 클래스의 인스턴스만 가능하다.
=> return 타입이 인터페이스 :: 인터페이스를 구현한 클래스의 인스턴스 반환
★ 인터페이스 장점
=> 두 객체 간의 중간역할
=> 선언과 구현을 분리시킴( 구현부분이 바뀌어도 선언부분에 영향이 없음 )
=> 표준화가 가능하다.
=> 변경에 유리한 설계가 가능하다.
=> 서로 관계없는 클래들을 관계를 맺어 줄 수 있다.
interface A { // 인터페이스
public abstract String move( int a ); // public abstract 생략가능
}
interface B extends A { // A 인터페이스 상속 받은 B 인터페이스
void move2( int a );
public static final int abc = 10; // 인터페이스는 상수(변하지 않는 수) 가능
}
class C implements B { // B 인터페이스 구현하는 C 클래스
public String move( int a ) { /* 내용 */ return ""; }
public void move2(int a){ /* 내용 */ }
}
//=================================================================================
abstract class D {
int x , y;
abstract void move( int x , int y ); // 구현부{} 없는경우 abstract 붙여야함.
void stop() {}
}
class E extends D { // 추상클래스 구현
int x , y;
void move( int x , int y ) { /* 내용 */ }
void stop() { /* 내용 */ }
}
// 추상클래스와 인터페이스 공통점
=> 추상 메서드를 가지고 있다.
=> 구현된 것이 전혀 없다.
// 추상클래스와 인터페이스 차이점
=> 인터페이스는 iv( 인스턴스 변수)를 가질 수 없다.




★ 함수형 인터페이스
=> 애너테이션 @Functionallnterface :: 컴퍼일러가 올바르게 작성했는지 체크해줌
=> 하나의 추상 메서드만 가져야 한다는 제약이 있다.
728x90