1. clone

→ 다른 PC에 업로드했던 원격저장소의 코드를 로컬저장소에 내려받는 행위

→ 여러 PC에서 파일을 한 버전으로 유지할 수 있다.

 

git_cli와 git_sourcetree 폴더의 내용물을 지운 상태에서 진행 (.git도 지우기)

1) 소스트리에서 클론하기

내려받고자 하는 repository의 코드 주소를 복사한다.

 

위와 같이 복사한 주소와 내려받을 폴더 경로를 지정해준 후 클론한다.

 

위와 같이 잘 복사된 것을 확인할 수 있다.

 

2) CLI에서 클론하기

CLI에서도 마찬가지로 받고자 하는 repository의 주소를 복사한다.

 

git clone 주소 . 명령어를 통해 복사한다.

※ 이때 주소 뒤에 .을 반드시 붙여주어야 한다.

 

이와 같이 잘 복사된 것을 확인할 수 있다.

'네트워크캠퍼스 > GIT, GITHUB' 카테고리의 다른 글

.gitignore 파일의 필요성  (0) 2024.01.12
  (0) 2024.01.12
로컬 저장소 내역 깃허브 업로드  (0) 2024.01.10
병합  (0) 2024.01.05
브랜치  (0) 2024.01.04

1. 매개변수의 다형성

※ Promotion : 자동 형변환 vs Casting : 명시적 형변환

- promotion은 멤버 변수의 값을 대입할 때 발생하지만, 메서드 호출 시 사용하는 매개변수에도 발생 가능

- 보통 메서드 호출 시 선언부에서 지정한 데이터타입과 일치하는 매개값을 전달하여 호출하지만, 매개변수에 다형성을 적용하면 자식 객체 전달 가능

 

1) 강제 타입 변환(Type Casting)

→ 부모 타입을 자식 타입으로 변환하는 것

- 부모 타입으로 형 변환이 된 자식 객체만 강제 타입 변환 사용 가능

 

public class Parent {
	public void method1() {
		System.out.println("부모측 1번 메서드 호출");
	}
	
	public void method2() {
		System.out.println("부모측 2번 메서드 호출");
	}
}
public class Child extends Parent{
	@Override
	public void method2() {
		System.out.println("자식측에서 재정의한 2번 메서드");
	}
	
	public void method3() {
		System.out.println("자식만 가지고 있는 3번 메서드");
	}
}
public class MainClass1 {
	public static void main(String[] args) {
		// Promotion이 적용되면 자식클래스에만 정의된 요소 조회 불가능
		Parent p = new Child();
		p.method1(); // Parent에만 정의된 메서드
		p.method2(); // 오버라이딩된 메서드는 타입상관없이 인스턴스 내 자식쪽 호출
		//p.method3(); // p 타입 변수로는 자식쪽에만 정의된 요소 호출 불가
		System.out.println("-----------------");
	}
}

 

Parent p = new Child;

① 좌변에 부모클래스, 우변에 자식클래스     

② 동일한 메서드가 있어야 함 (@Override)

→ 우선순위는 자식쪽에 있음, 부모타입임에도 불구하고 자식쪽 메서드를 호출할 수 있다. → Promotion

 

public class MainClass1 {
	public static void main(String[] args) {
		// Promotion이 적용되면 자식클래스에만 정의된 요소 조회 불가능
		Parent p = new Child();
		p.method1(); // Parent에만 정의된 메서드
		p.method2(); // 오버라이딩된 메서드는 타입상관없이 인스턴스 내 자식쪽 호출
		//p.method3(); // p 타입 변수로는 자식쪽에만 정의된 요소 호출 불가
		System.out.println("------------------------");
		
		Child c = (Child)p; // 부모타입 변수를 자식타입으로 강제형변환(cast)
		c.method2(); // 위와 동일하게 자식측 method2 호출
		c.method3(); // 형 변환 후에는 자식쪽에만 있는 요소도 호출 가능
		
		Child cc = new Child(); // 애초에 자식타입으로 인스턴스 대입 시에도
		cc.method3(); // 자식쪽에만 있는 요소 호출 가능
	}
}

 

Child c = (Child) p;

 

 

★ 부모타입 변수로 자식타입 인스턴스 호출 시

① 부모클래스에만 선언된 메서드 : 부모클래스의 메서드로 호출

② 부모클래스, 자식클래스 모두에 선언된 메서드 (오버라이딩) : 자식클래스의 메서드로 호출

③ 자식클래스에만 선언된 메서드 : 부모 타입으로 호출 불가

 

public class Child2 extends Parent{
	@Override
	public void method2() {
		System.out.println("2번 자식측에서 재정의한 2번 메서드");
	}
	
	public void method3() {
		System.out.println("2번 자식만 가지고 있는 3번 메서드");
	}
}
public class MainClass2 {

	public static void main(String[] args) {
		// Parent 타입에는 Child, Child2 모두 대입 가능
		Parent p1 = new Child(); // 이 부분만 고쳐도 되는 효율성
		p1.method2(); 
		
		// Parent 타입으로는 Child1의 method2도, Child2의 method2도 호출 가능
		// method2는 Parent에도 정의되어 있지만, Child와 Child2에서 오버라이딩된 메서드이기 때문에 호출 가능
	}
}

 

public class MainClass2 {

	public static void main(String[] args) {
		// Parent 타입에는 Child, Child2 모두 대입 가능
		Parent p1 = new Child2(); // 이 부분만 고쳐도 되는 효율성
		p1.method2(); 
		
		// Parent 타입으로는 Child1의 method2도, Child2의 method2도 호출 가능
		// method2는 Parent에도 정의되어 있지만, Child와 Child2에서 오버라이딩된 메서드이기 때문에 호출 가능
	}
}

 

 

 

2. instanceof 키워드

→ 객체가 지정한 클래스의 인스턴스인지 아닌지 검사할 때 사용

Person p = new student();
p instanceof Student // true 반환

왼쪽 항의 객체가 오른쪽 항 클래스의 인스턴스, 즉 오른쪽 항의 객체가 생성되었다면 true 리턴

 

public class Human {
	
	public String name;
	public int age;
	
	public Human(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public Human() {
		this("noname", 0);
		// this.name = "noname";
		// this.age = 0;
	}
	
	public void showInfo() {
		System.out.println("이름: " + this.name);
		System.out.println("나이: " + this.age);
		System.out.println("---------------");
	}
}
public class Student extends Human {
	public Student(String name, int age) {
		super(name, age);
	}
}
public class Cat {
	private String name;
	private int age;
	
	public Cat(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public void meow() {
		System.out.println("야옹 야옹");
	}
}
public class MainClass {

	public static void main(String[] args) {
		// Human, Student, Cat 인스턴스 생성
		Human h1 = new Human("김자바", 20);
		h1.showInfo();
		
		Student s1 = new Student("태국인", 19);
		s1.showInfo();
		
		Cat c1 = new Cat("룰루", 6);
		c1.meow();
		
		System.out.println(h1 instanceof Human); // h1이 Human 기반인가
		System.out.println(s1 instanceof Human); // s1이 Human 기반인가
		System.out.println(h1 instanceof Student); // h1이 Student 기반인가
		System.out.println(s1 instanceof Student); // s1이 Student 기반인가
		// 관련이 아예 없는 객체간 비교는 에러 발생
		//System.out.println(h1 instanceof Cat);
		//System.out.println(s1 instanceof Cat);
	}
}

'네트워크캠퍼스 > JAVA' 카테고리의 다른 글

싱글톤 패턴  (0) 2024.01.15
사용제한자  (0) 2024.01.12
배열의 다형성  (0) 2024.01.10
클래스의 다형성  (0) 2024.01.09
정보은닉, 캡슐화  (0) 2024.01.08

1. 파일과 디렉터리

1) 파일

※ 리눅스에서는 폴더마저 파일로 분류됨

→ 리눅스에서는 모든 것이 파일로 되어 있음

 

2) 디렉터리

- 모든 폴더 상위에 루트폴더(/) 존재

- 루트 디렉토리 하위에 모든 저장장치가 매칭

 

3) 대표적인 디렉터리

/bin 대부분의 명령어 실행파일
시스템과 관련된 중요한 명령어들이 주로 저장
/dev 디바이스(장치) 파일이 배치
디스크, 키보드, 마우스 등의 하드웨어를 제어할 수 있도록 돕는 특수 파일
/etc 리눅스에서 사용하는 대부분의 설정파일
애플리케이션 및 리눅스 자체 설정 파일
/home 각 사용자 계정명으로 생성되는 디렉터리
해당 사용자의 개인적 파일 저장
/sbin 시스템 관리자용 명령어 저장 (root 권한이 필요)
/tmp 임시저장파일
/usr 유저정보
/var 마운트된 정보

 

4) 절대경로 vs 상대경로

절대경로 : 해당 요소의 모든 경로를 기입해 경로를 지정하는 것

상대경로 : 현재 명령을 내리는 지점/파일 위치를 감안해서 상대적으로 위치를 지정하는 것

 

5) 와일드카드 

ex) $ ls ab* : ab로 시작하는 모든 파일 조회

ex) $ ls ab? : ab로 시작하는 3글자 파일 조회

 

6) cd 명령어

→ 디렉토리 간 이동

 

7) ls 명령어

→ 파일 목록 출력

-l 상세조회
-a 전체조회(숨김파일까지 조회)
-t 생성날짜 내림차순으로 조회
-F 파일 종류 조회
/:디렉터리  *:실행가능파일  @:심볼릭링크
ls 경로 해당 경로 내부 조회
-w [숫자] 해당 숫자만큼의 열로 출력
--quote-name 파일이름에 따옴표 붙임

루트폴더 내의 모든 요소 조회 가능

파일이름에 따옴표를 붙여서 출력

 

 

2. 파일 조작 명령어

1) mkdir : 디렉터리 생성

-p 옵션 : 여러 개의 디렉터리 한 번에 생성 가능

 

2) touch : 파일 생성

위와 같이 나열하여 여러 개 파일을 한번에 생성할 수도 있다.

 

3) rm, rmdir : 파일, 디렉터리 삭제

rm -r : 데릭터리와 디렉터리 하위 모든 것 삭제

rm -i 파일명 : 삭제할지 말지 확인 후 삭제

 

4) cat : 파일 내용 출력

-n 옵션 : 행 번호 출력

 

 

5) less : 스크롤 출력

space, f, ctrl+v : 한 화면 아래로 스크롤

b, alt+v : 한 화면 위로 스크롤

j, ctrl+n, enter : 한 행 아래로 스크롤

k, ctrl+p : 한 행 위로 스크롤

q : less 명령어 종료

 

6) cp : 파일, 디렉터리 복사

cp [옵션] [복사할파일] [복사할위치]

-i 옵션 : 덮어쓰기 전 경고

-r 옵션 : 디렉터리 복사 시 사용

위와 같이 디렉터리 복사 시에는 -r 옵션을 사용한다.

디렉터리 안에 있던 파일까지 모두 복사된 것을 확인할 수 있다.

 

7) mv : 파일 이동, 이름 변경

① 파일 이동

mv [옵션] [이동할파일] [목적지]

b.txt 파일이 test3 디렉터리로 잘 이동된 것을 확인할 수 있다.

위와 같이 여러 파일을 한 번에 옮기는 것도 가능하다.

디렉터리 이동의 경우 -r 옵션을 주지 않아도 된다.

 

② 파일명 변경

a.txt가 b.txt로 변경된 것을 확인할 수 있다.

 

8) ln : 링크 생성

※ 링크 : 리눅스 파일에 별명을 붙이는 것 → 별명으로 호출하는 것이 가능

ln [옵션] [링크할파일] [링크이름]

① 하드링크

 한 파일에 이름을 여러개 부여하는 것

위와 같이 file2를 열어보면 file1의 내용과 같은 것을 출력한다.

그냥 보기에는 복사와 같다고 생각할 수 있지만, 위와 같이 file의 내용을 수정하면 file2의 내용도 똑같이 변경되어 있는 것을 확인할 수 있다.

하드링크의 경우 원본을 삭제하더라도 위와 같이 계속 역할을 수행할 수 있다.

 

② 심볼릭링크

→ 디렉터리는 하드링크로 지정할 수 없고, 서로 다른 디스크에 걸쳐서 만드는 것이 불가능하다.

ln -s [링크할파일] [링크이름]

심볼릭링크의 경우 원본이 삭제되면 기능을 수행할 수 없게 된다.

즉, 바로가기의 기능처럼 참조형으로 해당 파일의 위치만 가지고 있기 때문에 링크가 깨진 심볼릭 링크는 사용할 수 없다.

위와 같이 심볼릭 링크의 원본이 삭제되면 연결된 링크 파일은 동작하지 않는 것을 확인할 수 있다.

 

☆ 링크를 사용하는 이유

① 긴 절대경로를 별명으로 줄여서 사용하기 위해

② 버전이 여러 개인 파일이 한 폴더에 있을 때 구분하기 위해

 

9) 파일 찾기

① find : 디렉터리에서 파일 찾기

find [검색할디렉터리] [검색조건] [액션]

현재 작업폴더에서 a 파일을 찾아 콘솔에 찍어달라는 의미이다.

 

② grep : 특정 문자열이 포함된 파일 찾기

grep [찾는문자] [경로]

위와 같이 cat.txt 파일에서 print라는 문자가 포함된 열만 출력한다.

-i 대소문자 구분 없이 검색 
-v 해당 문자가 포함되지 않은 문장 검색
-r 해당 디렉토리 하위까지 검색
--color 찾은 문자열 강조, 기본은 빨간색

콘솔에 hello world를 찍고, 그 중 hello가 포함된 줄만 출력하라는 의미이다.

 

10) --help : 명령어 도움말 보기

- 사용법, 명령어의 기능적 설명, 지정할 수 있는 옵션목록과 설명 등의 내용

※ $ LANG=ko_KR.UTF-8 cat --help : 한글 문서가 있는경우 한글 출력

 

11) man : 메뉴얼 출력, --help에 비해 상세한 내용

man [키워드]

-k 옵션 : 특정 명령어 출력

위와 같이 복사 관련 키워드의 메뉴얼이 출력된다.

 

man cat 입력 시 CAT(1)이라고 나온다.

괄호 안에 숫자는 섹션을 의미한다.

1 : 명령어

2 : 시스템콜

3 : 라이브러리 함수

4 : 디바이스파일

5 : 파일 서식

6 : 게임

7 : 기타

8 : 시스템 관리 명령어

9 : 커널 루틴

 

man [섹션번호] [이름] 

-wa 옵션 : 해당 명령어가 몇 번 섹션 번호 문서가 존재하는지 볼 수 있다.

 

12) which : 명령어 검색

which [옵션] [명령어]

 

 

3. 파일 권한 변경하기

→ 중요한 시스템 파일들을 함부로 제어하지 못하게 막기 위한 목적

 

1) 10자리 비트 -rwxrwxrwx

① 첫 자리

- : 일반 파일

d : 디렉터리

l : 심볼릭 링크

b : 블록장치

c : 문자장치

s : 소켓

p : 이름 있는 파이프

 

② 나머지는 세글자씩 묶기

r : 읽기 (4)

w : 쓰기 (2) 

x : 실행 (1)

 

③ 3비트씩 쪼갠 것의 의미

소유자의 권한, 그룹의 권한, 다른 사용자 및 그룹의 권한

 

2) chmod

$ chmod 숫자(3자리) 파일명 

745 : 소유자(rwx), 그룹(r), 다른사용자(rx) 의 권한을 가짐

 

$ chmod -R 숫자(3자리) 디렉터리 및 경로

위와 같이 test 디렉터리 안에 두 개의 파일이 있을 때

 

-R 옵션을 사용하면 디렉터리와 그 안의  파일들까지 모두 해당 권한으로 변경되는 것을 확인할 수 있다.

 

 

4. 파일 소유권 변경하기

☆ 소유권 변경이 가능한 사용자는 루트계정뿐 

1) $ su -

위 명령어를 통해 루트계정으로 변경한 후 진행

 

2) chown

# chown 유저명 파일명

# chown 유저명:그룹명 파일명

# chown -R 유저명:(그룹명) 파일명

 

루트 계정에서 rootuser.txt 파일을 생성해준다.

다시 일반사용자 계정으로 돌아와서 vi를 통해 해당 파일을 열어준다.

위와 같이 일반사용자 계정은 r 권한만 있기 때문에 readonly 경고가 뜨는 것을 확인할 수 있다.

루트 계정에서 chown 명령어를 이용하여 rootuser.txt 파일의 소유권을 ubuntu 계정으로 변경해준다.

다시 ubuntu로 돌아와서 rootuser.txt 파일 내용을 수정해보면 잘 변경되는 것을 확인할 수 있다.

'네트워크캠퍼스 > LINUX' 카테고리의 다른 글

프로세스  (0) 2024.01.16
텍스트에디터  (0) 2024.01.15
프롬프트  (0) 2024.01.10
Shell  (0) 2024.01.09
리눅스 개요  (0) 2024.01.09

1. push

→ 로컬저장소의 저장소(repository)를 원격저장소의 저장소로 복사하는 것

 

1) repository 추가

 

위와 같이 추가해주면 원격저장소 생성이 완료된다.

 

원격저장소를 연결하는 위의 명령어를 복사한다.

 

2) 깃허브 인증 추가 (토큰 생성)

repo는 필수, 나머지는 선택

 

3) 소스트리에서 깃허브 업로드

 

위에서 발급받은 토큰으로 인증

 

설정 탭에서 사용자 정보에 이름과 이메일 추가

 

전역 사용자 설정을 체크하면 global, 아니라면 local로 설정

컴퓨터를 나만 쓰는게 확실하다면 global로 설정하는 것이 편함, 여기서는 강의장 PC이므로 local로 설정

 

※ git global과 git local

- 특정 폴더에 대한 유저정보를 저장하고 싶다면 local 방식을 써야 한다.

- 컴퓨터 전체에서 공용으로 쓰는 계정을 사용하고 싶다면 global 방식을 써야 한다.

 

[저장소] - [저장소설정] 탭에서 위와 같이 생성했던 원격 저장소 정보 추가

 

위와 같이 브랜치를 선택하여 업로드할 수 있다.

 

푸시가 완료되면 위와 같이 원격 저장소의 모든 브랜치가 업로드된 것을 확인할 수 있다.

 

4) CLI에서 깃허브 업로드

→ CLI에서는 git config 명령어를 사용한다.

 

- 글로벌 설정 시

git config --global user.name"유저명"

git config --global user.email"이메일"

 

- 로컬 설정 시

git config --local user.name"유저명"

git config --local user.email"이메일"

 

 

먼저, 레포지토리를 생성한다.

위와 같이 원격저장 소 주소를 복사해둔다.

remote : 깃이 아닌 깃허브 관련 설정

add : 깃허브 관련 설정 추가

origin : 변수명 origin에 주소 저장 (가장 기본적인 이름)

 

git remote 명령어를 통해 원격 저장소 주소가 origin이라는 이름에 매칭된 것을 확인할 수 있다.

 

git remote show 명령어를 통해 제대로 등록이 되었는지 확인할 수 있다.

 

git push 명령어를 사용하여 모든 브랜치 업로드

 

위와 같이 잘 업로드 된 것을 확인할 수 있다.

'네트워크캠퍼스 > GIT, GITHUB' 카테고리의 다른 글

  (0) 2024.01.12
클론  (0) 2024.01.11
병합  (0) 2024.01.05
브랜치  (0) 2024.01.04
커맨드라인을 활용한 깃  (0) 2024.01.03

1. 이종모음(Heterogeneous Collection)

→ 배열에 다형성을 적용시키는 원리

- 배열은 원래 동종모음 구조

// 기본형 자료형으로 만든 배열 예시
// 다른 자료형을 넣을 수 없음
int [] iArr = {1, 2, 3, 4, 5, "인프라"}; // 오류 발생
// A 자료형의 힙 주소를 배열로 저장 가능한 배열 생성
A[] aArr = new A[2];

A a1 = new A();
A a2 = new A();

aArr[0] = a1;
aArr[1] = a2;

위와 같이 동종모음인 경우에만 배열 생성이 가능하다.

 

☆ 다형성을 이용하면 이종모음 구조의 객체 배열 생성이 가능하다.

// 모든 클래스의 부모클래스인 Object 배열을 선언하면
// 다형성 원리(부모 객체를 요구하는 자리에 자식타입을 대입 가능함)에 의해
// 모든 자료를 다 대입할 수 있음.
Object[] oArr = new Object[3];

B b1 = new B();
// aArr[1] = b1; // A타입을 요구하는 배열에 B타입 대입 불가
oArr[0] = b1;
oArr[1] = a2;
oArr[2] = 100; // Object 배열에는 기본형 자료도 대입 가능

위와 같이 다형성 원리에 의해 이종모음 구조의 객체 배열 생성이 가능한 것을 확인할 수 있다.

 

 

 

 

'네트워크캠퍼스 > JAVA' 카테고리의 다른 글

사용제한자  (0) 2024.01.12
매개변수의 다형성  (0) 2024.01.11
클래스의 다형성  (0) 2024.01.09
정보은닉, 캡슐화  (0) 2024.01.08
접근제한자  (0) 2024.01.08

1. 커맨드 삭제

 

1) 특정 단위나 지정

ctrl + b 커서를 한 글자 왼쪽으로 이동
ctrl + f 커서를 한 글자 오른쪽으로 이동
ctrl + a 커서를 맨 왼쪽으로 이동
ctrl + e 커서를 맨 오른쪽으로 이동

 

2) 단어 단위

alt + b 커서를 한 단어 왼쪽으로 이동
alt + f 커서를 한 단어 오른쪽으로 이동

 

3) 삭제

backspace
ctrl + h
커서 왼쪽 문자 하나 삭제
delete
ctrl + d
커서 오른쪽 문자 하나 삭제
ctrl + w 커서 왼쪽 한 단어 삭제

 

 

2. 커맨드 자르기 및 붙여넣기

ctrl + k 커서의 위치에서 끝까지 잘라내기
ctrl + u 커서의 위치에서 커맨드라인의 첫 문자까지 잘라내기
ctrl + y 마지막으로 잘라내기한 내용 붙여넣기

 

 

3. 각종 돌발 상황

 

1) 키보드 입력이 안되는 경우 → 화면 표시 잠그는 키를 입력했을 가능성

ctrl + s 화면 표시 잠그기 (입력 방지)
ctrl + q 화면 표시 잠금 풀기 (입력 가능)

 

2) 실행한 명령을 중도에 중단시키는 경우

ctrl + c

 

3) 프롬프트 문자가 깨지는 경우

ctrl + l 혹은 clear 입력

그래도 깨진다면 reset 입력

 

 

4. 명령 이력 확인하기

 

1) 명령 이력 확인

상단방향키
ctrl + p
직전 명령 하나씩 조회
하단방향키
ctrl + n
다음 명령 하나씩 조회
ctrl + r 전체적 이력 검색

 

2) ctrl + r 이후 

특정 문자 입력 해당 문자를 포함하는 검색결과 조회
ctrl + r 한 개 이전의 검색결과로 이동
enter 현재 검색 결과 실행
esc 조회 취소 및 커맨드라인으로 복귀
ctrl + g 검색 결과 지우고 커맨드라인으로 복귀

 

3) history [숫자]

가장 최근에 입력했던 명령어를 숫자만큼 출력해줌

!번호 해당 번호 명령어 재호출
!! 바로 직전 명령어 수행
!?문자열? 해당 문자를 포함한 명령어 중 가장 최근 명령어 하나 수행

 

'네트워크캠퍼스 > LINUX' 카테고리의 다른 글

프로세스  (0) 2024.01.16
텍스트에디터  (0) 2024.01.15
파일시스템  (0) 2024.01.11
Shell  (0) 2024.01.09
리눅스 개요  (0) 2024.01.09

1. 클래스의 다형성

1) 클래스의 다형성

→ 부모타입의 인스턴스로 자식 타입을 대입받거나 호출하는 것이 가능한 것

※ 자료형이 다른 변수는 대입이 불가능

부모 자료형과 자식 자료형도 같은 자료형이 아니기 때문에 원칙적으로는 대입이 불가능하다.

그러나 상속을 통한 인스턴스 생성 시 부모 영역과 자식 영역이 구분되어 저장되기 때문에 일부 영역은 통제 가능한 상태가 된다.

ex) 부모클래스 사람(이름,나이,자기소개()) & 자식클래스 학생(전공, 공부하기())

      부모타입인 사람 타입의 변수에 학생 인스턴스를 대입하는 것이 가능

☆ 부모쪽에 존재하는 함수를 오버라이딩한 경우만 자식의 함수로 호출이 가능하므로 인터페이스를 이용해 다형성을 구현한다.

 

2) 다형성(Polymorphism)

- 하나의 객체가 여러가지 유형으로 사용되는 것

- 상속을 전제조건으로 함

- 자식클래스가 부모클래스의 타입을 가질 수 있도록 허용 → 부모 타입에 모든 자식객체가 대입될 수 있음

 

① 다형성이 적용되지 않은 코드 예시

package noinheri;

public class Rabbit {
	// 토끼 몬스터 hp, atk, def
	private int hp;
	private int atk;
	private int def;

	// 생성자에서 void 파라미터로 각각 3, 0, 0으로 초기화
	public Rabbit() {
		this.hp = 3;
		this.atk = 0;
		this.def = 0;
	}
	
	// setter / getter 자동생성
	// alt + shift + s 후 Generate getters and setters 선택

	public int getHp() {
		return hp;
	}

	public void setHp(int hp) {
		this.hp = hp;
	}

	public int getAtk() {
		return atk;
	}

	public void setAtk(int atk) {
		this.atk = atk;
	}

	public int getDef() {
		return def;
	}

	public void setDef(int def) {
		this.def = def;
	}
}
package noinheri;

public class Warrior {
	// 정보은닉 적용
	private String id;
	private int hp;
	private int atk;
	private int def;
	private int exp;
	
	// 생성자 id 입력받고 나머지 필드 초기화
	public Warrior(String id) {
		this.id = id;
		this.hp = 20;
		this.atk = 3;
		this.def = 1;
		this.exp = 0;
	}
	
	// 캐릭터 상태 조회
	public void showStatus() {
		System.out.println("아이디 : " + this.id);
		System.out.println("체력 : " + this.hp);
		System.out.println("공격력 : " + this.atk);
		System.out.println("방어력 : " + this.def);
		System.out.println("경험치 : " + this.exp);
		System.out.println("------------------");
	}
	
	// 단독 사냥을 하도록 메서드 생성
	public void huntRabbit(Rabbit rabbit) {
		if(rabbit.getHp() <= 0) {
			System.out.println("이미 죽은 토끼입니다.");
			return; // 죽은 토끼에 대해서는 추가 로직이 필요없음
		}
		// 1. 내가 공격한 토끼의 체력 -3
		rabbit.setHp(rabbit.getHp() - this.atk);
		// 2. 방금 공격으로 죽었다면 경험치 5 증가
		if(rabbit.getHp() <= 0) {
			System.out.println("토끼를 죽였습니다.");
			this.exp += 5;
		} else {
			System.out.println("토끼를 공격했습니다.");
		}
	}
}
package noinheri;

public class MainClass1 {

	public static void main(String[] args) {
		// 전사 하나 생성
		Warrior w1 = new Warrior("전사1");
		// 생성 직후 정보 조회
		w1.showStatus();
		// 토끼 생성
		Rabbit r1 = new Rabbit();
		// 토끼와 교전
		w1.huntRabbit(r1);
		// 죽은 토끼 한 번 더 공격
		w1.huntRabbit(r1);
		// 사냥 후 정보 조회
		w1.showStatus();
	}
}

위 상황에서 huntRabbit() 함수는 Rabbit 자료형만을 받아올 수 있게 되어 있으므로 Rat 자료형 요구 시 오류가 발생한다.

 

package noinheri;

public class Rat {
	// 쥐 몬스터 hp, atk, def
	private int hp;
	private int atk;
	private int def;

	// 생성자에서 void 파라미터로 각각 3, 0, 0으로 초기화
	public Rat() {
		this.hp = 5;
		this.atk = 1;
		this.def = 0;
	}
	
	// setter / getter 자동생성
	// alt + shift + s 후 Generate getters and setters 선택

	public int getHp() {
		return hp;
	}

	public void setHp(int hp) {
		this.hp = hp;
	}

	public int getAtk() {
		return atk;
	}

	public void setAtk(int atk) {
		this.atk = atk;
	}

	public int getDef() {
		return def;
	}

	public void setDef(int def) {
		this.def = def;
	}
}
package noinheri;

public class Warrior {
	// 정보은닉 적용
	private String id;
	private int hp;
	private int atk;
	private int def;
	private int exp;
	
	// 생성자 id 입력받고 나머지 필드 초기화
	public Warrior(String id) {
		this.id = id;
		this.hp = 20;
		this.atk = 3;
		this.def = 1;
		this.exp = 0;
	}
	
	// 캐릭터 상태 조회
	public void showStatus() {
		System.out.println("아이디 : " + this.id);
		System.out.println("체력 : " + this.hp);
		System.out.println("공격력 : " + this.atk);
		System.out.println("방어력 : " + this.def);
		System.out.println("경험치 : " + this.exp);
		System.out.println("------------------");
	}
	
	// 단독 사냥을 하도록 메서드 생성
	public void huntRabbit(Rabbit rabbit) {
		if(rabbit.getHp() <= 0) {
			System.out.println("이미 죽은 토끼입니다.");
			return; // 죽은 토끼에 대해서는 추가 로직이 필요없음
		}
		// 1. 내가 공격한 토끼의 체력 -3
		rabbit.setHp(rabbit.getHp() - this.atk);
		// 2. 방금 공격으로 죽었다면 경험치 5 증가
		if(rabbit.getHp() <= 0) {
			System.out.println("토끼를 죽였습니다.");
			this.exp += 5;
		} else {
			System.out.println("토끼를 공격했습니다.");
		}
	}
	
	// Rat은 공격을 받고 죽지 않으면 1회 반격
	// 경험치는 80
	public void huntRat(Rat rat) {
		if(rat.getHp() <= 0) {
			System.out.println("이미 죽은 쥐입니다.");
			return;
		}
		rat.setHp(rat.getHp() - this.atk);
		if(rat.getHp() <= 0) {
			System.out.println("쥐를 죽였습니다.");
			this.exp += 80;
		}
		else {
			System.out.println("쥐를 공격했습니다.");
			System.out.println("쥐가 반격합니다.");
			this.hp = this.hp - rat.getAtk();
		}
	}
}
package noinheri;

public class MainClass2 {

	public static void main(String[] args) {
		// 전사 생성
		Warrior w1 = new Warrior("전사2");
		// 상태 조회
		w1.showStatus();
		// 쥐 생성
		Rat rat1 = new Rat();
		// 쥐와 교전 (3번)
		for(int i = 0; i < 3; i++) {
			w1.huntRat(rat1);
		}
		// 상태조회
		w1.showStatus();
	}
}

 

 

② 다형성이 적용된 코드 예시

package inheri;

public class Monster {
	// 모든 몬스터 클래스의 부모타입으로 설계된 클래스
	private String name; // 다형성 특성상 몬스터 종류를 식별하기 위한 변수
	private int hp;
	private int atk;
	private int def;
	private int exp;
	
	// 부모쪽 생성자로 초기화할 때 어떤 몬스터가 생성될지 사전에 알 수 없으므로
	// 고정값이 아닌 자식쪽에서 입력받은 자료를 대입하도록 생성자 설계
	public Monster(String name, int hp, int atk, int def, int exp) {
		this.name = name;
		this.hp = hp;
		this.atk = atk;
		this.def = def;
		this.exp = exp;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getHp() {
		return hp;
	}

	public void setHp(int hp) {
		this.hp = hp;
	}

	public int getAtk() {
		return atk;
	}

	public void setAtk(int atk) {
		this.atk = atk;
	}

	public int getDef() {
		return def;
	}

	public void setDef(int def) {
		this.def = def;
	}

	public int getExp() {
		return exp;
	}

	public void setExp(int exp) {
		this.exp = exp;
	}
}
package inheri;

public class Warrior {
	// 정보은닉 적용
	private String id;
	private int hp;
	private int atk;
	private int def;
	private int exp;
	
	// 생성자 id 입력받고 나머지 필드 초기화
	public Warrior(String id) {
		this.id = id;
		this.hp = 20;
		this.atk = 3;
		this.def = 1;
		this.exp = 0;
	}
	
	// 캐릭터 상태 조회
	public void showStatus() {
		System.out.println("아이디 : " + this.id);
		System.out.println("체력 : " + this.hp);
		System.out.println("공격력 : " + this.atk);
		System.out.println("방어력 : " + this.def);
		System.out.println("경험치 : " + this.exp);
		System.out.println("------------------");
	}
	
	// 파라미터로 모든 몬스터의 부모타입인 Monster 인스턴스를 요구하면
	// 다형성 원리에 의해 상속받은 모든 몬스터를 다 대입할 수 있음
	public void hunt(Monster monster) {
		// 죽은 몬스터는 교전 불가 및 메서드 즉시 종료
		if(monster.getHp() <= 0) {
			System.out.println(monster.getName() + "은 이미 죽어서 교전할 수 없습니다.");
			return;
		}
		// 다음 공격으로 몬스터가 죽는 경우
		if(monster.getHp() - (this.atk - monster.getDef()) <= 0){
			// 경험치부여
			monster.setHp(0);
			System.out.println(monster.getName() + "(이)가 죽었습니다.");
			this.exp += monster.getExp();
		} else {
			// 다음 공격으로 몬스터가 죽지 않아서 반격을 받는 경우
			// 몬스터 체력을 (내 공격력 - 몬스터 방어력)만큼 차감
			monster.setHp(this.atk - monster.getDef());
			// 내 체력을 (몬스터 공격력 - 내 방어력)만큼 차감
			this.hp -= monster.getAtk() - this.def;
			// **가 반격했습니다.
			System.out.println(monster.getName() + "(이)가 반격했습니다.");
		}
	}
}
// 해당 클래스의 인스턴스는 Monster 타입 변수에도 저장할 수 있음.
public class Rabbit extends Monster {
	public Rabbit() {
		// 부모인 Monster에 이름, 체력, 공격력, 방어력, 경험치 전달
		super("토끼", 3, 0, 0, 5);
	}
}
package inheri;

public class Rat extends Monster {
	public Rat() {
		// 부모인 Monster에 이름, 체력, 공격력, 방어력, 경험치 전달
		super("쥐", 5, 0, 0, 5);
	}
}
package inheri;

public class MainClass1 {

	public static void main(String[] args) {
		// 전사 생성
		Warrior w1 = new Warrior("전사1");
		// 상태 조회
		w1.showStatus();
		// 토끼 생성
		Rabbit r1 = new Rabbit();
		// 전사와 교전 2회
		w1.hunt(r1);
		w1.hunt(r1);
		
		// 쥐 생성
		Rat r2 = new Rat();
		w1.hunt(r2);
		w1.hunt(r2);
		w1.hunt(r2);
		w1.showStatus();
	}
}

위와 같이 상속을 통해 Monster 범주에 들어가는 객체를 모두 호출 가능하다.

원래라면 토끼나 쥐 객체를 생성한 후 Warrior 파일에서 hunt() 함수를 생성해줘야 했는데,

다형성을 이용하여 Monster 타입을 처리하는 hunt로 재설계함으로써 코드의 확장성을 높일 수 있다.

'네트워크캠퍼스 > JAVA' 카테고리의 다른 글

매개변수의 다형성  (0) 2024.01.11
배열의 다형성  (0) 2024.01.10
정보은닉, 캡슐화  (0) 2024.01.08
접근제한자  (0) 2024.01.08
상속  (0) 2024.01.05

1. 리눅스 Shell

→ 사용자와 운영체제 커널 사이의 인터페이스 역할

1) 명령어

명령어 의미
id 아이덴티티 정보
pwd 커맨드라인 위치 경로
ls 파일과 폴더목록
-l : 자세한 정보 출력
-a : 숨겨진 파일 표시
-t : 시간순 출력
--hide=파일명 : 검색결과에서 배제
date 현재 시간
echo 출력명령어
cat 내용물 확인
type 명령어 명령어 경로 조회

 

> : 파일 덮어쓰기

>> : 파일 이어쓰기

 

uname 명령어 : 기본 정보 출력

 

date 명령어

 

2) 명령어 조회하기

type 명령어를 통해 해당 명령어의 실제 위치를 확인할 수 있다.

 

또한, 위와 같이 해당 명령어를 수행하는 실제 실행 코드를 조회할 수 있다.

 

 

2. 셸과 커널의 역할

1) 셸의 역할

→ 사용자의 명령을 커널이라는 실제로 실행하는 심부름꾼에게 전달하는 전령

- 사용자 명령 입력 시 

① 매칭되는 명령어 조회 

② 존재하는 명령어라면 커널에 전달

③ 커널이 실행하고 결과를 화면에 표현

 

2) 겹치는 명령어의 실행 우선순위

ex) /bin/date와 /bin/user/date라는 두 개의 date가 존재한다면? /bin/date가 실행

→ 우선순위는 무조건 경로가 짧은 쪽

 

3) 셸과 커널이 분리된 이유

특정 부분에서 오류 발생 시 일체형이라면 유지보수가 힘들지만,

분리형인 경우 문제가 생긴 부분만 교체하면 되고 다른 요소와 조합해 사용하기도 수월

 

 

3. 프롬프트

1) 프롬프트

@을 기점으로 왼쪽은 사용자명, 오른쪽은 호스트명

 

whoami : 계정명

hostname : 호스트명

 

$ : 일반 사용자 계정

# : root 계정

 

 

4. 셸의 종류

※ 셸의 경우 기본적으로는 대화형 방식(직접 명령어를 입력하여 제어하는 것)을 수행한다.

- 보편적으로는 bash를 가장 많이 사용

- mac 환경인 경우 커스터마이징이 용이해 zsh 사용

 

$만 나타난 셸이 sh

 

최상단에 bash가 열려있으나 로그인된 상태는 아니므로 logout 명령을 적어도 exit을 입력하라고 한다.

 

 

5. 터미널과 셸의 관계

※ 터미널과 셸은 다르다.

- 터미널이라는 프로그램을 이용하여 컴퓨터의 입출력 받음

- 해당 입출력은 셸이 해석하고, 해석 후 유효한 명령인 경우 커널 실행

'네트워크캠퍼스 > LINUX' 카테고리의 다른 글

프로세스  (0) 2024.01.16
텍스트에디터  (0) 2024.01.15
파일시스템  (0) 2024.01.11
프롬프트  (0) 2024.01.10
리눅스 개요  (0) 2024.01.09

+ Recent posts