[{"data":1,"prerenderedAt":1794},["ShallowReactive",2],{"post-document:\u002Fjava\u002Foop\u002F2026\u002F08\u002F10\u002Fjava-oop-concepts\u002F":3},{"id":4,"title":5,"body":6,"categories":1773,"date":1775,"description":1776,"extension":1777,"image":1778,"key_concepts":1778,"last_modified_at":1778,"legacyPath":1779,"meta":1780,"navigation":69,"part":1782,"path":1783,"published":69,"robots":1778,"seo":1784,"series":1785,"stem":1786,"strengths":1778,"summary":1778,"tags":1787,"tradeoffs":1778,"__hash__":1793},"posts\u002Fposts\u002FBackend\u002FJAVA\u002Foop\u002F2026-08-10-java-oop-concepts.md","Java 객체지향 Part 2: OOP 핵심 문법",{"type":7,"value":8,"toc":1755},"minimark",[9,13,18,29,37,118,121,208,212,217,224,262,283,286,295,301,305,308,323,329,344,362,366,373,460,464,467,488,492,495,519,533,570,574,580,594,603,611,614,622,626,631,666,672,685,689,705,733,737,740,776,779,786,791,862,868,874,877,927,935,940,958,996,1002,1025,1029,1033,1036,1088,1092,1095,1179,1190,1194,1202,1254,1257,1261,1265,1268,1323,1326,1330,1333,1403,1409,1413,1475,1479,1602,1606,1751],[10,11,5],"h2",{"id":12},"java-객체지향-part-2-oop-핵심-문법",[14,15,17],"h3",{"id":16},"_1-oop란","1. OOP란?",[19,20,26],"pre",{"className":21,"code":23,"language":24,"meta":25},[22],"language-text","OOP = Object-Oriented Programming\n    = 객체지향 프로그래밍\n","text","",[27,28,23],"code",{"__ignoreMap":25},[30,31,32,33,36],"p",{},"객체지향 프로그래밍은 프로그램을 ",[27,34,35],{},"객체"," 단위로 나누어 설계하는 방법이다. 객체 안에 데이터와 동작을 함께 묶고, 객체끼리 메시지를 주고받으며 프로그램을 실행한다.",[19,38,42],{"className":39,"code":40,"language":41,"meta":25,"style":25},"language-java shiki shiki-themes github-light github-dark","class Stock {\n    String name; \u002F\u002F 데이터: 필드\n    double price;\n\n    void printInfo() { \u002F\u002F 동작: 메서드\n        System.out.println(name + \" : \" + price);\n    }\n}\n\nStock stock = new Stock(); \u002F\u002F 객체 생성\nstock.name = \"SKALA\";\nstock.printInfo();         \u002F\u002F 객체의 동작 호출\n","java",[27,43,44,52,58,64,71,77,83,89,95,100,106,112],{"__ignoreMap":25},[45,46,49],"span",{"class":47,"line":48},"line",1,[45,50,51],{},"class Stock {\n",[45,53,55],{"class":47,"line":54},2,[45,56,57],{},"    String name; \u002F\u002F 데이터: 필드\n",[45,59,61],{"class":47,"line":60},3,[45,62,63],{},"    double price;\n",[45,65,67],{"class":47,"line":66},4,[45,68,70],{"emptyLinePlaceholder":69},true,"\n",[45,72,74],{"class":47,"line":73},5,[45,75,76],{},"    void printInfo() { \u002F\u002F 동작: 메서드\n",[45,78,80],{"class":47,"line":79},6,[45,81,82],{},"        System.out.println(name + \" : \" + price);\n",[45,84,86],{"class":47,"line":85},7,[45,87,88],{},"    }\n",[45,90,92],{"class":47,"line":91},8,[45,93,94],{},"}\n",[45,96,98],{"class":47,"line":97},9,[45,99,70],{"emptyLinePlaceholder":69},[45,101,103],{"class":47,"line":102},10,[45,104,105],{},"Stock stock = new Stock(); \u002F\u002F 객체 생성\n",[45,107,109],{"class":47,"line":108},11,[45,110,111],{},"stock.name = \"SKALA\";\n",[45,113,115],{"class":47,"line":114},12,[45,116,117],{},"stock.printInfo();         \u002F\u002F 객체의 동작 호출\n",[30,119,120],{},"Java OOP를 이해할 때 가장 먼저 구분할 용어는 다음과 같다.",[122,123,124,137],"table",{},[125,126,127],"thead",{},[128,129,130,134],"tr",{},[131,132,133],"th",{},"용어",[131,135,136],{},"정의",[138,139,140,153,164,175,186,197],"tbody",{},[128,141,142,150],{},[143,144,145,146,149],"td",{},"클래스(",[27,147,148],{},"Class",")",[143,151,152],{},"객체를 만들기 위한 설계도. 필드와 메서드를 정의한다.",[128,154,155,161],{},[143,156,157,158,149],{},"객체(",[27,159,160],{},"Object",[143,162,163],{},"클래스에 따라 실행 중 메모리에 실제로 만들어진 실체다.",[128,165,166,172],{},[143,167,168,169,149],{},"인스턴스(",[27,170,171],{},"Instance",[143,173,174],{},"특정 클래스에서 만들어진 객체라는 관계를 강조하는 표현이다.",[128,176,177,183],{},[143,178,179,180,149],{},"필드(",[27,181,182],{},"Field",[143,184,185],{},"객체의 상태나 데이터를 저장하는 클래스 내부 변수다.",[128,187,188,194],{},[143,189,190,191,149],{},"메서드(",[27,192,193],{},"Method",[143,195,196],{},"객체가 수행할 동작을 정의한 클래스 내부 코드 블록이다.",[128,198,199,205],{},[143,200,201,202,149],{},"생성자(",[27,203,204],{},"Constructor",[143,206,207],{},"객체가 만들어질 때 초기 상태를 설정하는 특별한 코드 블록이다.",[14,209,211],{"id":210},"_2-클래스-객체-인스턴스-참조-변수","2. 클래스, 객체, 인스턴스, 참조 변수",[213,214,216],"h4",{"id":215},"클래스와-객체","클래스와 객체",[30,218,219,220,223],{},"클래스는 설계도이고 객체는 설계도로 만든 실제 결과물이다. 클래스 선언만으로는 객체가 생성되지 않으며, ",[27,221,222],{},"new","를 사용해야 객체가 만들어진다.",[19,225,227],{"className":39,"code":226,"language":41,"meta":25,"style":25},"class User {\n    String name;\n    int age;\n}\n\nUser user1 = new User();\nUser user2 = new User();\n",[27,228,229,234,239,244,248,252,257],{"__ignoreMap":25},[45,230,231],{"class":47,"line":48},[45,232,233],{},"class User {\n",[45,235,236],{"class":47,"line":54},[45,237,238],{},"    String name;\n",[45,240,241],{"class":47,"line":60},[45,242,243],{},"    int age;\n",[45,245,246],{"class":47,"line":66},[45,247,94],{},[45,249,250],{"class":47,"line":73},[45,251,70],{"emptyLinePlaceholder":69},[45,253,254],{"class":47,"line":79},[45,255,256],{},"User user1 = new User();\n",[45,258,259],{"class":47,"line":85},[45,260,261],{},"User user2 = new User();\n",[30,263,264,267,268,271,272,275,276,267,279,282],{},[27,265,266],{},"user1","과 ",[27,269,270],{},"user2","는 같은 ",[27,273,274],{},"User"," 클래스에서 만들어졌지만 서로 다른 객체다. 따라서 각각의 ",[27,277,278],{},"name",[27,280,281],{},"age"," 값을 독립적으로 가질 수 있다.",[213,284,285],{"id":285},"인스턴스",[30,287,288,290,291,294],{},[27,289,274],{}," 클래스에서 만들어진 객체를 ",[27,292,293],{},"User의 인스턴스","라고 한다. 즉, 객체는 실체에 초점을 둔 표현이고 인스턴스는 “어떤 클래스에서 만들어졌는가”에 초점을 둔 표현이다.",[19,296,299],{"className":297,"code":298,"language":24,"meta":25},[22],"User 클래스\n   │       │\n   ▼       ▼\nuser1   user2\n   │       │\nUser 인스턴스  User 인스턴스\n",[27,300,298],{"__ignoreMap":25},[213,302,304],{"id":303},"참조-변수","참조 변수",[30,306,307],{},"참조 변수는 객체 자체가 아니라 객체를 가리키는 참조값을 저장한다.",[19,309,311],{"className":39,"code":310,"language":41,"meta":25,"style":25},"User a = new User();\nUser b = a;\n",[27,312,313,318],{"__ignoreMap":25},[45,314,315],{"class":47,"line":48},[45,316,317],{},"User a = new User();\n",[45,319,320],{"class":47,"line":54},[45,321,322],{},"User b = a;\n",[19,324,327],{"className":325,"code":326,"language":24,"meta":25},[22],"a ─────┐\n       ▼\n  [ Heap의 User 객체 ]\n       ▲\nb ─────┘\n",[27,328,326],{"__ignoreMap":25},[30,330,331,334,335,338,339,334,341,343],{},[27,332,333],{},"a","와 ",[27,336,337],{},"b","는 같은 객체를 가리킨다. ",[27,340,333],{},[27,342,337],{},"가 별도의 변수가 아닌 것은 아니지만, 두 변수가 가리키는 객체는 하나다.",[30,345,346,347,350,351,354,355,354,358,361],{},"참고로 Java의 모든 클래스는 기본적으로 ",[27,348,349],{},"java.lang.Object","를 직접 또는 간접적으로 상속한다. ",[27,352,353],{},"int",", ",[27,356,357],{},"double",[27,359,360],{},"boolean"," 같은 기본형은 객체가 아니다.",[14,363,365],{"id":364},"_3-필드-메서드-생성자","3. 필드, 메서드, 생성자",[30,367,368,369,372],{},"다음 ",[27,370,371],{},"Stock"," 클래스를 기준으로 세 개념을 함께 살펴보자.",[19,374,376],{"className":39,"code":375,"language":41,"meta":25,"style":25},"class Stock {\n    private final String name; \u002F\u002F 필드\n    private double price;       \u002F\u002F 필드\n\n    Stock(String name, double price) { \u002F\u002F 생성자\n        this.name = name;\n        this.price = price;\n    }\n\n    public void updatePrice(double newPrice) { \u002F\u002F 메서드\n        this.price = newPrice;\n    }\n\n    public void printInfo() { \u002F\u002F 메서드\n        System.out.println(name + \" : \" + price + \"원\");\n    }\n}\n",[27,377,378,382,387,392,396,401,406,411,415,419,424,429,433,438,444,450,455],{"__ignoreMap":25},[45,379,380],{"class":47,"line":48},[45,381,51],{},[45,383,384],{"class":47,"line":54},[45,385,386],{},"    private final String name; \u002F\u002F 필드\n",[45,388,389],{"class":47,"line":60},[45,390,391],{},"    private double price;       \u002F\u002F 필드\n",[45,393,394],{"class":47,"line":66},[45,395,70],{"emptyLinePlaceholder":69},[45,397,398],{"class":47,"line":73},[45,399,400],{},"    Stock(String name, double price) { \u002F\u002F 생성자\n",[45,402,403],{"class":47,"line":79},[45,404,405],{},"        this.name = name;\n",[45,407,408],{"class":47,"line":85},[45,409,410],{},"        this.price = price;\n",[45,412,413],{"class":47,"line":91},[45,414,88],{},[45,416,417],{"class":47,"line":97},[45,418,70],{"emptyLinePlaceholder":69},[45,420,421],{"class":47,"line":102},[45,422,423],{},"    public void updatePrice(double newPrice) { \u002F\u002F 메서드\n",[45,425,426],{"class":47,"line":108},[45,427,428],{},"        this.price = newPrice;\n",[45,430,431],{"class":47,"line":114},[45,432,88],{},[45,434,436],{"class":47,"line":435},13,[45,437,70],{"emptyLinePlaceholder":69},[45,439,441],{"class":47,"line":440},14,[45,442,443],{},"    public void printInfo() { \u002F\u002F 메서드\n",[45,445,447],{"class":47,"line":446},15,[45,448,449],{},"        System.out.println(name + \" : \" + price + \"원\");\n",[45,451,453],{"class":47,"line":452},16,[45,454,88],{},[45,456,458],{"class":47,"line":457},17,[45,459,94],{},[213,461,463],{"id":462},"필드field","필드(Field)",[30,465,466],{},"필드는 클래스 안에 선언된 변수다. 객체가 가지고 있는 상태를 저장한다.",[468,469,470,479,482],"ul",{},[471,472,473,354,475,478],"li",{},[27,474,278],{},[27,476,477],{},"price",": Stock 객체의 상태",[471,480,481],{},"인스턴스 필드: 객체마다 독립적으로 존재",[471,483,484,487],{},[27,485,486],{},"static"," 필드: 클래스에 하나만 존재하며 객체들이 공유",[213,489,491],{"id":490},"메서드method","메서드(Method)",[30,493,494],{},"메서드는 클래스 안에 선언된 코드 블록이다. 객체의 동작을 정의하며, 입력을 받을 수도 있고 결과를 반환할 수도 있다.",[19,496,498],{"className":39,"code":497,"language":41,"meta":25,"style":25},"[접근 제어자] [반환형] [메서드 이름](매개변수 목록) {\n    \u002F\u002F 실행할 코드\n    return 반환값;\n}\n",[27,499,500,505,510,515],{"__ignoreMap":25},[45,501,502],{"class":47,"line":48},[45,503,504],{},"[접근 제어자] [반환형] [메서드 이름](매개변수 목록) {\n",[45,506,507],{"class":47,"line":54},[45,508,509],{},"    \u002F\u002F 실행할 코드\n",[45,511,512],{"class":47,"line":60},[45,513,514],{},"    return 반환값;\n",[45,516,517],{"class":47,"line":66},[45,518,94],{},[30,520,521,524,525,528,529,532],{},[27,522,523],{},"void","는 호출한 곳에 반환할 값이 없다는 뜻이다. ",[27,526,527],{},"0","이나 ",[27,530,531],{},"null","을 반환한다는 뜻이 아니다.",[19,534,536],{"className":39,"code":535,"language":41,"meta":25,"style":25},"public void printWelcome() {\n    System.out.println(\"환영합니다.\");\n}\n\npublic double getPrice() {\n    return price;\n}\n",[27,537,538,543,548,552,556,561,566],{"__ignoreMap":25},[45,539,540],{"class":47,"line":48},[45,541,542],{},"public void printWelcome() {\n",[45,544,545],{"class":47,"line":54},[45,546,547],{},"    System.out.println(\"환영합니다.\");\n",[45,549,550],{"class":47,"line":60},[45,551,94],{},[45,553,554],{"class":47,"line":66},[45,555,70],{"emptyLinePlaceholder":69},[45,557,558],{"class":47,"line":73},[45,559,560],{},"public double getPrice() {\n",[45,562,563],{"class":47,"line":79},[45,564,565],{},"    return price;\n",[45,567,568],{"class":47,"line":85},[45,569,94],{},[213,571,573],{"id":572},"생성자constructor","생성자(Constructor)",[30,575,576,577,579],{},"생성자는 ",[27,578,222],{},"로 객체를 만들 때 자동으로 실행되어 초기값을 설정하는 특별한 코드 블록이다.",[468,581,582,585,591],{},[471,583,584],{},"이름이 클래스 이름과 같다.",[471,586,587,588,590],{},"반환형을 작성하지 않는다. ",[27,589,523],{},"도 작성하지 않는다.",[471,592,593],{},"생성자를 직접 작성하지 않으면 컴파일러가 기본 생성자를 제공한다. 단, 다른 생성자를 직접 작성하면 기본 생성자가 자동으로 생기지 않는다.",[19,595,597],{"className":39,"code":596,"language":41,"meta":25,"style":25},"Stock stock = new Stock(\"SKALA\", 17000);\n",[27,598,599],{"__ignoreMap":25},[45,600,601],{"class":47,"line":48},[45,602,596],{},[30,604,605,606,267,608,610],{},"위 코드가 실행되면 Heap에 Stock 객체가 만들어지고, 생성자가 ",[27,607,278],{},[27,609,477],{},"를 초기화한다.",[30,612,613],{},"생성자는 메서드처럼 보이지만 Java 언어에서는 반환형이 없고 호출 방식도 다르므로 일반 메서드와 구분한다.",[14,615,617,618,621],{"id":616},"_4-this-매개변수-인자","4. ",[27,619,620],{},"this",", 매개변수, 인자",[213,623,624],{"id":620},[27,625,620],{},[30,627,628,630],{},[27,629,620],{},"는 인스턴스 메서드나 생성자에서 현재 객체 자신을 가리키는 참조다.",[19,632,634],{"className":39,"code":633,"language":41,"meta":25,"style":25},"class User {\n    private String name;\n\n    User(String name) {\n        this.name = name;\n    }\n}\n",[27,635,636,640,645,649,654,658,662],{"__ignoreMap":25},[45,637,638],{"class":47,"line":48},[45,639,233],{},[45,641,642],{"class":47,"line":54},[45,643,644],{},"    private String name;\n",[45,646,647],{"class":47,"line":60},[45,648,70],{"emptyLinePlaceholder":69},[45,650,651],{"class":47,"line":66},[45,652,653],{},"    User(String name) {\n",[45,655,656],{"class":47,"line":73},[45,657,405],{},[45,659,660],{"class":47,"line":79},[45,661,88],{},[45,663,664],{"class":47,"line":85},[45,665,94],{},[19,667,670],{"className":668,"code":669,"language":24,"meta":25},[22],"this.name = name;\n│           │\n│           └─ 생성자에 전달된 매개변수\n└─ 현재 객체의 필드\n",[27,671,669],{"__ignoreMap":25},[30,673,674,675,678,679,681,682,684],{},"따라서 ",[27,676,677],{},"this.name = name;","은 현재 객체의 ",[27,680,278],{}," 필드에 매개변수 ",[27,683,278],{},"의 값을 저장한다는 뜻이다.",[213,686,688],{"id":687},"매개변수와-인자","매개변수와 인자",[468,690,691,698],{},[471,692,693,694,697],{},"매개변수(",[27,695,696],{},"Parameter","): 메서드 선언부에서 입력을 받기 위해 선언한 변수",[471,699,700,701,704],{},"인자(",[27,702,703],{},"Argument","): 메서드를 호출할 때 실제로 전달하는 값",[19,706,708],{"className":39,"code":707,"language":41,"meta":25,"style":25},"public void sayHello(String name) { \u002F\u002F name: 매개변수\n    System.out.println(name);\n}\n\nsayHello(\"민형\");                   \u002F\u002F \"민형\": 인자\n",[27,709,710,715,720,724,728],{"__ignoreMap":25},[45,711,712],{"class":47,"line":48},[45,713,714],{},"public void sayHello(String name) { \u002F\u002F name: 매개변수\n",[45,716,717],{"class":47,"line":54},[45,718,719],{},"    System.out.println(name);\n",[45,721,722],{"class":47,"line":60},[45,723,94],{},[45,725,726],{"class":47,"line":66},[45,727,70],{"emptyLinePlaceholder":69},[45,729,730],{"class":47,"line":73},[45,731,732],{},"sayHello(\"민형\");                   \u002F\u002F \"민형\": 인자\n",[14,734,736],{"id":735},"_5-멤버member","5. 멤버(Member)",[30,738,739],{},"멤버는 클래스 내부에 속한 구성 요소를 통칭하는 말이다. 대표적으로 필드와 메서드가 있으며, 정적 멤버와 중첩 타입도 멤버에 포함될 수 있다.",[19,741,743],{"className":39,"code":742,"language":41,"meta":25,"style":25},"class User {\n    String name;        \u002F\u002F 필드 멤버\n\n    void introduce() {  \u002F\u002F 메서드 멤버\n        System.out.println(name);\n    }\n}\n",[27,744,745,749,754,758,763,768,772],{"__ignoreMap":25},[45,746,747],{"class":47,"line":48},[45,748,233],{},[45,750,751],{"class":47,"line":54},[45,752,753],{},"    String name;        \u002F\u002F 필드 멤버\n",[45,755,756],{"class":47,"line":60},[45,757,70],{"emptyLinePlaceholder":69},[45,759,760],{"class":47,"line":66},[45,761,762],{},"    void introduce() {  \u002F\u002F 메서드 멤버\n",[45,764,765],{"class":47,"line":73},[45,766,767],{},"        System.out.println(name);\n",[45,769,770],{"class":47,"line":79},[45,771,88],{},[45,773,774],{"class":47,"line":85},[45,775,94],{},[30,777,778],{},"생성자는 클래스 내부에 작성되지만 일반 메서드와는 구분되는 특별한 초기화 문법이다.",[14,780,782,783,785],{"id":781},"_6-static-클래스에-소속된-멤버","6. ",[27,784,486],{},": 클래스에 소속된 멤버",[30,787,788,790],{},[27,789,486],{},"은 필드나 메서드를 특정 객체가 아니라 클래스 자체에 소속시키는 키워드다.",[19,792,794],{"className":39,"code":793,"language":41,"meta":25,"style":25},"class User {\n    private static int count = 0;\n\n    User() {\n        count++;\n    }\n\n    public static int getCount() {\n        return count;\n    }\n}\n\nUser user1 = new User();\nUser user2 = new User();\nSystem.out.println(User.getCount()); \u002F\u002F 2\n",[27,795,796,800,805,809,814,819,823,827,832,837,841,845,849,853,857],{"__ignoreMap":25},[45,797,798],{"class":47,"line":48},[45,799,233],{},[45,801,802],{"class":47,"line":54},[45,803,804],{},"    private static int count = 0;\n",[45,806,807],{"class":47,"line":60},[45,808,70],{"emptyLinePlaceholder":69},[45,810,811],{"class":47,"line":66},[45,812,813],{},"    User() {\n",[45,815,816],{"class":47,"line":73},[45,817,818],{},"        count++;\n",[45,820,821],{"class":47,"line":79},[45,822,88],{},[45,824,825],{"class":47,"line":85},[45,826,70],{"emptyLinePlaceholder":69},[45,828,829],{"class":47,"line":91},[45,830,831],{},"    public static int getCount() {\n",[45,833,834],{"class":47,"line":97},[45,835,836],{},"        return count;\n",[45,838,839],{"class":47,"line":102},[45,840,88],{},[45,842,843],{"class":47,"line":108},[45,844,94],{},[45,846,847],{"class":47,"line":114},[45,848,70],{"emptyLinePlaceholder":69},[45,850,851],{"class":47,"line":435},[45,852,256],{},[45,854,855],{"class":47,"line":440},[45,856,261],{},[45,858,859],{"class":47,"line":446},[45,860,861],{},"System.out.println(User.getCount()); \u002F\u002F 2\n",[30,863,864,867],{},[27,865,866],{},"count","는 User 객체마다 따로 생기는 값이 아니라 User 클래스가 하나만 가지고 모든 객체가 공유하는 값이다.",[19,869,872],{"className":870,"code":871,"language":24,"meta":25},[22],"User 클래스\n    │\n  count = 2  ← user1, user2가 함께 사용\n",[27,873,871],{"__ignoreMap":25},[30,875,876],{},"static 메서드는 특정 객체 없이 실행될 수 있으므로 인스턴스 필드에 직접 접근할 수 없다.",[19,878,880],{"className":39,"code":879,"language":41,"meta":25,"style":25},"class Example {\n    private int instanceValue;\n    private static int classValue;\n\n    static void print() {\n        \u002F\u002F System.out.println(instanceValue); \u002F\u002F 오류\n        System.out.println(classValue);       \u002F\u002F 가능\n    }\n}\n",[27,881,882,887,892,897,901,906,914,919,923],{"__ignoreMap":25},[45,883,884],{"class":47,"line":48},[45,885,886],{},"class Example {\n",[45,888,889],{"class":47,"line":54},[45,890,891],{},"    private int instanceValue;\n",[45,893,894],{"class":47,"line":60},[45,895,896],{},"    private static int classValue;\n",[45,898,899],{"class":47,"line":66},[45,900,70],{"emptyLinePlaceholder":69},[45,902,903],{"class":47,"line":73},[45,904,905],{},"    static void print() {\n",[45,907,908,911],{"class":47,"line":79},[45,909,910],{},"        \u002F\u002F System.out.println(instanceValue);",[45,912,913],{}," \u002F\u002F 오류\n",[45,915,916],{"class":47,"line":85},[45,917,918],{},"        System.out.println(classValue);       \u002F\u002F 가능\n",[45,920,921],{"class":47,"line":91},[45,922,88],{},[45,924,925],{"class":47,"line":97},[45,926,94],{},[14,928,930,931,934],{"id":929},"_7-final-재대입과-변경-제한","7. ",[27,932,933],{},"final",": 재대입과 변경 제한",[30,936,937,939],{},[27,938,933],{},"은 대상에 따라 의미가 조금 다르다.",[19,941,943],{"className":39,"code":942,"language":41,"meta":25,"style":25},"final int age = 25;\n\u002F\u002F age = 30; \u002F\u002F 컴파일 오류\n",[27,944,945,950],{"__ignoreMap":25},[45,946,947],{"class":47,"line":48},[45,948,949],{},"final int age = 25;\n",[45,951,952,955],{"class":47,"line":54},[45,953,954],{},"\u002F\u002F age = 30;",[45,956,957],{}," \u002F\u002F 컴파일 오류\n",[122,959,960,970],{},[125,961,962],{},[128,963,964,967],{},[131,965,966],{},"적용 대상",[131,968,969],{},"의미",[138,971,972,980,988],{},[128,973,974,977],{},[143,975,976],{},"변수, 필드",[143,978,979],{},"값을 다시 대입할 수 없음",[128,981,982,985],{},[143,983,984],{},"클래스",[143,986,987],{},"다른 클래스가 상속할 수 없음",[128,989,990,993],{},[143,991,992],{},"메서드",[143,994,995],{},"자식 클래스가 오버라이드할 수 없음",[30,997,998,999,1001],{},"참조 변수에 ",[27,1000,933],{},"을 사용하면 참조 대상을 바꿀 수 없다는 뜻이다. 객체 내부 필드까지 모두 변경할 수 없다는 뜻은 아니다.",[19,1003,1005],{"className":39,"code":1004,"language":41,"meta":25,"style":25},"final User user = new User();\n\u002F\u002F user = new User(); \u002F\u002F 다른 객체를 다시 대입할 수 없음\nuser.name = \"민형\";    \u002F\u002F name이 final이 아니면 변경 가능\n",[27,1006,1007,1012,1020],{"__ignoreMap":25},[45,1008,1009],{"class":47,"line":48},[45,1010,1011],{},"final User user = new User();\n",[45,1013,1014,1017],{"class":47,"line":54},[45,1015,1016],{},"\u002F\u002F user = new User();",[45,1018,1019],{}," \u002F\u002F 다른 객체를 다시 대입할 수 없음\n",[45,1021,1022],{"class":47,"line":60},[45,1023,1024],{},"user.name = \"민형\";    \u002F\u002F name이 final이 아니면 변경 가능\n",[14,1026,1028],{"id":1027},"_8-접근-제어자와-캡슐화","8. 접근 제어자와 캡슐화",[213,1030,1032],{"id":1031},"접근-제어자access-modifier","접근 제어자(Access Modifier)",[30,1034,1035],{},"접근 제어자는 클래스, 필드, 메서드 등에 외부 코드가 접근할 수 있는 범위를 결정한다.",[122,1037,1038,1048],{},[125,1039,1040],{},[128,1041,1042,1045],{},[131,1043,1044],{},"접근 제어자",[131,1046,1047],{},"접근 범위",[138,1049,1050,1060,1070,1078],{},[128,1051,1052,1057],{},[143,1053,1054],{},[27,1055,1056],{},"public",[143,1058,1059],{},"어디서든 접근 가능",[128,1061,1062,1067],{},[143,1063,1064],{},[27,1065,1066],{},"protected",[143,1068,1069],{},"같은 패키지와 자식 클래스에서 접근 가능",[128,1071,1072,1075],{},[143,1073,1074],{},"기본 접근 제어자",[143,1076,1077],{},"같은 패키지에서만 접근 가능",[128,1079,1080,1085],{},[143,1081,1082],{},[27,1083,1084],{},"private",[143,1086,1087],{},"선언된 클래스 내부에서만 접근 가능",[213,1089,1091],{"id":1090},"캡슐화encapsulation","캡슐화(Encapsulation)",[30,1093,1094],{},"캡슐화는 객체 내부의 데이터를 외부에서 직접 변경하지 못하게 숨기고, 필요한 기능만 메서드로 공개하는 설계 방식이다.",[19,1096,1098],{"className":39,"code":1097,"language":41,"meta":25,"style":25},"class Account {\n    private int balance;\n\n    public void deposit(int money) {\n        if (money > 0) {\n            balance += money;\n        }\n    }\n\n    public int getBalance() {\n        return balance;\n    }\n}\n\nAccount account = new Account();\naccount.deposit(10000);\nSystem.out.println(account.getBalance());\n",[27,1099,1100,1105,1110,1114,1119,1124,1129,1134,1138,1142,1147,1152,1156,1160,1164,1169,1174],{"__ignoreMap":25},[45,1101,1102],{"class":47,"line":48},[45,1103,1104],{},"class Account {\n",[45,1106,1107],{"class":47,"line":54},[45,1108,1109],{},"    private int balance;\n",[45,1111,1112],{"class":47,"line":60},[45,1113,70],{"emptyLinePlaceholder":69},[45,1115,1116],{"class":47,"line":66},[45,1117,1118],{},"    public void deposit(int money) {\n",[45,1120,1121],{"class":47,"line":73},[45,1122,1123],{},"        if (money > 0) {\n",[45,1125,1126],{"class":47,"line":79},[45,1127,1128],{},"            balance += money;\n",[45,1130,1131],{"class":47,"line":85},[45,1132,1133],{},"        }\n",[45,1135,1136],{"class":47,"line":91},[45,1137,88],{},[45,1139,1140],{"class":47,"line":97},[45,1141,70],{"emptyLinePlaceholder":69},[45,1143,1144],{"class":47,"line":102},[45,1145,1146],{},"    public int getBalance() {\n",[45,1148,1149],{"class":47,"line":108},[45,1150,1151],{},"        return balance;\n",[45,1153,1154],{"class":47,"line":114},[45,1155,88],{},[45,1157,1158],{"class":47,"line":435},[45,1159,94],{},[45,1161,1162],{"class":47,"line":440},[45,1163,70],{"emptyLinePlaceholder":69},[45,1165,1166],{"class":47,"line":446},[45,1167,1168],{},"Account account = new Account();\n",[45,1170,1171],{"class":47,"line":452},[45,1172,1173],{},"account.deposit(10000);\n",[45,1175,1176],{"class":47,"line":457},[45,1177,1178],{},"System.out.println(account.getBalance());\n",[30,1180,1181,1182,1185,1186,1189],{},"외부 코드는 ",[27,1183,1184],{},"balance","를 직접 바꾸지 않고, 유효성 검사가 포함된 ",[27,1187,1188],{},"deposit()","을 통해서만 잔액을 변경한다.",[213,1191,1193],{"id":1192},"getter와-setter","Getter와 Setter",[468,1195,1196,1199],{},[471,1197,1198],{},"Getter: private 필드의 값을 반환하는 메서드",[471,1200,1201],{},"Setter: private 필드에 값을 대입하는 메서드",[19,1203,1205],{"className":39,"code":1204,"language":41,"meta":25,"style":25},"class User {\n    private String name;\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n}\n",[27,1206,1207,1211,1215,1219,1224,1229,1233,1237,1242,1246,1250],{"__ignoreMap":25},[45,1208,1209],{"class":47,"line":48},[45,1210,233],{},[45,1212,1213],{"class":47,"line":54},[45,1214,644],{},[45,1216,1217],{"class":47,"line":60},[45,1218,70],{"emptyLinePlaceholder":69},[45,1220,1221],{"class":47,"line":66},[45,1222,1223],{},"    public String getName() {\n",[45,1225,1226],{"class":47,"line":73},[45,1227,1228],{},"        return name;\n",[45,1230,1231],{"class":47,"line":79},[45,1232,88],{},[45,1234,1235],{"class":47,"line":85},[45,1236,70],{"emptyLinePlaceholder":69},[45,1238,1239],{"class":47,"line":91},[45,1240,1241],{},"    public void setName(String name) {\n",[45,1243,1244],{"class":47,"line":97},[45,1245,405],{},[45,1247,1248],{"class":47,"line":102},[45,1249,88],{},[45,1251,1252],{"class":47,"line":108},[45,1253,94],{},[30,1255,1256],{},"Getter와 Setter를 모든 필드에 무조건 만들 필요는 없다. 객체 설계에 따라 필요한 기능만 외부에 공개하는 것이 중요하다.",[14,1258,1260],{"id":1259},"_9-상속과-오버라이드","9. 상속과 오버라이드",[213,1262,1264],{"id":1263},"상속inheritance","상속(Inheritance)",[30,1266,1267],{},"상속은 기존 클래스의 필드와 메서드를 자식 클래스가 물려받는 기능이다.",[19,1269,1271],{"className":39,"code":1270,"language":41,"meta":25,"style":25},"class Animal {\n    public void eat() {\n        System.out.println(\"먹는다\");\n    }\n}\n\nclass Dog extends Animal {\n}\n\nDog dog = new Dog();\ndog.eat(); \u002F\u002F Animal에게서 물려받은 메서드\n",[27,1272,1273,1278,1283,1288,1292,1296,1300,1305,1309,1313,1318],{"__ignoreMap":25},[45,1274,1275],{"class":47,"line":48},[45,1276,1277],{},"class Animal {\n",[45,1279,1280],{"class":47,"line":54},[45,1281,1282],{},"    public void eat() {\n",[45,1284,1285],{"class":47,"line":60},[45,1286,1287],{},"        System.out.println(\"먹는다\");\n",[45,1289,1290],{"class":47,"line":66},[45,1291,88],{},[45,1293,1294],{"class":47,"line":73},[45,1295,94],{},[45,1297,1298],{"class":47,"line":79},[45,1299,70],{"emptyLinePlaceholder":69},[45,1301,1302],{"class":47,"line":85},[45,1303,1304],{},"class Dog extends Animal {\n",[45,1306,1307],{"class":47,"line":91},[45,1308,94],{},[45,1310,1311],{"class":47,"line":97},[45,1312,70],{"emptyLinePlaceholder":69},[45,1314,1315],{"class":47,"line":102},[45,1316,1317],{},"Dog dog = new Dog();\n",[45,1319,1320],{"class":47,"line":108},[45,1321,1322],{},"dog.eat(); \u002F\u002F Animal에게서 물려받은 메서드\n",[30,1324,1325],{},"Java 클래스는 부모 클래스를 하나만 직접 상속할 수 있다. 대신 하나의 클래스가 여러 인터페이스를 구현하는 것은 가능하다.",[213,1327,1329],{"id":1328},"오버라이드override","오버라이드(Override)",[30,1331,1332],{},"오버라이드는 부모 클래스에서 물려받은 메서드를 자식 클래스에서 같은 형태로 다시 정의하는 것이다.",[19,1334,1336],{"className":39,"code":1335,"language":41,"meta":25,"style":25},"class Animal {\n    public void sound() {\n        System.out.println(\"동물 소리\");\n    }\n}\n\nclass Dog extends Animal {\n    @Override\n    public void sound() {\n        System.out.println(\"멍멍\");\n    }\n}\n\nDog dog = new Dog();\ndog.sound(); \u002F\u002F 멍멍\n",[27,1337,1338,1342,1347,1352,1356,1360,1364,1368,1373,1377,1382,1386,1390,1394,1398],{"__ignoreMap":25},[45,1339,1340],{"class":47,"line":48},[45,1341,1277],{},[45,1343,1344],{"class":47,"line":54},[45,1345,1346],{},"    public void sound() {\n",[45,1348,1349],{"class":47,"line":60},[45,1350,1351],{},"        System.out.println(\"동물 소리\");\n",[45,1353,1354],{"class":47,"line":66},[45,1355,88],{},[45,1357,1358],{"class":47,"line":73},[45,1359,94],{},[45,1361,1362],{"class":47,"line":79},[45,1363,70],{"emptyLinePlaceholder":69},[45,1365,1366],{"class":47,"line":85},[45,1367,1304],{},[45,1369,1370],{"class":47,"line":91},[45,1371,1372],{},"    @Override\n",[45,1374,1375],{"class":47,"line":97},[45,1376,1346],{},[45,1378,1379],{"class":47,"line":102},[45,1380,1381],{},"        System.out.println(\"멍멍\");\n",[45,1383,1384],{"class":47,"line":108},[45,1385,88],{},[45,1387,1388],{"class":47,"line":114},[45,1389,94],{},[45,1391,1392],{"class":47,"line":435},[45,1393,70],{"emptyLinePlaceholder":69},[45,1395,1396],{"class":47,"line":440},[45,1397,1317],{},[45,1399,1400],{"class":47,"line":446},[45,1401,1402],{},"dog.sound(); \u002F\u002F 멍멍\n",[30,1404,1405,1408],{},[27,1406,1407],{},"@Override","는 부모 메서드를 재정의한다는 것을 컴파일러에 알려 주는 애너테이션이다. 메서드 이름이나 매개변수를 잘못 작성했을 때 오류를 확인하는 데 도움이 된다.",[213,1410,1412],{"id":1411},"오버로딩과-오버라이드-비교","오버로딩과 오버라이드 비교",[122,1414,1415,1427],{},[125,1416,1417],{},[128,1418,1419,1422,1425],{},[131,1420,1421],{},"구분",[131,1423,1424],{},"오버로딩(Overloading)",[131,1426,1329],{},[138,1428,1429,1440,1451,1462],{},[128,1430,1431,1434,1437],{},[143,1432,1433],{},"발생 위치",[143,1435,1436],{},"같은 클래스 안",[143,1438,1439],{},"부모와 자식 클래스 사이",[128,1441,1442,1445,1448],{},[143,1443,1444],{},"목적",[143,1446,1447],{},"같은 이름으로 다른 입력 처리",[143,1449,1450],{},"부모 동작을 자식에 맞게 변경",[128,1452,1453,1456,1459],{},[143,1454,1455],{},"매개변수",[143,1457,1458],{},"달라야 함",[143,1460,1461],{},"부모 메서드와 같아야 함",[128,1463,1464,1467,1470],{},[143,1465,1466],{},"표시",[143,1468,1469],{},"별도 키워드 없음",[143,1471,1472,1474],{},[27,1473,1407],{}," 사용 권장",[14,1476,1478],{"id":1477},"_10-핵심-용어-요약","10. 핵심 용어 요약",[122,1480,1481,1490],{},[125,1482,1483],{},[128,1484,1485,1487],{},[131,1486,133],{},[131,1488,1489],{},"한 줄 정의",[138,1491,1492,1500,1507,1514,1521,1528,1536,1543,1551,1560,1569,1578,1586,1594],{},[128,1493,1494,1497],{},[143,1495,1496],{},"OOP",[143,1498,1499],{},"객체를 중심으로 데이터와 동작을 묶어 설계하는 프로그래밍 방식",[128,1501,1502,1504],{},[143,1503,984],{},[143,1505,1506],{},"객체를 만들기 위한 설계도",[128,1508,1509,1511],{},[143,1510,35],{},[143,1512,1513],{},"실행 중 메모리에 만들어진 실체",[128,1515,1516,1518],{},[143,1517,285],{},[143,1519,1520],{},"특정 클래스에서 만들어진 객체",[128,1522,1523,1525],{},[143,1524,304],{},[143,1526,1527],{},"객체를 가리키는 참조값을 저장하는 변수",[128,1529,1530,1533],{},[143,1531,1532],{},"필드",[143,1534,1535],{},"객체의 상태를 저장하는 변수",[128,1537,1538,1540],{},[143,1539,992],{},[143,1541,1542],{},"객체의 동작을 정의하는 코드 블록",[128,1544,1545,1548],{},[143,1546,1547],{},"생성자",[143,1549,1550],{},"객체 생성 시 초기값을 설정하는 코드 블록",[128,1552,1553,1557],{},[143,1554,1555],{},[27,1556,620],{},[143,1558,1559],{},"현재 객체를 가리키는 참조",[128,1561,1562,1566],{},[143,1563,1564],{},[27,1565,486],{},[143,1567,1568],{},"클래스에 소속되어 객체들이 공유하는 멤버를 만드는 키워드",[128,1570,1571,1575],{},[143,1572,1573],{},[27,1574,933],{},[143,1576,1577],{},"재대입, 상속, 오버라이드를 제한하는 키워드",[128,1579,1580,1583],{},[143,1581,1582],{},"캡슐화",[143,1584,1585],{},"내부 데이터를 숨기고 필요한 기능만 공개하는 설계 방식",[128,1587,1588,1591],{},[143,1589,1590],{},"상속",[143,1592,1593],{},"부모 클래스의 기능을 자식 클래스가 물려받는 기능",[128,1595,1596,1599],{},[143,1597,1598],{},"오버라이드",[143,1600,1601],{},"부모 메서드를 자식 클래스에서 다시 정의하는 것",[14,1603,1605],{"id":1604},"마지막-한-번에-정리","마지막 한 번에 정리",[122,1607,1608,1621],{},[125,1609,1610],{},[128,1611,1612,1615,1618],{},[131,1613,1614],{},"체크 포인트",[131,1616,1617],{},"핵심 문장",[131,1619,1620],{},"외우기 포인트",[138,1622,1623,1635,1649,1663,1673,1688,1703,1715,1727,1740],{},[128,1624,1625,1627,1630],{},[143,1626,216],{},[143,1628,1629],{},"클래스는 설계도, 객체는 실행 중 만든 실체",[143,1631,1632,1634],{},[27,1633,222],{}," 뒤에만 객체가 생성됨",[128,1636,1637,1640,1643],{},[143,1638,1639],{},"인스턴스와 참조",[143,1641,1642],{},"변수는 참조값을 저장",[143,1644,1645,1648],{},[27,1646,1647],{},"a = b","는 객체 복사가 아니라 주소 공유",[128,1650,1651,1654,1657],{},[143,1652,1653],{},"필드와 메서드",[143,1655,1656],{},"필드는 상태, 메서드는 동작",[143,1658,1659,1660,1662],{},"필드는 ",[27,1661,486],{},"이면 공유, 아니면 객체별로 별도 생성",[128,1664,1665,1667,1670],{},[143,1666,1547],{},[143,1668,1669],{},"객체 생성 시점의 초기화 구문",[143,1671,1672],{},"반환형이 없고 클래스명과 동일",[128,1674,1675,1679,1682],{},[143,1676,1677],{},[27,1678,620],{},[143,1680,1681],{},"현재 객체 자신을 가리킴",[143,1683,1684,1687],{},[27,1685,1686],{},"this.name = name","은 필드\u002F매개변수 구분용",[128,1689,1690,1694,1697],{},[143,1691,1692],{},[27,1693,486],{},[143,1695,1696],{},"클래스 소유 멤버",[143,1698,1699,1702],{},[27,1700,1701],{},"ClassName.메서드()","로 호출 가능",[128,1704,1705,1709,1712],{},[143,1706,1707],{},[27,1708,933],{},[143,1710,1711],{},"변경 제한 키워드",[143,1713,1714],{},"변수는 재할당 금지, 클래스\u002F메서드는 상속·오버라이드 제한",[128,1716,1717,1719,1722],{},[143,1718,1044],{},[143,1720,1721],{},"외부 접근 범위 제어",[143,1723,1724,1726],{},[27,1725,1084],{}," + getter\u002Fsetter 조합으로 캡슐화",[128,1728,1729,1732,1735],{},[143,1730,1731],{},"상속\u002F오버라이드",[143,1733,1734],{},"기능 재사용과 동작 변경",[143,1736,1737,1738],{},"오버라이드는 이름·매개변수 동일 + ",[27,1739,1407],{},[128,1741,1742,1745,1748],{},[143,1743,1744],{},"오버로딩\u002F오버라이드",[143,1746,1747],{},"이름은 같아도 다른 용도",[143,1749,1750],{},"오버로딩은 매개변수\u002F시그니처 다름",[1752,1753,1754],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":25,"searchDepth":54,"depth":54,"links":1756},[1757],{"id":12,"depth":54,"text":5,"children":1758},[1759,1760,1761,1762,1764,1765,1767,1769,1770,1771,1772],{"id":16,"depth":60,"text":17},{"id":210,"depth":60,"text":211},{"id":364,"depth":60,"text":365},{"id":616,"depth":60,"text":1763},"4. this, 매개변수, 인자",{"id":735,"depth":60,"text":736},{"id":781,"depth":60,"text":1766},"6. static: 클래스에 소속된 멤버",{"id":929,"depth":60,"text":1768},"7. final: 재대입과 변경 제한",{"id":1027,"depth":60,"text":1028},{"id":1259,"depth":60,"text":1260},{"id":1477,"depth":60,"text":1478},{"id":1604,"depth":60,"text":1605},[41,1774],"oop","2026-08-10 12:00:00 +0900","참조 변수, 멤버, static, final, 접근 제어자, 캡슐화, 상속과 오버라이드를 코드로 정리한다.","md",null,"\u002Fjava\u002Foop\u002F2026\u002F08\u002F10\u002Fjava-oop-concepts\u002F",{"layout":1781},"post","2","\u002Fposts\u002Fbackend\u002Fjava\u002Foop\u002F2026-08-10-java-oop-concepts",{"title":5,"description":1776},"Java 객체지향","posts\u002FBackend\u002FJAVA\u002Foop\u002F2026-08-10-java-oop-concepts",[1788,1496,148,160,171,182,193,204,1789,1790,1791,1792],"Java","Static","Encapsulation","Inheritance","Override","0TJHVMHJTriTElNh-xjvrVA86CBszPAmlfbHJyTz9X4",1788744784970]