[{"data":1,"prerenderedAt":1153},["ShallowReactive",2],{"blog-\u002Fblog\u002Fjava-oop-inheritance-polymorphism-encapsulation":3},{"id":4,"title":5,"body":6,"description":1139,"difficulty":1140,"extension":1141,"framework":1142,"frameworkSlug":81,"meta":1143,"navigation":573,"order":104,"path":1144,"qaPath":1145,"seo":1146,"stem":1147,"subtopic":1148,"topic":1149,"topicSlug":1150,"updated":1151,"__hash__":1152},"blog\u002Fblog\u002Fjava-oop-inheritance-polymorphism-encapsulation.md","Java OOP — Inheritance, Polymorphism, Abstraction & Encapsulation",{"type":7,"value":8,"toc":1128},"minimark",[9,14,32,36,76,201,204,208,226,247,337,370,374,416,502,520,524,531,680,690,694,715,783,790,794,810,929,942,946,986,1071,1082,1086,1124],[10,11,13],"h2",{"id":12},"object-oriented-programming-in-java","Object-oriented programming in Java",[15,16,17,18,22,23,27,28,31],"p",{},"Java is an object-oriented language to its core, and OOP questions dominate Java\ninterviews. Beyond reciting \"the four pillars,\" what matters is understanding ",[19,20,21],"em",{},"how"," the\nmechanisms work — dynamic dispatch, the ",[24,25,26],"code",{},"equals","\u002F",[24,29,30],{},"hashCode"," contract, why composition\noften beats inheritance, and where interfaces fit. This guide walks through the model and\nthe design judgment that goes with it.",[10,33,35],{"id":34},"the-four-pillars","The four pillars",[37,38,39,47,60,70],"ul",{},[40,41,42,46],"li",{},[43,44,45],"strong",{},"Encapsulation"," — bundle data with the methods that operate on it and hide state\nbehind a public API (private fields + methods).",[40,48,49,52,53,56,57,59],{},[43,50,51],{},"Abstraction"," — expose ",[19,54,55],{},"what"," an object does, hide ",[19,58,21],{},", via interfaces and abstract\nclasses.",[40,61,62,65,66,69],{},[43,63,64],{},"Inheritance"," — a subclass reuses and extends a superclass (",[24,67,68],{},"extends",").",[40,71,72,75],{},[43,73,74],{},"Polymorphism"," — one reference type, many runtime forms.",[77,78,83],"pre",{"className":79,"code":80,"language":81,"meta":82,"style":82},"language-java shiki shiki-themes github-light github-dark","class Account {\n  private double balance;           \u002F\u002F encapsulated state\n  public void deposit(double amt) {\n    if (amt \u003C= 0) throw new IllegalArgumentException();\n    balance += amt;                 \u002F\u002F validated in one place\n  }\n}\n","java","",[24,84,85,102,118,143,174,189,195],{"__ignoreMap":82},[86,87,90,94,98],"span",{"class":88,"line":89},"line",1,[86,91,93],{"class":92},"szBVR","class",[86,95,97],{"class":96},"sScJk"," Account",[86,99,101],{"class":100},"sVt8B"," {\n",[86,103,105,108,111,114],{"class":88,"line":104},2,[86,106,107],{"class":92},"  private",[86,109,110],{"class":92}," double",[86,112,113],{"class":100}," balance;           ",[86,115,117],{"class":116},"sJ8bj","\u002F\u002F encapsulated state\n",[86,119,121,124,127,130,133,136,140],{"class":88,"line":120},3,[86,122,123],{"class":92},"  public",[86,125,126],{"class":92}," void",[86,128,129],{"class":96}," deposit",[86,131,132],{"class":100},"(",[86,134,135],{"class":92},"double",[86,137,139],{"class":138},"s4XuR"," amt",[86,141,142],{"class":100},") {\n",[86,144,146,149,152,155,159,162,165,168,171],{"class":88,"line":145},4,[86,147,148],{"class":92},"    if",[86,150,151],{"class":100}," (amt ",[86,153,154],{"class":92},"\u003C=",[86,156,158],{"class":157},"sj4cs"," 0",[86,160,161],{"class":100},") ",[86,163,164],{"class":92},"throw",[86,166,167],{"class":92}," new",[86,169,170],{"class":96}," IllegalArgumentException",[86,172,173],{"class":100},"();\n",[86,175,177,180,183,186],{"class":88,"line":176},5,[86,178,179],{"class":100},"    balance ",[86,181,182],{"class":92},"+=",[86,184,185],{"class":100}," amt;                 ",[86,187,188],{"class":116},"\u002F\u002F validated in one place\n",[86,190,192],{"class":88,"line":191},6,[86,193,194],{"class":100},"  }\n",[86,196,198],{"class":88,"line":197},7,[86,199,200],{"class":100},"}\n",[15,202,203],{},"Encapsulation lets you change internals without breaking callers; a public mutable field\ngives that up.",[10,205,207],{"id":206},"inheritance-and-polymorphism","Inheritance and polymorphism",[15,209,210,211,214,215,217,218,221,222,225],{},"Inheritance models an ",[43,212,213],{},"is-a"," relationship with ",[24,216,68],{},". Java allows ",[43,219,220],{},"single"," class\ninheritance (to avoid the diamond problem) but a class can implement ",[43,223,224],{},"many interfaces",".\nPolymorphism comes in two forms:",[37,227,228,238],{},[40,229,230,233,234,237],{},[43,231,232],{},"Runtime (dynamic)"," — method ",[43,235,236],{},"overriding","; the JVM calls the actual object's method\nvia dynamic dispatch.",[40,239,240,233,243,246],{},[43,241,242],{},"Compile-time (static)",[43,244,245],{},"overloading","; the compiler picks by argument\ntypes.",[77,248,250],{"className":79,"code":249,"language":81,"meta":82,"style":82},"class Animal { String sound() { return \"...\"; } }\nclass Dog extends Animal { @Override String sound() { return \"Woof\"; } }\nAnimal a = new Dog();\na.sound(); \u002F\u002F \"Woof\" — resolved at runtime by the real object\n",[24,251,252,278,310,324],{"__ignoreMap":82},[86,253,254,256,259,262,265,268,271,275],{"class":88,"line":89},[86,255,93],{"class":92},[86,257,258],{"class":96}," Animal",[86,260,261],{"class":100}," { String ",[86,263,264],{"class":96},"sound",[86,266,267],{"class":100},"() { ",[86,269,270],{"class":92},"return",[86,272,274],{"class":273},"sZZnC"," \"...\"",[86,276,277],{"class":100},"; } }\n",[86,279,280,282,285,288,290,293,296,299,301,303,305,308],{"class":88,"line":104},[86,281,93],{"class":92},[86,283,284],{"class":96}," Dog",[86,286,287],{"class":92}," extends",[86,289,258],{"class":96},[86,291,292],{"class":100}," { @",[86,294,295],{"class":92},"Override",[86,297,298],{"class":100}," String ",[86,300,264],{"class":96},[86,302,267],{"class":100},[86,304,270],{"class":92},[86,306,307],{"class":273}," \"Woof\"",[86,309,277],{"class":100},[86,311,312,315,318,320,322],{"class":88,"line":120},[86,313,314],{"class":100},"Animal a ",[86,316,317],{"class":92},"=",[86,319,167],{"class":92},[86,321,284],{"class":96},[86,323,173],{"class":100},[86,325,326,329,331,334],{"class":88,"line":145},[86,327,328],{"class":100},"a.",[86,330,264],{"class":96},[86,332,333],{"class":100},"(); ",[86,335,336],{"class":116},"\u002F\u002F \"Woof\" — resolved at runtime by the real object\n",[15,338,339,342,343,345,346,349,350,361,362,365,366,369],{},[43,340,341],{},"Overriding"," replaces an inherited method (same signature, dynamic); ",[43,344,245],{},"\noffers variations with different parameters (resolved at compile time). Use ",[24,347,348],{},"@Override","\nso the compiler verifies you actually overrode. A subtle point: ",[43,351,352,353,356,357,360],{},"fields and ",[24,354,355],{},"static","\nmethods are ",[19,358,359],{},"hidden",", not overridden"," — they bind to the declared type, so\n",[24,363,364],{},"A x = new B(); x.staticMethod()"," calls ",[24,367,368],{},"A","'s version.",[10,371,373],{"id":372},"abstraction-interfaces-vs-abstract-classes","Abstraction: interfaces vs abstract classes",[37,375,376,386],{},[40,377,378,381,382,385],{},[43,379,380],{},"Abstract class"," — can have state, constructors, and a mix of concrete and abstract\nmethods; a class extends ",[43,383,384],{},"one",". Use for a family of classes sharing implementation.",[40,387,388,391,392,27,395,27,397,400,401,404,405,408,409,412,413,69],{},[43,389,390],{},"Interface"," — a contract; now allows ",[24,393,394],{},"default",[24,396,355],{},[24,398,399],{},"private"," methods but ",[43,402,403],{},"no\ninstance state","; a class implements ",[43,406,407],{},"many",". Use for a capability unrelated classes\ncan share (",[24,410,411],{},"Comparable",", ",[24,414,415],{},"Runnable",[77,417,419],{"className":79,"code":418,"language":81,"meta":82,"style":82},"interface Drawable { void draw(); default void hide() {} }\nabstract class Shape {\n  abstract double area();\n  String describe() { return \"area=\" + area(); }\n}\n",[24,420,421,450,463,475,498],{"__ignoreMap":82},[86,422,423,426,429,432,435,438,440,442,444,447],{"class":88,"line":89},[86,424,425],{"class":92},"interface",[86,427,428],{"class":96}," Drawable",[86,430,431],{"class":100}," { ",[86,433,434],{"class":92},"void",[86,436,437],{"class":96}," draw",[86,439,333],{"class":100},[86,441,394],{"class":92},[86,443,126],{"class":92},[86,445,446],{"class":96}," hide",[86,448,449],{"class":100},"() {} }\n",[86,451,452,455,458,461],{"class":88,"line":104},[86,453,454],{"class":92},"abstract",[86,456,457],{"class":92}," class",[86,459,460],{"class":96}," Shape",[86,462,101],{"class":100},[86,464,465,468,470,473],{"class":88,"line":120},[86,466,467],{"class":92},"  abstract",[86,469,110],{"class":92},[86,471,472],{"class":96}," area",[86,474,173],{"class":100},[86,476,477,480,483,485,487,490,493,495],{"class":88,"line":145},[86,478,479],{"class":100},"  String ",[86,481,482],{"class":96},"describe",[86,484,267],{"class":100},[86,486,270],{"class":92},[86,488,489],{"class":273}," \"area=\"",[86,491,492],{"class":92}," +",[86,494,472],{"class":96},[86,496,497],{"class":100},"(); }\n",[86,499,500],{"class":88,"line":176},[86,501,200],{"class":100},[15,503,504,507,508,511,512,515,516,519],{},[43,505,506],{},"Default methods"," (Java 8) let interfaces evolve without breaking implementers; if two\ninterfaces give conflicting defaults, the class must override and can call\n",[24,509,510],{},"Interface.super.method()",". This is Java's controlled answer to multiple inheritance:\nmultiple ",[19,513,514],{},"types"," are fine, conflicting ",[19,517,518],{},"behavior"," must be resolved explicitly.",[10,521,523],{"id":522},"composition-over-inheritance","Composition over inheritance",[15,525,526,527,530],{},"Inheritance tightly couples a subclass to its parent's implementation (the \"fragile base\nclass\" problem). ",[43,528,529],{},"Composition"," — building behavior by holding other objects and\ndelegating — is looser and more flexible.",[77,532,534],{"className":79,"code":533,"language":81,"meta":82,"style":82},"\u002F\u002F inheritance misused: a Stack is-a List? leaks all List methods\nclass Stack\u003CT> extends ArrayList\u003CT> {}\n\n\u002F\u002F composition: Stack HAS a list, exposes only stack operations\nclass Stack\u003CT> {\n  private final List\u003CT> items = new ArrayList\u003C>();\n  void push(T t) { items.add(t); }\n  T pop() { return items.remove(items.size() - 1); }\n}\n",[24,535,536,541,569,575,580,593,615,638,675],{"__ignoreMap":82},[86,537,538],{"class":88,"line":89},[86,539,540],{"class":116},"\u002F\u002F inheritance misused: a Stack is-a List? leaks all List methods\n",[86,542,543,545,548,551,554,557,559,562,564,566],{"class":88,"line":104},[86,544,93],{"class":92},[86,546,547],{"class":96}," Stack",[86,549,550],{"class":100},"\u003C",[86,552,553],{"class":92},"T",[86,555,556],{"class":100},"> ",[86,558,68],{"class":92},[86,560,561],{"class":96}," ArrayList",[86,563,550],{"class":100},[86,565,553],{"class":92},[86,567,568],{"class":100},"> {}\n",[86,570,571],{"class":88,"line":120},[86,572,574],{"emptyLinePlaceholder":573},true,"\n",[86,576,577],{"class":88,"line":145},[86,578,579],{"class":116},"\u002F\u002F composition: Stack HAS a list, exposes only stack operations\n",[86,581,582,584,586,588,590],{"class":88,"line":176},[86,583,93],{"class":92},[86,585,547],{"class":96},[86,587,550],{"class":100},[86,589,553],{"class":92},[86,591,592],{"class":100},"> {\n",[86,594,595,597,600,603,605,608,610,612],{"class":88,"line":191},[86,596,107],{"class":92},[86,598,599],{"class":92}," final",[86,601,602],{"class":100}," List\u003C",[86,604,553],{"class":92},[86,606,607],{"class":100},"> items ",[86,609,317],{"class":92},[86,611,167],{"class":92},[86,613,614],{"class":100}," ArrayList\u003C>();\n",[86,616,617,620,623,626,629,632,635],{"class":88,"line":197},[86,618,619],{"class":92},"  void",[86,621,622],{"class":96}," push",[86,624,625],{"class":100},"(T ",[86,627,628],{"class":138},"t",[86,630,631],{"class":100},") { items.",[86,633,634],{"class":96},"add",[86,636,637],{"class":100},"(t); }\n",[86,639,641,644,647,649,651,654,657,660,663,666,669,672],{"class":88,"line":640},8,[86,642,643],{"class":100},"  T ",[86,645,646],{"class":96},"pop",[86,648,267],{"class":100},[86,650,270],{"class":92},[86,652,653],{"class":100}," items.",[86,655,656],{"class":96},"remove",[86,658,659],{"class":100},"(items.",[86,661,662],{"class":96},"size",[86,664,665],{"class":100},"() ",[86,667,668],{"class":92},"-",[86,670,671],{"class":157}," 1",[86,673,674],{"class":100},"); }\n",[86,676,678],{"class":88,"line":677},9,[86,679,200],{"class":100},[15,681,682,683,685,686,689],{},"Guideline: use inheritance only for a genuine ",[43,684,213],{}," with a base designed for\nextension; otherwise ",[43,687,688],{},"compose"," (has-a). This also sidesteps the single-inheritance\nlimit.",[10,691,693],{"id":692},"constructors-super-and-this","Constructors, super, and this",[15,695,696,697,700,701,704,705,707,708,710,711,714],{},"A constructor initializes an object: same name as the class, no return type. Defining any\nconstructor removes the free default one; constructors aren't inherited but a subclass\nmust call one via ",[24,698,699],{},"super(...)",". ",[24,702,703],{},"this(...)"," chains to another constructor in the same\nclass; both ",[24,706,699],{}," and ",[24,709,703],{}," must be the ",[43,712,713],{},"first statement",", so you use at\nmost one.",[77,716,718],{"className":79,"code":717,"language":81,"meta":82,"style":82},"class Sub extends Base {\n  Sub() { this(5); }       \u002F\u002F delegate within Sub...\n  Sub(int n) { super(n); } \u002F\u002F ...which reaches super\n}\n",[24,719,720,734,755,779],{"__ignoreMap":82},[86,721,722,724,727,729,732],{"class":88,"line":89},[86,723,93],{"class":92},[86,725,726],{"class":96}," Sub",[86,728,287],{"class":92},[86,730,731],{"class":96}," Base",[86,733,101],{"class":100},[86,735,736,739,741,744,746,749,752],{"class":88,"line":104},[86,737,738],{"class":96},"  Sub",[86,740,267],{"class":100},[86,742,743],{"class":157},"this",[86,745,132],{"class":100},[86,747,748],{"class":157},"5",[86,750,751],{"class":100},"); }       ",[86,753,754],{"class":116},"\u002F\u002F delegate within Sub...\n",[86,756,757,759,761,764,767,770,773,776],{"class":88,"line":120},[86,758,738],{"class":96},[86,760,132],{"class":100},[86,762,763],{"class":92},"int",[86,765,766],{"class":138}," n",[86,768,769],{"class":100},") { ",[86,771,772],{"class":157},"super",[86,774,775],{"class":100},"(n); } ",[86,777,778],{"class":116},"\u002F\u002F ...which reaches super\n",[86,780,781],{"class":88,"line":145},[86,782,200],{"class":100},[15,784,785,786,789],{},"Construction runs top-down: static initializers once at class load, then the superclass\nconstructor, then instance field initializers, then the subclass constructor body. A\nclassic trap: calling an overridable method from a constructor runs the subclass override\n",[19,787,788],{},"before"," its fields are initialized.",[10,791,793],{"id":792},"the-equalshashcode-contract","The equals\u002FhashCode contract",[15,795,796,797,799,800,803,804,806,807,809],{},"If you override ",[24,798,26],{},", you ",[43,801,802],{},"must"," override ",[24,805,30],{},", keeping them consistent: equal\nobjects must have equal hash codes (and ",[24,808,26],{}," must be reflexive, symmetric,\ntransitive, consistent).",[77,811,813],{"className":79,"code":812,"language":81,"meta":82,"style":82},"class Point {\n  final int x, y;\n  @Override public boolean equals(Object o) {\n    return o instanceof Point p && x == p.x && y == p.y;\n  }\n  @Override public int hashCode() { return Objects.hash(x, y); }\n}\n",[24,814,815,824,835,859,895,899,925],{"__ignoreMap":82},[86,816,817,819,822],{"class":88,"line":89},[86,818,93],{"class":92},[86,820,821],{"class":96}," Point",[86,823,101],{"class":100},[86,825,826,829,832],{"class":88,"line":104},[86,827,828],{"class":92},"  final",[86,830,831],{"class":92}," int",[86,833,834],{"class":100}," x, y;\n",[86,836,837,840,842,845,848,851,854,857],{"class":88,"line":120},[86,838,839],{"class":100},"  @",[86,841,295],{"class":92},[86,843,844],{"class":92}," public",[86,846,847],{"class":92}," boolean",[86,849,850],{"class":96}," equals",[86,852,853],{"class":100},"(Object ",[86,855,856],{"class":138},"o",[86,858,142],{"class":100},[86,860,861,864,867,870,873,876,879,882,885,887,890,892],{"class":88,"line":145},[86,862,863],{"class":92},"    return",[86,865,866],{"class":100}," o ",[86,868,869],{"class":92},"instanceof",[86,871,872],{"class":100}," Point p ",[86,874,875],{"class":92},"&&",[86,877,878],{"class":100}," x ",[86,880,881],{"class":92},"==",[86,883,884],{"class":100}," p.x ",[86,886,875],{"class":92},[86,888,889],{"class":100}," y ",[86,891,881],{"class":92},[86,893,894],{"class":100}," p.y;\n",[86,896,897],{"class":88,"line":176},[86,898,194],{"class":100},[86,900,901,903,905,907,909,912,914,916,919,922],{"class":88,"line":191},[86,902,839],{"class":100},[86,904,295],{"class":92},[86,906,844],{"class":92},[86,908,831],{"class":92},[86,910,911],{"class":96}," hashCode",[86,913,267],{"class":100},[86,915,270],{"class":92},[86,917,918],{"class":100}," Objects.",[86,920,921],{"class":96},"hash",[86,923,924],{"class":100},"(x, y); }\n",[86,926,927],{"class":88,"line":197},[86,928,200],{"class":100},[15,930,931,932,935,936,938,939,941],{},"Break the contract and hash-based collections silently misbehave — a ",[24,933,934],{},"HashMap"," may fail\nto find an object whose ",[24,937,30],{}," doesn't match its ",[24,940,26],{},". Base both on the same\nimmutable fields.",[10,943,945],{"id":944},"modern-oop-features","Modern OOP features",[37,947,948,964,972],{},[40,949,950,955,956,27,958,27,960,963],{},[43,951,952],{},[24,953,954],{},"record"," (Java 16+) — a concise, immutable data carrier that generates the\nconstructor, accessors, ",[24,957,26],{},[24,959,30],{},[24,961,962],{},"toString",".",[40,965,966,971],{},[43,967,968],{},[24,969,970],{},"enum"," — a type-safe fixed set of instances that can carry fields and methods.",[40,973,974,977,978,981,982,985],{},[43,975,976],{},"Immutable classes"," — make the class ",[24,979,980],{},"final",", fields ",[24,983,984],{},"private final",", set in the\nconstructor, no setters, and defensively copy mutable fields.",[77,987,989],{"className":79,"code":988,"language":81,"meta":82,"style":82},"record Point(int x, int y) {}\nenum Planet { EARTH(9.81), MARS(3.71);\n  final double g; Planet(double g) { this.g = g; } }\n",[24,990,991,1009,1040],{"__ignoreMap":82},[86,992,993,995,997,999,1001,1004,1006],{"class":88,"line":89},[86,994,954],{"class":92},[86,996,821],{"class":96},[86,998,132],{"class":100},[86,1000,763],{"class":92},[86,1002,1003],{"class":100}," x, ",[86,1005,763],{"class":92},[86,1007,1008],{"class":100}," y) {}\n",[86,1010,1011,1013,1016,1018,1021,1023,1026,1029,1032,1034,1037],{"class":88,"line":104},[86,1012,970],{"class":92},[86,1014,1015],{"class":96}," Planet",[86,1017,431],{"class":100},[86,1019,1020],{"class":157},"EARTH",[86,1022,132],{"class":100},[86,1024,1025],{"class":157},"9.81",[86,1027,1028],{"class":100},"), ",[86,1030,1031],{"class":157},"MARS",[86,1033,132],{"class":100},[86,1035,1036],{"class":157},"3.71",[86,1038,1039],{"class":100},");\n",[86,1041,1042,1044,1046,1049,1052,1054,1056,1059,1061,1063,1066,1068],{"class":88,"line":120},[86,1043,828],{"class":92},[86,1045,110],{"class":92},[86,1047,1048],{"class":100}," g; ",[86,1050,1051],{"class":96},"Planet",[86,1053,132],{"class":100},[86,1055,135],{"class":92},[86,1057,1058],{"class":138}," g",[86,1060,769],{"class":100},[86,1062,743],{"class":157},[86,1064,1065],{"class":100},".g ",[86,1067,317],{"class":92},[86,1069,1070],{"class":100}," g; } }\n",[15,1072,1073,1074,1077,1078,1081],{},"Round it out with the ",[43,1075,1076],{},"SOLID"," principles — Single Responsibility, Open\u002FClosed, Liskov\nSubstitution, Interface Segregation, Dependency Inversion — and aim for ",[43,1079,1080],{},"high cohesion,\nlow coupling",": classes that do one thing well and depend on abstractions, not\nconcretions.",[10,1083,1085],{"id":1084},"recap","Recap",[15,1087,1088,1089,1092,1093,1096,1097,1100,1101,1108,1109,1112,1113,27,1115,1117,1118,1120,1121,1123],{},"OOP in Java rests on ",[43,1090,1091],{},"encapsulation, abstraction, inheritance, and polymorphism"," —\nbut the depth is in the mechanics: ",[43,1094,1095],{},"dynamic dispatch"," for overriding (vs hidden fields\nand statics), ",[43,1098,1099],{},"interfaces vs abstract classes"," for abstraction, and the\n",[43,1102,1103,27,1105,1107],{},[24,1104,26],{},[24,1106,30],{}," contract"," for collections. Favor ",[43,1110,1111],{},"composition over inheritance",",\nchain constructors with ",[24,1114,743],{},[24,1116,772],{},", and reach for ",[24,1119,954],{},"s, ",[24,1122,970],{},"s, and immutable\ndesigns. Guided by SOLID and \"high cohesion, low coupling,\" your Java designs stay\nflexible and correct.",[1125,1126,1127],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":82,"searchDepth":104,"depth":104,"links":1129},[1130,1131,1132,1133,1134,1135,1136,1137,1138],{"id":12,"depth":104,"text":13},{"id":34,"depth":104,"text":35},{"id":206,"depth":104,"text":207},{"id":372,"depth":104,"text":373},{"id":522,"depth":104,"text":523},{"id":692,"depth":104,"text":693},{"id":792,"depth":104,"text":793},{"id":944,"depth":104,"text":945},{"id":1084,"depth":104,"text":1085},"Java OOP interview questions — the four pillars, inheritance vs composition, abstract classes vs interfaces, overloading vs overriding, polymorphism, the equals\u002FhashCode contract, records and enums.","medium","md","Java",{},"\u002Fblog\u002Fjava-oop-inheritance-polymorphism-encapsulation","\u002Fjava\u002Ffundamentals\u002Foop",{"title":5,"description":1139},"blog\u002Fjava-oop-inheritance-polymorphism-encapsulation","Object-Oriented Programming","Fundamentals","fundamentals","2026-06-18","lMMq6Bdoq6Cx8ZUzIUCrHydX6b0ewWSGIhZKvi5K4dg",1781808673081]