[{"data":1,"prerenderedAt":3317},["ShallowReactive",2],{"navigation_docs":3,"-tu-hoc-oop-4-tinh-chat":420,"-tu-hoc-oop-4-tinh-chat-surround":3312},[4,153],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Phỏng vấn .NET","i-lucide-briefcase","\u002Fphong-van","1.phong-van",[10,27,66,111,128],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":26},"Tổng quan","i-lucide-compass","\u002Fphong-van\u002Ftong-quan","1.phong-van\u002F1.tong-quan",[16,21],{"title":17,"path":18,"stem":19,"icon":20},"Thị trường HCM","\u002Fphong-van\u002Ftong-quan\u002Fthi-truong","1.phong-van\u002F1.tong-quan\u002F1.thi-truong","i-lucide-trending-up",{"title":22,"path":23,"stem":24,"icon":25},"Lộ trình 7 ngày","\u002Fphong-van\u002Ftong-quan\u002Flo-trinh","1.phong-van\u002F1.tong-quan\u002F2.lo-trinh","i-lucide-calendar-days",false,{"title":22,"icon":25,"path":28,"stem":29,"children":30,"page":26},"\u002Fphong-van\u002Flo-trinh","1.phong-van\u002F2.lo-trinh",[31,36,41,46,51,56,61],{"title":32,"path":33,"stem":34,"icon":35},"Ngày 1 — C# cơ bản","\u002Fphong-van\u002Flo-trinh\u002Fngay-1-csharp-co-ban","1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban","i-lucide-1",{"title":37,"path":38,"stem":39,"icon":40},"Ngày 2 — OOP và SOLID","\u002Fphong-van\u002Flo-trinh\u002Fngay-2-oop-solid","1.phong-van\u002F2.lo-trinh\u002F2.ngay-2-oop-solid","i-lucide-2",{"title":42,"path":43,"stem":44,"icon":45},"Ngày 3 — C# nâng cao","\u002Fphong-van\u002Flo-trinh\u002Fngay-3-csharp-nang-cao","1.phong-van\u002F2.lo-trinh\u002F3.ngay-3-csharp-nang-cao","i-lucide-3",{"title":47,"path":48,"stem":49,"icon":50},"Ngày 4 — Database và SQL","\u002Fphong-van\u002Flo-trinh\u002Fngay-4-database-sql","1.phong-van\u002F2.lo-trinh\u002F4.ngay-4-database-sql","i-lucide-4",{"title":52,"path":53,"stem":54,"icon":55},"Ngày 5 — ASP.NET Core và EF Core","\u002Fphong-van\u002Flo-trinh\u002Fngay-5-aspnet-efcore","1.phong-van\u002F2.lo-trinh\u002F5.ngay-5-aspnet-efcore","i-lucide-5",{"title":57,"path":58,"stem":59,"icon":60},"Ngày 6 — DSA coding","\u002Fphong-van\u002Flo-trinh\u002Fngay-6-dsa","1.phong-van\u002F2.lo-trinh\u002F6.ngay-6-dsa","i-lucide-6",{"title":62,"path":63,"stem":64,"icon":65},"Ngày 7 — Mock và HR","\u002Fphong-van\u002Flo-trinh\u002Fngay-7-mock-interview","1.phong-van\u002F2.lo-trinh\u002F7.ngay-7-mock-interview","i-lucide-7",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":26},"Ngân hàng câu hỏi","i-lucide-database","\u002Fphong-van\u002Fngan-hang-cau-hoi","1.phong-van\u002F3.ngan-hang-cau-hoi",[72,77,82,87,92,97,102,107],{"title":73,"path":74,"stem":75,"icon":76},"C# (60+ câu)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fcsharp","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F1.csharp","i-lucide-hash",{"title":78,"path":79,"stem":80,"icon":81},"OOP và SOLID (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Foop","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F2.oop","i-lucide-shapes",{"title":83,"path":84,"stem":85,"icon":86},"SQL (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fsql","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F3.sql","i-lucide-database-zap",{"title":88,"path":89,"stem":90,"icon":91},"ASP.NET và EF (50+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-ef","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F4.aspnet-ef","i-lucide-server",{"title":93,"path":94,"stem":95,"icon":96},"DSA và Coding (30+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdsa-coding","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F5.dsa-coding","i-lucide-binary",{"title":98,"path":99,"stem":100,"icon":101},"HR và Soft skill (25+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fhr-behavior","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F6.hr-behavior","i-lucide-users",{"title":103,"path":104,"stem":105,"icon":106},"Design Pattern (55+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdesign-pattern","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern","i-lucide-puzzle",{"title":108,"path":109,"stem":110,"icon":91},"ASP.NET MVC và Web API","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-mvc-webapi","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F8.aspnet-mvc-webapi",{"title":112,"itle":113,"icon":114,"path":115,"stem":116,"children":117,"page":26},"Tai Lieu","Tài liệu và Cheat sheet","i-lucide-book-marked","\u002Fphong-van\u002Ftai-lieu","1.phong-van\u002F4.tai-lieu",[118,123],{"title":119,"path":120,"stem":121,"icon":122},"Cheat Sheet","\u002Fphong-van\u002Ftai-lieu\u002Fcheatsheet","1.phong-van\u002F4.tai-lieu\u002F1.cheatsheet","i-lucide-clipboard-list",{"title":124,"path":125,"stem":126,"icon":127},"Nguồn tham khảo","\u002Fphong-van\u002Ftai-lieu\u002Fnguon","1.phong-van\u002F4.tai-lieu\u002F2.nguon","i-lucide-link",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":26},"Phỏng vấn English","i-lucide-globe","\u002Fphong-van\u002Fenglish-interview","1.phong-van\u002F5.english-interview",[134,138,143,148],{"title":135,"path":136,"stem":137,"icon":130},"Tổng quan English","\u002Fphong-van\u002Fenglish-interview\u002Ftong-quan","1.phong-van\u002F5.english-interview\u002F1.tong-quan",{"title":139,"path":140,"stem":141,"icon":142},"Vocabulary","\u002Fphong-van\u002Fenglish-interview\u002Fvocabulary","1.phong-van\u002F5.english-interview\u002F2.vocabulary","i-lucide-book-a",{"title":144,"path":145,"stem":146,"icon":147},"Technical Q và A (EN)","\u002Fphong-van\u002Fenglish-interview\u002Ftechnical-en","1.phong-van\u002F5.english-interview\u002F3.technical-en","i-lucide-code",{"title":149,"path":150,"stem":151,"icon":152},"Behavioral (EN)","\u002Fphong-van\u002Fenglish-interview\u002Fbehavioral-en","1.phong-van\u002F5.english-interview\u002F4.behavioral-en","i-lucide-message-square-text",{"title":154,"icon":155,"path":156,"stem":157,"children":158},"Tự học","i-lucide-graduation-cap","\u002Ftu-hoc","2.tu-hoc",[159,161,287,310,333,357,384],{"title":154,"path":156,"stem":160,"icon":155},"2.tu-hoc\u002Findex",{"title":162,"icon":68,"path":163,"stem":164,"children":165},"Database","\u002Ftu-hoc\u002Fdatabase","2.tu-hoc\u002F1.database\u002Findex",[166,167,197,222,243,248],{"title":162,"path":163,"stem":164,"icon":68},{"title":168,"icon":91,"path":169,"stem":170,"children":171,"page":26},"SQL Server","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server","2.tu-hoc\u002F1.database\u002F2.sql-server",[172,177,182,187,192],{"title":173,"path":174,"stem":175,"icon":176},"1. Giới thiệu và Cài đặt","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F1.gioi-thieu-cai-dat","i-lucide-play-circle",{"title":178,"path":179,"stem":180,"icon":181},"2. Cú pháp cơ bản","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban","i-lucide-code-2",{"title":183,"path":184,"stem":185,"icon":186},"3. Truy vấn nâng cao","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F3.truy-van-nang-cao","i-lucide-git-merge",{"title":188,"path":189,"stem":190,"icon":191},"4. Đặc thù và Performance","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F4.dac-thu-performance","i-lucide-gauge",{"title":193,"path":194,"stem":195,"icon":196},"5. Q và A phỏng vấn","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van","i-lucide-message-circle-question",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":26},"PostgreSQL","i-simple-icons-postgresql","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql","2.tu-hoc\u002F1.database\u002F3.postgresql",[203,206,209,212,215,218],{"title":173,"path":204,"stem":205,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":207,"stem":208,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F2.cu-phap-co-ban",{"title":183,"path":210,"stem":211,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F3.truy-van-nang-cao",{"title":188,"path":213,"stem":214,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F4.dac-thu-performance",{"title":193,"path":216,"stem":217,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F5.cau-hoi-phong-van",{"title":219,"path":220,"stem":221,"icon":96},"6. Tích hợp C# và Postgres","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftich-hop-csharp","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F6.tich-hop-csharp",{"title":223,"icon":224,"path":225,"stem":226,"children":227,"page":26},"MySQL","i-simple-icons-mysql","\u002Ftu-hoc\u002Fdatabase\u002Fmysql","2.tu-hoc\u002F1.database\u002F4.mysql",[228,231,234,237,240],{"title":173,"path":229,"stem":230,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F4.mysql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":232,"stem":233,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F4.mysql\u002F2.cu-phap-co-ban",{"title":183,"path":235,"stem":236,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F4.mysql\u002F3.truy-van-nang-cao",{"title":188,"path":238,"stem":239,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F4.mysql\u002F4.dac-thu-performance",{"title":193,"path":241,"stem":242,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F4.mysql\u002F5.cau-hoi-phong-van",{"title":244,"path":245,"stem":246,"icon":247},"So sánh 3 RDBMS","\u002Ftu-hoc\u002Fdatabase\u002Fso-sanh","2.tu-hoc\u002F1.database\u002F5.so-sanh","i-lucide-columns-3",{"title":249,"path":250,"stem":251,"children":252,"icon":254},"Supabase (BaaS)","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002Findex",[253,255,259,264,269,274,278,283],{"title":249,"path":250,"stem":251,"icon":254},"i-simple-icons-supabase",{"title":256,"path":257,"stem":258,"icon":68},"1. Database","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fdatabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002F1.database",{"title":260,"path":261,"stem":262,"icon":263},"2. Authentication","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fauthentication","2.tu-hoc\u002F1.database\u002F6.supabase\u002F2.authentication","i-lucide-key",{"title":265,"path":266,"stem":267,"icon":268},"3. Storage & Realtime","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fstorage-realtime","2.tu-hoc\u002F1.database\u002F6.supabase\u002F3.storage-realtime","i-lucide-zap",{"title":270,"path":271,"stem":272,"icon":273},"4. Edge Functions & AI","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Ffunctions-ai","2.tu-hoc\u002F1.database\u002F6.supabase\u002F4.functions-ai","i-lucide-brain",{"title":275,"path":276,"stem":277,"icon":181},"5. API & SDKs","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fapi-sdk","2.tu-hoc\u002F1.database\u002F6.supabase\u002F5.api-sdk",{"title":279,"path":280,"stem":281,"icon":282},"6. Platform & Deploy","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fplatform-deploy","2.tu-hoc\u002F1.database\u002F6.supabase\u002F6.platform-deploy","i-lucide-cloud",{"title":284,"path":285,"stem":286,"icon":196},"7. Interview & Q&A","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Finterview","2.tu-hoc\u002F1.database\u002F6.supabase\u002F7.interview",{"title":288,"icon":289,"path":290,"stem":291,"children":292},"TypeScript","i-simple-icons-typescript","\u002Ftu-hoc\u002Ftypescript","2.tu-hoc\u002F2.typescript\u002Findex",[293,294,297,301,306],{"title":288,"path":290,"stem":291,"icon":289},{"title":173,"path":295,"stem":296,"icon":176},"\u002Ftu-hoc\u002Ftypescript\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F2.typescript\u002F1.gioi-thieu-cai-dat",{"title":298,"path":299,"stem":300,"icon":81},"2. Type System","\u002Ftu-hoc\u002Ftypescript\u002Ftype-system","2.tu-hoc\u002F2.typescript\u002F2.type-system",{"title":302,"path":303,"stem":304,"icon":305},"3. Advanced types","\u002Ftu-hoc\u002Ftypescript\u002Fadvanced-types","2.tu-hoc\u002F2.typescript\u002F3.advanced-types","i-lucide-braces",{"title":307,"path":308,"stem":309,"icon":196},"4. Q và A phỏng vấn","\u002Ftu-hoc\u002Ftypescript\u002Fcau-hoi-phong-van","2.tu-hoc\u002F2.typescript\u002F4.cau-hoi-phong-van",{"title":311,"icon":81,"path":312,"stem":313,"children":314},"OOP","\u002Ftu-hoc\u002Foop","2.tu-hoc\u002F3.oop\u002Findex",[315,316,321,326,330],{"title":311,"path":312,"stem":313,"icon":81},{"title":317,"path":318,"stem":319,"icon":320},"1. Bốn tính chất","\u002Ftu-hoc\u002Foop\u002F4-tinh-chat","2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat","i-lucide-circle-dot",{"title":322,"path":323,"stem":324,"icon":325},"2. SOLID","\u002Ftu-hoc\u002Foop\u002Fsolid","2.tu-hoc\u002F3.oop\u002F2.solid","i-lucide-shield",{"title":327,"path":328,"stem":329,"icon":106},"3. Design Pattern","\u002Ftu-hoc\u002Foop\u002Fdesign-pattern","2.tu-hoc\u002F3.oop\u002F3.design-pattern",{"title":307,"path":331,"stem":332,"icon":196},"\u002Ftu-hoc\u002Foop\u002Fcau-hoi-phong-van","2.tu-hoc\u002F3.oop\u002F4.cau-hoi-phong-van",{"title":334,"icon":305,"path":335,"stem":336,"children":337},"Generic","\u002Ftu-hoc\u002Fgeneric","2.tu-hoc\u002F4.generic\u002Findex",[338,339,344,349,354],{"title":334,"path":335,"stem":336,"icon":305},{"title":340,"path":341,"stem":342,"icon":343},"1. Khái niệm và cú pháp","\u002Ftu-hoc\u002Fgeneric\u002Fkhai-niem","2.tu-hoc\u002F4.generic\u002F1.khai-niem","i-lucide-book",{"title":345,"path":346,"stem":347,"icon":348},"2. Constraint và Variance","\u002Ftu-hoc\u002Fgeneric\u002Fconstraint-variance","2.tu-hoc\u002F4.generic\u002F2.constraint-variance","i-lucide-filter",{"title":350,"path":351,"stem":352,"icon":353},"3. C# vs TS","\u002Ftu-hoc\u002Fgeneric\u002Fso-sanh","2.tu-hoc\u002F4.generic\u002F3.so-sanh","i-lucide-git-compare",{"title":307,"path":355,"stem":356,"icon":196},"\u002Ftu-hoc\u002Fgeneric\u002Fcau-hoi-phong-van","2.tu-hoc\u002F4.generic\u002F4.cau-hoi-phong-van",{"title":358,"icon":359,"path":360,"stem":361,"children":362},"Nuxt 4","i-simple-icons-nuxt","\u002Ftu-hoc\u002Fnuxt-4","2.tu-hoc\u002F5.nuxt-4\u002Findex",[363,364,367,372,376,379],{"title":358,"path":360,"stem":361,"icon":359},{"title":173,"path":365,"stem":366,"icon":176},"\u002Ftu-hoc\u002Fnuxt-4\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F5.nuxt-4\u002F1.gioi-thieu-cai-dat",{"title":368,"path":369,"stem":370,"icon":371},"2. Routing và Rendering","\u002Ftu-hoc\u002Fnuxt-4\u002Frouting-rendering","2.tu-hoc\u002F5.nuxt-4\u002F2.routing-rendering","i-lucide-route",{"title":373,"path":374,"stem":375,"icon":91},"3. Data và Server","\u002Ftu-hoc\u002Fnuxt-4\u002Fdata-server","2.tu-hoc\u002F5.nuxt-4\u002F3.data-server",{"title":307,"path":377,"stem":378,"icon":196},"\u002Ftu-hoc\u002Fnuxt-4\u002Fcau-hoi-phong-van","2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van",{"title":380,"path":381,"stem":382,"icon":383},"5. Practical Todo App","\u002Ftu-hoc\u002Fnuxt-4\u002Fpractical-todo-app","2.tu-hoc\u002F5.nuxt-4\u002F5.practical-todo-app","i-lucide-check-square",{"title":385,"path":386,"stem":387,"children":388,"icon":390},"Tailwind CSS","\u002Ftu-hoc\u002Ftailwindcss","2.tu-hoc\u002F6.tailwindcss\u002Findex",[389,391,396,401,406,411,416],{"title":385,"path":386,"stem":387,"icon":390},"i-simple-icons-tailwindcss",{"title":392,"path":393,"stem":394,"icon":395},"1. Layout & Spacing","\u002Ftu-hoc\u002Ftailwindcss\u002Flayout-spacing","2.tu-hoc\u002F6.tailwindcss\u002F1.layout-spacing","i-lucide-layout",{"title":397,"path":398,"stem":399,"icon":400},"2. Typography & Colors","\u002Ftu-hoc\u002Ftailwindcss\u002Ftypography-colors","2.tu-hoc\u002F6.tailwindcss\u002F2.typography-colors","i-lucide-type",{"title":402,"path":403,"stem":404,"icon":405},"3. Interactive & Effects","\u002Ftu-hoc\u002Ftailwindcss\u002Finteractive-effects","2.tu-hoc\u002F6.tailwindcss\u002F3.interactive-effects","i-lucide-sparkles",{"title":407,"path":408,"stem":409,"icon":410},"4. Responsive & Dark Mode","\u002Ftu-hoc\u002Ftailwindcss\u002Fresponsive-darkmode","2.tu-hoc\u002F6.tailwindcss\u002F4.responsive-darkmode","i-lucide-monitor-smartphone",{"title":412,"path":413,"stem":414,"icon":415},"5. Customization & Theme","\u002Ftu-hoc\u002Ftailwindcss\u002Fcustomization","2.tu-hoc\u002F6.tailwindcss\u002F5.customization","i-lucide-settings-2",{"title":417,"path":418,"stem":419,"icon":181},"6. Practical Projects","\u002Ftu-hoc\u002Ftailwindcss\u002Fpractical-projects","2.tu-hoc\u002F6.tailwindcss\u002F6.practical-projects",{"id":421,"title":422,"body":423,"description":3305,"extension":3306,"links":3307,"meta":3308,"navigation":3309,"path":318,"seo":3310,"stem":319,"__hash__":3311},"docs\u002F2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat.md","Bốn tính chất OOP",{"type":424,"value":425,"toc":3288},"minimark",[426,431,464,488,492,500,1044,1086,1091,1124,1131,1135,1142,1660,1693,1697,1704,2157,2161,2169,2180,2184,2205,2533,2537,2544,2548,2570,2895,2939,2943,2957,2967,2971,3000,3096,3100,3107,3277,3284],[427,428,430],"h2",{"id":429},"bốn-tính-chất-oop-overview","Bốn tính chất OOP — overview",[432,433,434,440,454,459],"field-group",{},[435,436,439],"field",{"name":437,"type":438},"1. Encapsulation","Đóng gói","Che giấu state, expose qua API có kiểm soát (method\u002Fproperty).",[435,441,444,445,449,450,453],{"name":442,"type":443},"2. Abstraction","Trừu tượng","Tách \"",[446,447,448],"em",{},"cái gì làm","\" khỏi \"",[446,451,452],{},"làm như thế nào","\". Dùng interface \u002F abstract class.",[435,455,458],{"name":456,"type":457},"3. Inheritance","Kế thừa","Class con dùng lại + chuyên biệt hoá code class cha. Quan hệ \"is-a\".",[435,460,463],{"name":461,"type":462},"4. Polymorphism","Đa hình","Cùng interface, nhiều cách hiện thực — runtime quyết định.",[465,466,469,481],"callout",{"color":467,"icon":468},"warning","i-lucide-star",[470,471,472,473,477,478],"p",{},"⭐ ",[474,475,476],"strong",{},"Câu PV gần như 100%:"," ",[446,479,480],{},"\"Kể 4 tính chất OOP và cho ví dụ.\"",[470,482,483,484,487],{},"Đừng học thuộc định nghĩa — kể được kèm ",[474,485,486],{},"ví dụ code cụ thể"," mới được điểm. Phần dưới có pattern để bạn nhớ lâu.",[427,489,491],{"id":490},"_1-encapsulation-đóng-gói","1. Encapsulation — đóng gói",[493,494,495],"blockquote",{},[470,496,497],{},[474,498,499],{},"State private + API public có validation = encapsulation.",[501,502,503,665],"tabs",{},[504,505,508],"div",{"icon":506,"label":507},"i-simple-icons-csharp","C#",[509,510,515],"pre",{"className":511,"code":512,"language":513,"meta":514,"style":514},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","public class BankAccount {\n    \u002F\u002F State được giấu kín\n    private decimal _balance;\n    private readonly string _owner;\n    \n    public BankAccount(string owner, decimal initial) {\n        _owner = owner;\n        _balance = initial >= 0 ? initial : 0;\n    }\n    \n    \u002F\u002F API expose có kiểm soát\n    public decimal Balance => _balance;\n    public string Owner => _owner;\n    \n    public void Deposit(decimal amount) {\n        if (amount \u003C= 0) throw new ArgumentException(\"Must be positive\");\n        _balance += amount;\n    }\n    \n    public bool TryWithdraw(decimal amount) {\n        if (amount \u003C= 0 || amount > _balance) return false;\n        _balance -= amount;\n        return true;\n    }\n}\n","csharp","",[516,517,518,526,532,538,544,550,556,562,568,574,579,585,591,597,602,608,614,620,625,630,636,642,648,654,659],"code",{"__ignoreMap":514},[519,520,523],"span",{"class":521,"line":522},"line",1,[519,524,525],{},"public class BankAccount {\n",[519,527,529],{"class":521,"line":528},2,[519,530,531],{},"    \u002F\u002F State được giấu kín\n",[519,533,535],{"class":521,"line":534},3,[519,536,537],{},"    private decimal _balance;\n",[519,539,541],{"class":521,"line":540},4,[519,542,543],{},"    private readonly string _owner;\n",[519,545,547],{"class":521,"line":546},5,[519,548,549],{},"    \n",[519,551,553],{"class":521,"line":552},6,[519,554,555],{},"    public BankAccount(string owner, decimal initial) {\n",[519,557,559],{"class":521,"line":558},7,[519,560,561],{},"        _owner = owner;\n",[519,563,565],{"class":521,"line":564},8,[519,566,567],{},"        _balance = initial >= 0 ? initial : 0;\n",[519,569,571],{"class":521,"line":570},9,[519,572,573],{},"    }\n",[519,575,577],{"class":521,"line":576},10,[519,578,549],{},[519,580,582],{"class":521,"line":581},11,[519,583,584],{},"    \u002F\u002F API expose có kiểm soát\n",[519,586,588],{"class":521,"line":587},12,[519,589,590],{},"    public decimal Balance => _balance;\n",[519,592,594],{"class":521,"line":593},13,[519,595,596],{},"    public string Owner => _owner;\n",[519,598,600],{"class":521,"line":599},14,[519,601,549],{},[519,603,605],{"class":521,"line":604},15,[519,606,607],{},"    public void Deposit(decimal amount) {\n",[519,609,611],{"class":521,"line":610},16,[519,612,613],{},"        if (amount \u003C= 0) throw new ArgumentException(\"Must be positive\");\n",[519,615,617],{"class":521,"line":616},17,[519,618,619],{},"        _balance += amount;\n",[519,621,623],{"class":521,"line":622},18,[519,624,573],{},[519,626,628],{"class":521,"line":627},19,[519,629,549],{},[519,631,633],{"class":521,"line":632},20,[519,634,635],{},"    public bool TryWithdraw(decimal amount) {\n",[519,637,639],{"class":521,"line":638},21,[519,640,641],{},"        if (amount \u003C= 0 || amount > _balance) return false;\n",[519,643,645],{"class":521,"line":644},22,[519,646,647],{},"        _balance -= amount;\n",[519,649,651],{"class":521,"line":650},23,[519,652,653],{},"        return true;\n",[519,655,657],{"class":521,"line":656},24,[519,658,573],{},[519,660,662],{"class":521,"line":661},25,[519,663,664],{},"}\n",[504,666,667],{"icon":289,"label":288},[509,668,672],{"className":669,"code":670,"language":671,"meta":514,"style":514},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","class BankAccount {\n    \u002F\u002F # = TRULY private (runtime enforced)\n    #balance: number;\n    readonly #owner: string;\n    \n    constructor(owner: string, initial: number) {\n        this.#owner = owner;\n        this.#balance = initial >= 0 ? initial : 0;\n    }\n    \n    get balance(): number { return this.#balance; }\n    get owner(): string { return this.#owner; }\n    \n    deposit(amount: number): void {\n        if (amount \u003C= 0) throw new Error(\"Must be positive\");\n        this.#balance += amount;\n    }\n    \n    tryWithdraw(amount: number): boolean {\n        if (amount \u003C= 0 || amount > this.#balance) return false;\n        this.#balance -= amount;\n        return true;\n    }\n}\n","typescript",[516,673,674,688,694,709,724,729,760,776,806,810,814,845,867,871,893,936,950,954,958,978,1013,1026,1036,1040],{"__ignoreMap":514},[519,675,676,680,684],{"class":521,"line":522},[519,677,679],{"class":678},"spNyl","class",[519,681,683],{"class":682},"sBMFI"," BankAccount",[519,685,687],{"class":686},"sMK4o"," {\n",[519,689,690],{"class":521,"line":528},[519,691,693],{"class":692},"sHwdD","    \u002F\u002F # = TRULY private (runtime enforced)\n",[519,695,696,700,703,706],{"class":521,"line":534},[519,697,699],{"class":698},"swJcz","    #balance",[519,701,702],{"class":686},":",[519,704,705],{"class":682}," number",[519,707,708],{"class":686},";\n",[519,710,711,714,717,719,722],{"class":521,"line":540},[519,712,713],{"class":678},"    readonly",[519,715,716],{"class":698}," #owner",[519,718,702],{"class":686},[519,720,721],{"class":682}," string",[519,723,708],{"class":686},[519,725,726],{"class":521,"line":546},[519,727,549],{"class":728},"sTEyZ",[519,730,731,734,737,741,743,745,748,751,753,755,758],{"class":521,"line":552},[519,732,733],{"class":678},"    constructor",[519,735,736],{"class":686},"(",[519,738,740],{"class":739},"sHdIc","owner",[519,742,702],{"class":686},[519,744,721],{"class":682},[519,746,747],{"class":686},",",[519,749,750],{"class":739}," initial",[519,752,702],{"class":686},[519,754,705],{"class":682},[519,756,757],{"class":686},")",[519,759,687],{"class":686},[519,761,762,765,768,771,774],{"class":521,"line":558},[519,763,764],{"class":686},"        this.",[519,766,767],{"class":728},"#owner",[519,769,770],{"class":686}," =",[519,772,773],{"class":728}," owner",[519,775,708],{"class":686},[519,777,778,780,783,785,787,790,794,797,799,802,804],{"class":521,"line":564},[519,779,764],{"class":686},[519,781,782],{"class":728},"#balance",[519,784,770],{"class":686},[519,786,750],{"class":728},[519,788,789],{"class":686}," >=",[519,791,793],{"class":792},"sbssI"," 0",[519,795,796],{"class":686}," ?",[519,798,750],{"class":728},[519,800,801],{"class":686}," :",[519,803,793],{"class":792},[519,805,708],{"class":686},[519,807,808],{"class":521,"line":570},[519,809,573],{"class":686},[519,811,812],{"class":521,"line":576},[519,813,549],{"class":728},[519,815,816,819,822,825,827,830,834,837,839,842],{"class":521,"line":581},[519,817,818],{"class":678},"    get",[519,820,821],{"class":698}," balance",[519,823,824],{"class":686},"():",[519,826,705],{"class":682},[519,828,829],{"class":686}," {",[519,831,833],{"class":832},"s7zQu"," return",[519,835,836],{"class":686}," this.",[519,838,782],{"class":728},[519,840,841],{"class":686},";",[519,843,844],{"class":686}," }\n",[519,846,847,849,851,853,855,857,859,861,863,865],{"class":521,"line":587},[519,848,818],{"class":678},[519,850,773],{"class":698},[519,852,824],{"class":686},[519,854,721],{"class":682},[519,856,829],{"class":686},[519,858,833],{"class":832},[519,860,836],{"class":686},[519,862,767],{"class":728},[519,864,841],{"class":686},[519,866,844],{"class":686},[519,868,869],{"class":521,"line":593},[519,870,549],{"class":728},[519,872,873,876,878,881,883,885,888,891],{"class":521,"line":599},[519,874,875],{"class":698},"    deposit",[519,877,736],{"class":686},[519,879,880],{"class":739},"amount",[519,882,702],{"class":686},[519,884,705],{"class":682},[519,886,887],{"class":686},"):",[519,889,890],{"class":682}," void",[519,892,687],{"class":686},[519,894,895,898,901,903,906,908,911,914,917,921,923,926,930,932,934],{"class":521,"line":604},[519,896,897],{"class":832},"        if",[519,899,900],{"class":698}," (",[519,902,880],{"class":728},[519,904,905],{"class":686}," \u003C=",[519,907,793],{"class":792},[519,909,910],{"class":698},") ",[519,912,913],{"class":832},"throw",[519,915,916],{"class":686}," new",[519,918,920],{"class":919},"s2Zo4"," Error",[519,922,736],{"class":698},[519,924,925],{"class":686},"\"",[519,927,929],{"class":928},"sfazB","Must be positive",[519,931,925],{"class":686},[519,933,757],{"class":698},[519,935,708],{"class":686},[519,937,938,940,942,945,948],{"class":521,"line":610},[519,939,764],{"class":686},[519,941,782],{"class":728},[519,943,944],{"class":686}," +=",[519,946,947],{"class":728}," amount",[519,949,708],{"class":686},[519,951,952],{"class":521,"line":616},[519,953,573],{"class":686},[519,955,956],{"class":521,"line":622},[519,957,549],{"class":728},[519,959,960,963,965,967,969,971,973,976],{"class":521,"line":627},[519,961,962],{"class":698},"    tryWithdraw",[519,964,736],{"class":686},[519,966,880],{"class":739},[519,968,702],{"class":686},[519,970,705],{"class":682},[519,972,887],{"class":686},[519,974,975],{"class":682}," boolean",[519,977,687],{"class":686},[519,979,980,982,984,986,988,990,993,995,998,1000,1002,1004,1007,1011],{"class":521,"line":632},[519,981,897],{"class":832},[519,983,900],{"class":698},[519,985,880],{"class":728},[519,987,905],{"class":686},[519,989,793],{"class":792},[519,991,992],{"class":686}," ||",[519,994,947],{"class":728},[519,996,997],{"class":686}," >",[519,999,836],{"class":686},[519,1001,782],{"class":728},[519,1003,910],{"class":698},[519,1005,1006],{"class":832},"return",[519,1008,1010],{"class":1009},"sfNiH"," false",[519,1012,708],{"class":686},[519,1014,1015,1017,1019,1022,1024],{"class":521,"line":638},[519,1016,764],{"class":686},[519,1018,782],{"class":728},[519,1020,1021],{"class":686}," -=",[519,1023,947],{"class":728},[519,1025,708],{"class":686},[519,1027,1028,1031,1034],{"class":521,"line":644},[519,1029,1030],{"class":832},"        return",[519,1032,1033],{"class":1009}," true",[519,1035,708],{"class":686},[519,1037,1038],{"class":521,"line":650},[519,1039,573],{"class":686},[519,1041,1042],{"class":521,"line":656},[519,1043,664],{"class":686},[465,1045,1048,1053],{"color":1046,"icon":1047},"primary","i-lucide-info",[470,1049,1050],{},[474,1051,1052],{},"Khác biệt C# vs TS:",[1054,1055,1056,1068],"ul",{},[1057,1058,1059,1060,1063,1064,1067],"li",{},"C# ",[516,1061,1062],{},"private"," enforce ở ",[474,1065,1066],{},"compile + runtime IL",".",[1057,1069,1070,1071,1073,1074,1077,1078,1081,1082,1085],{},"TS ",[516,1072,1062],{}," chỉ check ",[474,1075,1076],{},"compile-time"," — runtime vẫn truy cập được. Dùng ",[516,1079,1080],{},"#"," để ",[474,1083,1084],{},"truly private runtime"," (JS native).",[1087,1088,1090],"h3",{"id":1089},"vì-sao-quan-trọng","Vì sao quan trọng?",[509,1092,1094],{"className":511,"code":1093,"language":513,"meta":514,"style":514},"\u002F\u002F ❌ Nếu không encapsulate\npublic class BankAccount {\n    public decimal Balance;\n}\naccount.Balance = -1000000;       \u002F\u002F Negative balance? Bug!\naccount.Balance += 1.0\u002F3;         \u002F\u002F Floating point chia số → mất tiền\n",[516,1095,1096,1101,1105,1110,1114,1119],{"__ignoreMap":514},[519,1097,1098],{"class":521,"line":522},[519,1099,1100],{},"\u002F\u002F ❌ Nếu không encapsulate\n",[519,1102,1103],{"class":521,"line":528},[519,1104,525],{},[519,1106,1107],{"class":521,"line":534},[519,1108,1109],{},"    public decimal Balance;\n",[519,1111,1112],{"class":521,"line":540},[519,1113,664],{},[519,1115,1116],{"class":521,"line":546},[519,1117,1118],{},"account.Balance = -1000000;       \u002F\u002F Negative balance? Bug!\n",[519,1120,1121],{"class":521,"line":552},[519,1122,1123],{},"account.Balance += 1.0\u002F3;         \u002F\u002F Floating point chia số → mất tiền\n",[470,1125,1126,1127,1130],{},"→ Encapsulation = ",[474,1128,1129],{},"invariant"," (bất biến của class) được bảo vệ. Balance không bao giờ âm. Validation luôn chạy.",[427,1132,1134],{"id":1133},"_2-abstraction-trừu-tượng","2. Abstraction — trừu tượng",[493,1136,1137],{},[470,1138,1139],{},[474,1140,1141],{},"Định nghĩa \"cái gì\" mà không nói \"làm sao\".",[501,1143,1144,1301],{},[504,1145,1146],{"icon":506,"label":507},[509,1147,1149],{"className":511,"code":1148,"language":513,"meta":514,"style":514},"\u002F\u002F Abstraction qua interface\npublic interface IPaymentGateway {\n    Task\u003CPaymentResult> ChargeAsync(decimal amount, string currency);\n    Task\u003Cbool> RefundAsync(string transactionId);\n}\n\n\u002F\u002F Implementation cụ thể — Caller không cần biết\npublic class StripeGateway : IPaymentGateway {\n    public Task\u003CPaymentResult> ChargeAsync(decimal amount, string currency) {\n        \u002F\u002F gọi Stripe API\n    }\n    public Task\u003Cbool> RefundAsync(string transactionId) { ... }\n}\n\npublic class VnPayGateway : IPaymentGateway {\n    public Task\u003CPaymentResult> ChargeAsync(decimal amount, string currency) {\n        \u002F\u002F gọi VnPay API\n    }\n    public Task\u003Cbool> RefundAsync(string transactionId) { ... }\n}\n\n\u002F\u002F Service chỉ phụ thuộc abstraction\npublic class CheckoutService {\n    private readonly IPaymentGateway _gateway;\n    public CheckoutService(IPaymentGateway gateway) => _gateway = gateway;\n    \n    public async Task Checkout(Order order) {\n        var result = await _gateway.ChargeAsync(order.Total, \"VND\");\n        \u002F\u002F ...\n    }\n}\n",[516,1150,1151,1156,1161,1166,1171,1175,1181,1186,1191,1196,1201,1205,1210,1214,1218,1223,1227,1232,1236,1240,1244,1248,1253,1258,1263,1268,1273,1279,1285,1291,1296],{"__ignoreMap":514},[519,1152,1153],{"class":521,"line":522},[519,1154,1155],{},"\u002F\u002F Abstraction qua interface\n",[519,1157,1158],{"class":521,"line":528},[519,1159,1160],{},"public interface IPaymentGateway {\n",[519,1162,1163],{"class":521,"line":534},[519,1164,1165],{},"    Task\u003CPaymentResult> ChargeAsync(decimal amount, string currency);\n",[519,1167,1168],{"class":521,"line":540},[519,1169,1170],{},"    Task\u003Cbool> RefundAsync(string transactionId);\n",[519,1172,1173],{"class":521,"line":546},[519,1174,664],{},[519,1176,1177],{"class":521,"line":552},[519,1178,1180],{"emptyLinePlaceholder":1179},true,"\n",[519,1182,1183],{"class":521,"line":558},[519,1184,1185],{},"\u002F\u002F Implementation cụ thể — Caller không cần biết\n",[519,1187,1188],{"class":521,"line":564},[519,1189,1190],{},"public class StripeGateway : IPaymentGateway {\n",[519,1192,1193],{"class":521,"line":570},[519,1194,1195],{},"    public Task\u003CPaymentResult> ChargeAsync(decimal amount, string currency) {\n",[519,1197,1198],{"class":521,"line":576},[519,1199,1200],{},"        \u002F\u002F gọi Stripe API\n",[519,1202,1203],{"class":521,"line":581},[519,1204,573],{},[519,1206,1207],{"class":521,"line":587},[519,1208,1209],{},"    public Task\u003Cbool> RefundAsync(string transactionId) { ... }\n",[519,1211,1212],{"class":521,"line":593},[519,1213,664],{},[519,1215,1216],{"class":521,"line":599},[519,1217,1180],{"emptyLinePlaceholder":1179},[519,1219,1220],{"class":521,"line":604},[519,1221,1222],{},"public class VnPayGateway : IPaymentGateway {\n",[519,1224,1225],{"class":521,"line":610},[519,1226,1195],{},[519,1228,1229],{"class":521,"line":616},[519,1230,1231],{},"        \u002F\u002F gọi VnPay API\n",[519,1233,1234],{"class":521,"line":622},[519,1235,573],{},[519,1237,1238],{"class":521,"line":627},[519,1239,1209],{},[519,1241,1242],{"class":521,"line":632},[519,1243,664],{},[519,1245,1246],{"class":521,"line":638},[519,1247,1180],{"emptyLinePlaceholder":1179},[519,1249,1250],{"class":521,"line":644},[519,1251,1252],{},"\u002F\u002F Service chỉ phụ thuộc abstraction\n",[519,1254,1255],{"class":521,"line":650},[519,1256,1257],{},"public class CheckoutService {\n",[519,1259,1260],{"class":521,"line":656},[519,1261,1262],{},"    private readonly IPaymentGateway _gateway;\n",[519,1264,1265],{"class":521,"line":661},[519,1266,1267],{},"    public CheckoutService(IPaymentGateway gateway) => _gateway = gateway;\n",[519,1269,1271],{"class":521,"line":1270},26,[519,1272,549],{},[519,1274,1276],{"class":521,"line":1275},27,[519,1277,1278],{},"    public async Task Checkout(Order order) {\n",[519,1280,1282],{"class":521,"line":1281},28,[519,1283,1284],{},"        var result = await _gateway.ChargeAsync(order.Total, \"VND\");\n",[519,1286,1288],{"class":521,"line":1287},29,[519,1289,1290],{},"        \u002F\u002F ...\n",[519,1292,1294],{"class":521,"line":1293},30,[519,1295,573],{},[519,1297,1299],{"class":521,"line":1298},31,[519,1300,664],{},[504,1302,1303],{"icon":289,"label":288},[509,1304,1306],{"className":669,"code":1305,"language":671,"meta":514,"style":514},"interface PaymentGateway {\n    charge(amount: number, currency: string): Promise\u003CPaymentResult>;\n    refund(transactionId: string): Promise\u003Cboolean>;\n}\n\nclass StripeGateway implements PaymentGateway {\n    async charge(amount: number, currency: string) { \u002F* Stripe API *\u002F }\n    async refund(transactionId: string) { \u002F* ... *\u002F return true; }\n}\n\nclass VnPayGateway implements PaymentGateway {\n    async charge(amount: number, currency: string) { \u002F* VnPay API *\u002F }\n    async refund(transactionId: string) { \u002F* ... *\u002F return true; }\n}\n\nclass CheckoutService {\n    constructor(private gateway: PaymentGateway) {}\n    \n    async checkout(order: Order) {\n        const result = await this.gateway.charge(order.total, \"VND\");\n    }\n}\n",[516,1307,1308,1318,1354,1379,1383,1387,1401,1434,1464,1468,1472,1485,1516,1544,1548,1552,1561,1581,1585,1606,1652,1656],{"__ignoreMap":514},[519,1309,1310,1313,1316],{"class":521,"line":522},[519,1311,1312],{"class":678},"interface",[519,1314,1315],{"class":682}," PaymentGateway",[519,1317,687],{"class":686},[519,1319,1320,1323,1325,1327,1329,1331,1333,1336,1338,1340,1342,1345,1348,1351],{"class":521,"line":528},[519,1321,1322],{"class":698},"    charge",[519,1324,736],{"class":686},[519,1326,880],{"class":739},[519,1328,702],{"class":686},[519,1330,705],{"class":682},[519,1332,747],{"class":686},[519,1334,1335],{"class":739}," currency",[519,1337,702],{"class":686},[519,1339,721],{"class":682},[519,1341,887],{"class":686},[519,1343,1344],{"class":682}," Promise",[519,1346,1347],{"class":686},"\u003C",[519,1349,1350],{"class":682},"PaymentResult",[519,1352,1353],{"class":686},">;\n",[519,1355,1356,1359,1361,1364,1366,1368,1370,1372,1374,1377],{"class":521,"line":534},[519,1357,1358],{"class":698},"    refund",[519,1360,736],{"class":686},[519,1362,1363],{"class":739},"transactionId",[519,1365,702],{"class":686},[519,1367,721],{"class":682},[519,1369,887],{"class":686},[519,1371,1344],{"class":682},[519,1373,1347],{"class":686},[519,1375,1376],{"class":682},"boolean",[519,1378,1353],{"class":686},[519,1380,1381],{"class":521,"line":540},[519,1382,664],{"class":686},[519,1384,1385],{"class":521,"line":546},[519,1386,1180],{"emptyLinePlaceholder":1179},[519,1388,1389,1391,1394,1397,1399],{"class":521,"line":552},[519,1390,679],{"class":678},[519,1392,1393],{"class":682}," StripeGateway",[519,1395,1396],{"class":678}," implements",[519,1398,1315],{"class":682},[519,1400,687],{"class":686},[519,1402,1403,1406,1409,1411,1413,1415,1417,1419,1421,1423,1425,1427,1429,1432],{"class":521,"line":558},[519,1404,1405],{"class":678},"    async",[519,1407,1408],{"class":698}," charge",[519,1410,736],{"class":686},[519,1412,880],{"class":739},[519,1414,702],{"class":686},[519,1416,705],{"class":682},[519,1418,747],{"class":686},[519,1420,1335],{"class":739},[519,1422,702],{"class":686},[519,1424,721],{"class":682},[519,1426,757],{"class":686},[519,1428,829],{"class":686},[519,1430,1431],{"class":692}," \u002F* Stripe API *\u002F",[519,1433,844],{"class":686},[519,1435,1436,1438,1441,1443,1445,1447,1449,1451,1453,1456,1458,1460,1462],{"class":521,"line":564},[519,1437,1405],{"class":678},[519,1439,1440],{"class":698}," refund",[519,1442,736],{"class":686},[519,1444,1363],{"class":739},[519,1446,702],{"class":686},[519,1448,721],{"class":682},[519,1450,757],{"class":686},[519,1452,829],{"class":686},[519,1454,1455],{"class":692}," \u002F* ... *\u002F",[519,1457,833],{"class":832},[519,1459,1033],{"class":1009},[519,1461,841],{"class":686},[519,1463,844],{"class":686},[519,1465,1466],{"class":521,"line":570},[519,1467,664],{"class":686},[519,1469,1470],{"class":521,"line":576},[519,1471,1180],{"emptyLinePlaceholder":1179},[519,1473,1474,1476,1479,1481,1483],{"class":521,"line":581},[519,1475,679],{"class":678},[519,1477,1478],{"class":682}," VnPayGateway",[519,1480,1396],{"class":678},[519,1482,1315],{"class":682},[519,1484,687],{"class":686},[519,1486,1487,1489,1491,1493,1495,1497,1499,1501,1503,1505,1507,1509,1511,1514],{"class":521,"line":587},[519,1488,1405],{"class":678},[519,1490,1408],{"class":698},[519,1492,736],{"class":686},[519,1494,880],{"class":739},[519,1496,702],{"class":686},[519,1498,705],{"class":682},[519,1500,747],{"class":686},[519,1502,1335],{"class":739},[519,1504,702],{"class":686},[519,1506,721],{"class":682},[519,1508,757],{"class":686},[519,1510,829],{"class":686},[519,1512,1513],{"class":692}," \u002F* VnPay API *\u002F",[519,1515,844],{"class":686},[519,1517,1518,1520,1522,1524,1526,1528,1530,1532,1534,1536,1538,1540,1542],{"class":521,"line":593},[519,1519,1405],{"class":678},[519,1521,1440],{"class":698},[519,1523,736],{"class":686},[519,1525,1363],{"class":739},[519,1527,702],{"class":686},[519,1529,721],{"class":682},[519,1531,757],{"class":686},[519,1533,829],{"class":686},[519,1535,1455],{"class":692},[519,1537,833],{"class":832},[519,1539,1033],{"class":1009},[519,1541,841],{"class":686},[519,1543,844],{"class":686},[519,1545,1546],{"class":521,"line":599},[519,1547,664],{"class":686},[519,1549,1550],{"class":521,"line":604},[519,1551,1180],{"emptyLinePlaceholder":1179},[519,1553,1554,1556,1559],{"class":521,"line":610},[519,1555,679],{"class":678},[519,1557,1558],{"class":682}," CheckoutService",[519,1560,687],{"class":686},[519,1562,1563,1565,1567,1569,1572,1574,1576,1578],{"class":521,"line":616},[519,1564,733],{"class":678},[519,1566,736],{"class":686},[519,1568,1062],{"class":678},[519,1570,1571],{"class":739}," gateway",[519,1573,702],{"class":686},[519,1575,1315],{"class":682},[519,1577,757],{"class":686},[519,1579,1580],{"class":686}," {}\n",[519,1582,1583],{"class":521,"line":622},[519,1584,549],{"class":728},[519,1586,1587,1589,1592,1594,1597,1599,1602,1604],{"class":521,"line":627},[519,1588,1405],{"class":678},[519,1590,1591],{"class":698}," checkout",[519,1593,736],{"class":686},[519,1595,1596],{"class":739},"order",[519,1598,702],{"class":686},[519,1600,1601],{"class":682}," Order",[519,1603,757],{"class":686},[519,1605,687],{"class":686},[519,1607,1608,1611,1614,1616,1619,1621,1624,1626,1629,1631,1633,1635,1638,1640,1643,1646,1648,1650],{"class":521,"line":632},[519,1609,1610],{"class":678},"        const",[519,1612,1613],{"class":728}," result",[519,1615,770],{"class":686},[519,1617,1618],{"class":832}," await",[519,1620,836],{"class":686},[519,1622,1623],{"class":728},"gateway",[519,1625,1067],{"class":686},[519,1627,1628],{"class":919},"charge",[519,1630,736],{"class":698},[519,1632,1596],{"class":728},[519,1634,1067],{"class":686},[519,1636,1637],{"class":728},"total",[519,1639,747],{"class":686},[519,1641,1642],{"class":686}," \"",[519,1644,1645],{"class":928},"VND",[519,1647,925],{"class":686},[519,1649,757],{"class":698},[519,1651,708],{"class":686},[519,1653,1654],{"class":521,"line":638},[519,1655,573],{"class":686},[519,1657,1658],{"class":521,"line":644},[519,1659,664],{"class":686},[465,1661,1662,1670],{"color":467,"icon":468},[470,1663,472,1664,477,1667],{},[474,1665,1666],{},"Câu PV cốt lõi:",[446,1668,1669],{},"\"Abstraction khác Encapsulation chỗ nào?\"",[493,1671,1672,1690],{},[470,1673,1674,1675,1678,1679,1681,1682,1685,1686,1689],{},"\"Encapsulation là ",[474,1676,1677],{},"mechanism"," (cách che data — ",[516,1680,1062],{},"). Abstraction là ",[474,1683,1684],{},"concept"," (che complexity — chỉ expose ",[516,1687,1688],{},"charge()"," không expose chi tiết gọi HTTP, parse JSON, retry, etc.).",[470,1691,1692],{},"Hai khái niệm bổ trợ: encapsulation phục vụ abstraction. Khi gộp lại — bạn cho user 1 API đơn giản và an toàn.\"",[427,1694,1696],{"id":1695},"_3-inheritance-kế-thừa","3. Inheritance — kế thừa",[493,1698,1699],{},[470,1700,1701],{},[474,1702,1703],{},"Class con tái sử dụng + chuyên biệt class cha. Quan hệ \"is-a\".",[501,1705,1706,1820],{},[504,1707,1708],{"icon":506,"label":507},[509,1709,1711],{"className":511,"code":1710,"language":513,"meta":514,"style":514},"public abstract class Animal {\n    public string Name { get; }\n    \n    protected Animal(string name) => Name = name;\n    \n    \u002F\u002F Hành vi chung\n    public void Sleep() => Console.WriteLine($\"{Name} is sleeping\");\n    \n    \u002F\u002F Hành vi con phải define\n    public abstract string Speak();\n}\n\npublic class Dog : Animal {\n    public Dog(string name) : base(name) {}\n    public override string Speak() => \"Woof!\";\n    public void Fetch() => Console.WriteLine($\"{Name} fetches the ball\");\n}\n\npublic class Cat : Animal {\n    public Cat(string name) : base(name) {}\n    public override string Speak() => \"Meow!\";\n    public void Scratch() => Console.WriteLine($\"{Name} scratches\");\n}\n",[516,1712,1713,1718,1723,1727,1732,1736,1741,1746,1750,1755,1760,1764,1768,1773,1778,1783,1788,1792,1796,1801,1806,1811,1816],{"__ignoreMap":514},[519,1714,1715],{"class":521,"line":522},[519,1716,1717],{},"public abstract class Animal {\n",[519,1719,1720],{"class":521,"line":528},[519,1721,1722],{},"    public string Name { get; }\n",[519,1724,1725],{"class":521,"line":534},[519,1726,549],{},[519,1728,1729],{"class":521,"line":540},[519,1730,1731],{},"    protected Animal(string name) => Name = name;\n",[519,1733,1734],{"class":521,"line":546},[519,1735,549],{},[519,1737,1738],{"class":521,"line":552},[519,1739,1740],{},"    \u002F\u002F Hành vi chung\n",[519,1742,1743],{"class":521,"line":558},[519,1744,1745],{},"    public void Sleep() => Console.WriteLine($\"{Name} is sleeping\");\n",[519,1747,1748],{"class":521,"line":564},[519,1749,549],{},[519,1751,1752],{"class":521,"line":570},[519,1753,1754],{},"    \u002F\u002F Hành vi con phải define\n",[519,1756,1757],{"class":521,"line":576},[519,1758,1759],{},"    public abstract string Speak();\n",[519,1761,1762],{"class":521,"line":581},[519,1763,664],{},[519,1765,1766],{"class":521,"line":587},[519,1767,1180],{"emptyLinePlaceholder":1179},[519,1769,1770],{"class":521,"line":593},[519,1771,1772],{},"public class Dog : Animal {\n",[519,1774,1775],{"class":521,"line":599},[519,1776,1777],{},"    public Dog(string name) : base(name) {}\n",[519,1779,1780],{"class":521,"line":604},[519,1781,1782],{},"    public override string Speak() => \"Woof!\";\n",[519,1784,1785],{"class":521,"line":610},[519,1786,1787],{},"    public void Fetch() => Console.WriteLine($\"{Name} fetches the ball\");\n",[519,1789,1790],{"class":521,"line":616},[519,1791,664],{},[519,1793,1794],{"class":521,"line":622},[519,1795,1180],{"emptyLinePlaceholder":1179},[519,1797,1798],{"class":521,"line":627},[519,1799,1800],{},"public class Cat : Animal {\n",[519,1802,1803],{"class":521,"line":632},[519,1804,1805],{},"    public Cat(string name) : base(name) {}\n",[519,1807,1808],{"class":521,"line":638},[519,1809,1810],{},"    public override string Speak() => \"Meow!\";\n",[519,1812,1813],{"class":521,"line":644},[519,1814,1815],{},"    public void Scratch() => Console.WriteLine($\"{Name} scratches\");\n",[519,1817,1818],{"class":521,"line":650},[519,1819,664],{},[504,1821,1822],{"icon":289,"label":288},[509,1823,1825],{"className":669,"code":1824,"language":671,"meta":514,"style":514},"abstract class Animal {\n    constructor(public readonly name: string) {}\n    \n    sleep(): void { console.log(`${this.name} is sleeping`); }\n    \n    abstract speak(): string;\n}\n\nclass Dog extends Animal {\n    constructor(name: string) { super(name); }\n    speak(): string { return \"Woof!\"; }\n    fetch(): void { console.log(`${this.name} fetches the ball`); }\n}\n\nclass Cat extends Animal {\n    constructor(name: string) { super(name); }\n    speak(): string { return \"Meow!\"; }\n    scratch(): void { console.log(`${this.name} scratches`); }\n}\n",[516,1826,1827,1840,1863,1867,1912,1916,1930,1934,1938,1952,1981,2005,2043,2047,2051,2064,2092,2115,2153],{"__ignoreMap":514},[519,1828,1829,1832,1835,1838],{"class":521,"line":522},[519,1830,1831],{"class":678},"abstract",[519,1833,1834],{"class":678}," class",[519,1836,1837],{"class":682}," Animal",[519,1839,687],{"class":686},[519,1841,1842,1844,1846,1849,1852,1855,1857,1859,1861],{"class":521,"line":528},[519,1843,733],{"class":678},[519,1845,736],{"class":686},[519,1847,1848],{"class":678},"public",[519,1850,1851],{"class":678}," readonly",[519,1853,1854],{"class":739}," name",[519,1856,702],{"class":686},[519,1858,721],{"class":682},[519,1860,757],{"class":686},[519,1862,1580],{"class":686},[519,1864,1865],{"class":521,"line":534},[519,1866,549],{"class":728},[519,1868,1869,1872,1874,1876,1878,1881,1883,1886,1888,1891,1894,1897,1900,1903,1906,1908,1910],{"class":521,"line":540},[519,1870,1871],{"class":698},"    sleep",[519,1873,824],{"class":686},[519,1875,890],{"class":682},[519,1877,829],{"class":686},[519,1879,1880],{"class":728}," console",[519,1882,1067],{"class":686},[519,1884,1885],{"class":919},"log",[519,1887,736],{"class":698},[519,1889,1890],{"class":686},"`${",[519,1892,1893],{"class":686},"this.",[519,1895,1896],{"class":728},"name",[519,1898,1899],{"class":686},"}",[519,1901,1902],{"class":928}," is sleeping",[519,1904,1905],{"class":686},"`",[519,1907,757],{"class":698},[519,1909,841],{"class":686},[519,1911,844],{"class":686},[519,1913,1914],{"class":521,"line":546},[519,1915,549],{"class":728},[519,1917,1918,1921,1924,1926,1928],{"class":521,"line":552},[519,1919,1920],{"class":678},"    abstract",[519,1922,1923],{"class":698}," speak",[519,1925,824],{"class":686},[519,1927,721],{"class":682},[519,1929,708],{"class":686},[519,1931,1932],{"class":521,"line":558},[519,1933,664],{"class":686},[519,1935,1936],{"class":521,"line":564},[519,1937,1180],{"emptyLinePlaceholder":1179},[519,1939,1940,1942,1945,1948,1950],{"class":521,"line":570},[519,1941,679],{"class":678},[519,1943,1944],{"class":682}," Dog",[519,1946,1947],{"class":678}," extends",[519,1949,1837],{"class":682},[519,1951,687],{"class":686},[519,1953,1954,1956,1958,1960,1962,1964,1966,1968,1971,1973,1975,1977,1979],{"class":521,"line":576},[519,1955,733],{"class":678},[519,1957,736],{"class":686},[519,1959,1896],{"class":739},[519,1961,702],{"class":686},[519,1963,721],{"class":682},[519,1965,757],{"class":686},[519,1967,829],{"class":686},[519,1969,1970],{"class":728}," super",[519,1972,736],{"class":698},[519,1974,1896],{"class":728},[519,1976,757],{"class":698},[519,1978,841],{"class":686},[519,1980,844],{"class":686},[519,1982,1983,1986,1988,1990,1992,1994,1996,1999,2001,2003],{"class":521,"line":581},[519,1984,1985],{"class":698},"    speak",[519,1987,824],{"class":686},[519,1989,721],{"class":682},[519,1991,829],{"class":686},[519,1993,833],{"class":832},[519,1995,1642],{"class":686},[519,1997,1998],{"class":928},"Woof!",[519,2000,925],{"class":686},[519,2002,841],{"class":686},[519,2004,844],{"class":686},[519,2006,2007,2010,2012,2014,2016,2018,2020,2022,2024,2026,2028,2030,2032,2035,2037,2039,2041],{"class":521,"line":587},[519,2008,2009],{"class":698},"    fetch",[519,2011,824],{"class":686},[519,2013,890],{"class":682},[519,2015,829],{"class":686},[519,2017,1880],{"class":728},[519,2019,1067],{"class":686},[519,2021,1885],{"class":919},[519,2023,736],{"class":698},[519,2025,1890],{"class":686},[519,2027,1893],{"class":686},[519,2029,1896],{"class":728},[519,2031,1899],{"class":686},[519,2033,2034],{"class":928}," fetches the ball",[519,2036,1905],{"class":686},[519,2038,757],{"class":698},[519,2040,841],{"class":686},[519,2042,844],{"class":686},[519,2044,2045],{"class":521,"line":593},[519,2046,664],{"class":686},[519,2048,2049],{"class":521,"line":599},[519,2050,1180],{"emptyLinePlaceholder":1179},[519,2052,2053,2055,2058,2060,2062],{"class":521,"line":604},[519,2054,679],{"class":678},[519,2056,2057],{"class":682}," Cat",[519,2059,1947],{"class":678},[519,2061,1837],{"class":682},[519,2063,687],{"class":686},[519,2065,2066,2068,2070,2072,2074,2076,2078,2080,2082,2084,2086,2088,2090],{"class":521,"line":610},[519,2067,733],{"class":678},[519,2069,736],{"class":686},[519,2071,1896],{"class":739},[519,2073,702],{"class":686},[519,2075,721],{"class":682},[519,2077,757],{"class":686},[519,2079,829],{"class":686},[519,2081,1970],{"class":728},[519,2083,736],{"class":698},[519,2085,1896],{"class":728},[519,2087,757],{"class":698},[519,2089,841],{"class":686},[519,2091,844],{"class":686},[519,2093,2094,2096,2098,2100,2102,2104,2106,2109,2111,2113],{"class":521,"line":616},[519,2095,1985],{"class":698},[519,2097,824],{"class":686},[519,2099,721],{"class":682},[519,2101,829],{"class":686},[519,2103,833],{"class":832},[519,2105,1642],{"class":686},[519,2107,2108],{"class":928},"Meow!",[519,2110,925],{"class":686},[519,2112,841],{"class":686},[519,2114,844],{"class":686},[519,2116,2117,2120,2122,2124,2126,2128,2130,2132,2134,2136,2138,2140,2142,2145,2147,2149,2151],{"class":521,"line":622},[519,2118,2119],{"class":698},"    scratch",[519,2121,824],{"class":686},[519,2123,890],{"class":682},[519,2125,829],{"class":686},[519,2127,1880],{"class":728},[519,2129,1067],{"class":686},[519,2131,1885],{"class":919},[519,2133,736],{"class":698},[519,2135,1890],{"class":686},[519,2137,1893],{"class":686},[519,2139,1896],{"class":728},[519,2141,1899],{"class":686},[519,2143,2144],{"class":928}," scratches",[519,2146,1905],{"class":686},[519,2148,757],{"class":698},[519,2150,841],{"class":686},[519,2152,844],{"class":686},[519,2154,2155],{"class":521,"line":627},[519,2156,664],{"class":686},[1087,2158,2160],{"id":2159},"nhiều-cấp-kế-thừa-nên-dừng-ở-2-3-cấp","Nhiều cấp kế thừa — nên dừng ở 2-3 cấp",[509,2162,2167],{"className":2163,"code":2165,"language":2166},[2164],"language-text","Animal\n ├─ Mammal\n │   ├─ Dog\n │   └─ Cat\n └─ Bird\n     └─ Penguin\n","text",[516,2168,2165],{"__ignoreMap":514},[465,2170,2172,2175,2176,2179],{"color":467,"icon":2171},"i-lucide-alert-triangle",[474,2173,2174],{},"Cảnh báo deep inheritance:"," > 3 cấp → khó maintain, \"fragile base class\" (sửa cha vỡ con). Nguyên tắc: ",[474,2177,2178],{},"\"Favor composition over inheritance\""," — sẽ giải thích kỹ ở SOLID.",[1087,2181,2183],{"id":2182},"multiple-inheritance","Multiple inheritance?",[1054,2185,2186,2194],{},[1057,2187,2188,2190,2191,1067],{},[474,2189,507],{},": chỉ 1 base class, ",[474,2192,2193],{},"nhiều interface",[1057,2195,2196,2190,2198,2200,2201,2204],{},[474,2197,288],{},[474,2199,2193],{},". Có ",[516,2202,2203],{},"mixin"," để mô phỏng multiple inheritance.",[509,2206,2208],{"className":669,"code":2207,"language":671,"meta":514,"style":514},"\u002F\u002F TS mixin pattern\ntype Constructor\u003CT = {}> = new (...args: any[]) => T;\n\nfunction Timestamped\u003CTBase extends Constructor>(Base: TBase) {\n    return class extends Base {\n        createdAt = new Date();\n    };\n}\n\nfunction Tagged\u003CTBase extends Constructor>(Base: TBase) {\n    return class extends Base {\n        tags: string[] = [];\n    };\n}\n\nclass User { constructor(public name: string) {} }\nclass TaggedTimestampedUser extends Timestamped(Tagged(User)) {}\n\nconst u = new TaggedTimestampedUser(\"Alice\");\nu.tags.push(\"vip\");\nu.createdAt;     \u002F\u002F có sẵn\n",[516,2209,2210,2215,2261,2265,2297,2311,2326,2331,2335,2339,2366,2378,2397,2401,2405,2409,2438,2460,2464,2491,2519],{"__ignoreMap":514},[519,2211,2212],{"class":521,"line":522},[519,2213,2214],{"class":692},"\u002F\u002F TS mixin pattern\n",[519,2216,2217,2220,2223,2225,2228,2230,2233,2235,2237,2240,2243,2245,2248,2251,2253,2256,2259],{"class":521,"line":528},[519,2218,2219],{"class":678},"type",[519,2221,2222],{"class":682}," Constructor",[519,2224,1347],{"class":686},[519,2226,2227],{"class":682},"T",[519,2229,770],{"class":686},[519,2231,2232],{"class":686}," {}>",[519,2234,770],{"class":686},[519,2236,916],{"class":832},[519,2238,2239],{"class":686}," (...",[519,2241,2242],{"class":739},"args",[519,2244,702],{"class":686},[519,2246,2247],{"class":682}," any",[519,2249,2250],{"class":728},"[]",[519,2252,757],{"class":686},[519,2254,2255],{"class":678}," =>",[519,2257,2258],{"class":682}," T",[519,2260,708],{"class":686},[519,2262,2263],{"class":521,"line":534},[519,2264,1180],{"emptyLinePlaceholder":1179},[519,2266,2267,2270,2273,2275,2278,2280,2282,2285,2288,2290,2293,2295],{"class":521,"line":540},[519,2268,2269],{"class":678},"function",[519,2271,2272],{"class":919}," Timestamped",[519,2274,1347],{"class":686},[519,2276,2277],{"class":682},"TBase",[519,2279,1947],{"class":678},[519,2281,2222],{"class":682},[519,2283,2284],{"class":686},">(",[519,2286,2287],{"class":739},"Base",[519,2289,702],{"class":686},[519,2291,2292],{"class":682}," TBase",[519,2294,757],{"class":686},[519,2296,687],{"class":686},[519,2298,2299,2302,2304,2306,2309],{"class":521,"line":546},[519,2300,2301],{"class":832},"    return",[519,2303,1834],{"class":678},[519,2305,1947],{"class":678},[519,2307,2308],{"class":682}," Base",[519,2310,687],{"class":686},[519,2312,2313,2316,2319,2321,2324],{"class":521,"line":552},[519,2314,2315],{"class":698},"        createdAt ",[519,2317,2318],{"class":686},"=",[519,2320,916],{"class":686},[519,2322,2323],{"class":698}," Date()",[519,2325,708],{"class":686},[519,2327,2328],{"class":521,"line":558},[519,2329,2330],{"class":686},"    };\n",[519,2332,2333],{"class":521,"line":564},[519,2334,664],{"class":686},[519,2336,2337],{"class":521,"line":570},[519,2338,1180],{"emptyLinePlaceholder":1179},[519,2340,2341,2343,2346,2348,2350,2352,2354,2356,2358,2360,2362,2364],{"class":521,"line":576},[519,2342,2269],{"class":678},[519,2344,2345],{"class":919}," Tagged",[519,2347,1347],{"class":686},[519,2349,2277],{"class":682},[519,2351,1947],{"class":678},[519,2353,2222],{"class":682},[519,2355,2284],{"class":686},[519,2357,2287],{"class":739},[519,2359,702],{"class":686},[519,2361,2292],{"class":682},[519,2363,757],{"class":686},[519,2365,687],{"class":686},[519,2367,2368,2370,2372,2374,2376],{"class":521,"line":581},[519,2369,2301],{"class":832},[519,2371,1834],{"class":678},[519,2373,1947],{"class":678},[519,2375,2308],{"class":682},[519,2377,687],{"class":686},[519,2379,2380,2383,2385,2387,2390,2392,2395],{"class":521,"line":587},[519,2381,2382],{"class":698},"        tags",[519,2384,702],{"class":686},[519,2386,721],{"class":682},[519,2388,2389],{"class":698},"[] ",[519,2391,2318],{"class":686},[519,2393,2394],{"class":698}," []",[519,2396,708],{"class":686},[519,2398,2399],{"class":521,"line":593},[519,2400,2330],{"class":686},[519,2402,2403],{"class":521,"line":599},[519,2404,664],{"class":686},[519,2406,2407],{"class":521,"line":604},[519,2408,1180],{"emptyLinePlaceholder":1179},[519,2410,2411,2413,2416,2418,2421,2423,2425,2427,2429,2431,2433,2436],{"class":521,"line":610},[519,2412,679],{"class":678},[519,2414,2415],{"class":682}," User",[519,2417,829],{"class":686},[519,2419,2420],{"class":678}," constructor",[519,2422,736],{"class":686},[519,2424,1848],{"class":678},[519,2426,1854],{"class":739},[519,2428,702],{"class":686},[519,2430,721],{"class":682},[519,2432,757],{"class":686},[519,2434,2435],{"class":686}," {}",[519,2437,844],{"class":686},[519,2439,2440,2442,2445,2447,2449,2451,2454,2457],{"class":521,"line":616},[519,2441,679],{"class":678},[519,2443,2444],{"class":682}," TaggedTimestampedUser",[519,2446,1947],{"class":678},[519,2448,2272],{"class":919},[519,2450,736],{"class":728},[519,2452,2453],{"class":919},"Tagged",[519,2455,2456],{"class":728},"(User)) ",[519,2458,2459],{"class":686},"{}\n",[519,2461,2462],{"class":521,"line":622},[519,2463,1180],{"emptyLinePlaceholder":1179},[519,2465,2466,2469,2472,2474,2476,2478,2480,2482,2485,2487,2489],{"class":521,"line":627},[519,2467,2468],{"class":678},"const",[519,2470,2471],{"class":728}," u ",[519,2473,2318],{"class":686},[519,2475,916],{"class":686},[519,2477,2444],{"class":919},[519,2479,736],{"class":728},[519,2481,925],{"class":686},[519,2483,2484],{"class":928},"Alice",[519,2486,925],{"class":686},[519,2488,757],{"class":728},[519,2490,708],{"class":686},[519,2492,2493,2496,2498,2501,2503,2506,2508,2510,2513,2515,2517],{"class":521,"line":632},[519,2494,2495],{"class":728},"u",[519,2497,1067],{"class":686},[519,2499,2500],{"class":728},"tags",[519,2502,1067],{"class":686},[519,2504,2505],{"class":919},"push",[519,2507,736],{"class":728},[519,2509,925],{"class":686},[519,2511,2512],{"class":928},"vip",[519,2514,925],{"class":686},[519,2516,757],{"class":728},[519,2518,708],{"class":686},[519,2520,2521,2523,2525,2528,2530],{"class":521,"line":638},[519,2522,2495],{"class":728},[519,2524,1067],{"class":686},[519,2526,2527],{"class":728},"createdAt",[519,2529,841],{"class":686},[519,2531,2532],{"class":692},"     \u002F\u002F có sẵn\n",[427,2534,2536],{"id":2535},"_4-polymorphism-đa-hình","4. Polymorphism — đa hình",[493,2538,2539],{},[470,2540,2541],{},[474,2542,2543],{},"Cùng API, nhiều behavior — runtime quyết.",[1087,2545,2547],{"id":2546},"_2-loại-chính","2 loại chính",[432,2549,2550,2555],{},[435,2551,2554],{"name":2552,"type":2553},"Compile-time","Overloading","Cùng tên, khác signature. C# hỗ trợ, TS hỗ trợ qua signature overload (declaration only).",[435,2556,2559,2562,2563,2565,2566,2569],{"name":2557,"type":2558},"Runtime","Overriding",[516,2560,2561],{},"virtual","\u002F",[516,2564,1831],{}," ở cha, ",[516,2567,2568],{},"override"," ở con. Runtime quyết qua vtable.",[501,2571,2572,2609,2741,2773],{},[504,2573,2575],{"icon":506,"label":2574},"C# Overriding",[509,2576,2578],{"className":511,"code":2577,"language":513,"meta":514,"style":514},"Animal[] zoo = { new Dog(\"Rex\"), new Cat(\"Tom\") };\nforeach (var a in zoo) {\n    Console.WriteLine($\"{a.Name}: {a.Speak()}\");\n    \u002F\u002F Runtime gọi Dog.Speak() hoặc Cat.Speak() đúng,\n    \u002F\u002F dù biến a kiểu Animal\n}\n",[516,2579,2580,2585,2590,2595,2600,2605],{"__ignoreMap":514},[519,2581,2582],{"class":521,"line":522},[519,2583,2584],{},"Animal[] zoo = { new Dog(\"Rex\"), new Cat(\"Tom\") };\n",[519,2586,2587],{"class":521,"line":528},[519,2588,2589],{},"foreach (var a in zoo) {\n",[519,2591,2592],{"class":521,"line":534},[519,2593,2594],{},"    Console.WriteLine($\"{a.Name}: {a.Speak()}\");\n",[519,2596,2597],{"class":521,"line":540},[519,2598,2599],{},"    \u002F\u002F Runtime gọi Dog.Speak() hoặc Cat.Speak() đúng,\n",[519,2601,2602],{"class":521,"line":546},[519,2603,2604],{},"    \u002F\u002F dù biến a kiểu Animal\n",[519,2606,2607],{"class":521,"line":552},[519,2608,664],{},[504,2610,2612],{"icon":289,"label":2611},"TS Overriding",[509,2613,2615],{"className":669,"code":2614,"language":671,"meta":514,"style":514},"const zoo: Animal[] = [new Dog(\"Rex\"), new Cat(\"Tom\")];\nfor (const a of zoo) {\n    console.log(`${a.name}: ${a.speak()}`);\n}\n",[516,2616,2617,2671,2692,2737],{"__ignoreMap":514},[519,2618,2619,2621,2624,2626,2628,2630,2632,2635,2638,2640,2642,2644,2647,2649,2651,2653,2655,2657,2659,2661,2664,2666,2669],{"class":521,"line":522},[519,2620,2468],{"class":678},[519,2622,2623],{"class":728}," zoo",[519,2625,702],{"class":686},[519,2627,1837],{"class":682},[519,2629,2389],{"class":728},[519,2631,2318],{"class":686},[519,2633,2634],{"class":728}," [",[519,2636,2637],{"class":686},"new",[519,2639,1944],{"class":919},[519,2641,736],{"class":728},[519,2643,925],{"class":686},[519,2645,2646],{"class":928},"Rex",[519,2648,925],{"class":686},[519,2650,757],{"class":728},[519,2652,747],{"class":686},[519,2654,916],{"class":686},[519,2656,2057],{"class":919},[519,2658,736],{"class":728},[519,2660,925],{"class":686},[519,2662,2663],{"class":928},"Tom",[519,2665,925],{"class":686},[519,2667,2668],{"class":728},")]",[519,2670,708],{"class":686},[519,2672,2673,2676,2678,2680,2683,2686,2689],{"class":521,"line":528},[519,2674,2675],{"class":832},"for",[519,2677,900],{"class":728},[519,2679,2468],{"class":678},[519,2681,2682],{"class":728}," a ",[519,2684,2685],{"class":686},"of",[519,2687,2688],{"class":728}," zoo) ",[519,2690,2691],{"class":686},"{\n",[519,2693,2694,2697,2699,2701,2703,2705,2708,2710,2712,2714,2717,2720,2722,2724,2727,2730,2733,2735],{"class":521,"line":534},[519,2695,2696],{"class":728},"    console",[519,2698,1067],{"class":686},[519,2700,1885],{"class":919},[519,2702,736],{"class":698},[519,2704,1890],{"class":686},[519,2706,2707],{"class":728},"a",[519,2709,1067],{"class":686},[519,2711,1896],{"class":728},[519,2713,1899],{"class":686},[519,2715,2716],{"class":928},": ",[519,2718,2719],{"class":686},"${",[519,2721,2707],{"class":728},[519,2723,1067],{"class":686},[519,2725,2726],{"class":919},"speak",[519,2728,2729],{"class":728},"()",[519,2731,2732],{"class":686},"}`",[519,2734,757],{"class":698},[519,2736,708],{"class":686},[519,2738,2739],{"class":521,"line":540},[519,2740,664],{"class":686},[504,2742,2744],{"icon":506,"label":2743},"C# Overloading",[509,2745,2747],{"className":511,"code":2746,"language":513,"meta":514,"style":514},"public class Calculator {\n    public int Add(int a, int b) => a + b;\n    public double Add(double a, double b) => a + b;\n    public string Add(string a, string b) => a + b;\n}\n",[516,2748,2749,2754,2759,2764,2769],{"__ignoreMap":514},[519,2750,2751],{"class":521,"line":522},[519,2752,2753],{},"public class Calculator {\n",[519,2755,2756],{"class":521,"line":528},[519,2757,2758],{},"    public int Add(int a, int b) => a + b;\n",[519,2760,2761],{"class":521,"line":534},[519,2762,2763],{},"    public double Add(double a, double b) => a + b;\n",[519,2765,2766],{"class":521,"line":540},[519,2767,2768],{},"    public string Add(string a, string b) => a + b;\n",[519,2770,2771],{"class":521,"line":546},[519,2772,664],{},[504,2774,2776,2888],{"icon":289,"label":2775},"TS Overloading",[509,2777,2779],{"className":669,"code":2778,"language":671,"meta":514,"style":514},"class Calculator {\n    add(a: number, b: number): number;\n    add(a: string, b: string): string;\n    add(a: any, b: any): any { return a + b; }\n}\n",[516,2780,2781,2790,2818,2844,2884],{"__ignoreMap":514},[519,2782,2783,2785,2788],{"class":521,"line":522},[519,2784,679],{"class":678},[519,2786,2787],{"class":682}," Calculator",[519,2789,687],{"class":686},[519,2791,2792,2795,2797,2799,2801,2803,2805,2808,2810,2812,2814,2816],{"class":521,"line":528},[519,2793,2794],{"class":698},"    add",[519,2796,736],{"class":686},[519,2798,2707],{"class":739},[519,2800,702],{"class":686},[519,2802,705],{"class":682},[519,2804,747],{"class":686},[519,2806,2807],{"class":739}," b",[519,2809,702],{"class":686},[519,2811,705],{"class":682},[519,2813,887],{"class":686},[519,2815,705],{"class":682},[519,2817,708],{"class":686},[519,2819,2820,2822,2824,2826,2828,2830,2832,2834,2836,2838,2840,2842],{"class":521,"line":534},[519,2821,2794],{"class":698},[519,2823,736],{"class":686},[519,2825,2707],{"class":739},[519,2827,702],{"class":686},[519,2829,721],{"class":682},[519,2831,747],{"class":686},[519,2833,2807],{"class":739},[519,2835,702],{"class":686},[519,2837,721],{"class":682},[519,2839,887],{"class":686},[519,2841,721],{"class":682},[519,2843,708],{"class":686},[519,2845,2846,2848,2850,2852,2854,2856,2858,2860,2862,2864,2866,2868,2870,2872,2875,2878,2880,2882],{"class":521,"line":540},[519,2847,2794],{"class":698},[519,2849,736],{"class":686},[519,2851,2707],{"class":739},[519,2853,702],{"class":686},[519,2855,2247],{"class":682},[519,2857,747],{"class":686},[519,2859,2807],{"class":739},[519,2861,702],{"class":686},[519,2863,2247],{"class":682},[519,2865,887],{"class":686},[519,2867,2247],{"class":682},[519,2869,829],{"class":686},[519,2871,833],{"class":832},[519,2873,2874],{"class":728}," a",[519,2876,2877],{"class":686}," +",[519,2879,2807],{"class":728},[519,2881,841],{"class":686},[519,2883,844],{"class":686},[519,2885,2886],{"class":521,"line":546},[519,2887,664],{"class":686},[470,2889,2890,2891,2894],{},"TS overload chỉ ở signature, body ",[474,2892,2893],{},"một cái"," xử lý hết.",[465,2896,2897,2905],{"color":467,"icon":468},[470,2898,472,2899,477,2902],{},[474,2900,2901],{},"Câu PV kinh điển:",[446,2903,2904],{},"\"Đa hình runtime hoạt động ra sao?\"",[493,2906,2907,2917,2932],{},[470,2908,2909,2910,2913,2914,702],{},"\"Runtime polymorphism qua ",[474,2911,2912],{},"vtable"," (virtual method table). Mỗi class có 1 vtable lưu pointer tới method virtual. Khi gọi ",[516,2915,2916],{},"a.Speak()",[2918,2919,2920,2923,2929],"ol",{},[1057,2921,2922],{},"Runtime lookup vtable của object thực (Dog\u002FCat) qua type tag.",[1057,2924,2925,2926,1067],{},"Tìm slot tương ứng method ",[516,2927,2928],{},"Speak",[1057,2930,2931],{},"Gọi function pointer trong slot đó.",[470,2933,2934,2935,2938],{},"Đó là vì sao virtual method ",[474,2936,2937],{},"chậm hơn rất ít"," static — phải qua 1 cấp indirection.\"",[1087,2940,2942],{"id":2941},"ad-hoc-polymorphism-overloading-vs-subtype-polymorphism-overriding","Ad-hoc polymorphism (overloading) vs Subtype polymorphism (overriding)",[1054,2944,2945,2951],{},[1057,2946,2947,2950],{},[474,2948,2949],{},"Ad-hoc",": cùng tên, signature khác, compile chọn.",[1057,2952,2953,2956],{},[474,2954,2955],{},"Subtype",": cùng signature, type khác, runtime chọn.",[470,2958,2959,2960,2963,2964,2966],{},"(Còn 1 loại nữa — ",[474,2961,2962],{},"Parametric polymorphism"," = generic. Xem section ",[2707,2965,334],{"href":335},".)",[427,2968,2970],{"id":2969},"bonus-composition-vs-inheritance","Bonus — Composition vs Inheritance",[465,2972,2973,2978],{"color":1046,"icon":1047},[470,2974,2975,2977],{},[474,2976,2178],{}," — quy tắc thực dụng cực mạnh.",[1054,2979,2980,2990],{},[1057,2981,2982,2985,2986,2989],{},[474,2983,2984],{},"Inheritance"," \"is-a\": Dog ",[474,2987,2988],{},"IS-A"," Animal.",[1057,2991,2992,2995,2996,2999],{},[474,2993,2994],{},"Composition"," \"has-a\": Car ",[474,2997,2998],{},"HAS-A"," Engine.",[509,3001,3003],{"className":511,"code":3002,"language":513,"meta":514,"style":514},"\u002F\u002F ❌ Lạm dụng inheritance — hierarchy phình to\npublic class Vehicle { ... }\npublic class Car : Vehicle { ... }\npublic class ElectricCar : Car { ... }\npublic class TeslaCar : ElectricCar { ... }\n\u002F\u002F 4 cấp → fragile, khó test, khó thay đổi\n\n\u002F\u002F ✅ Composition — Car HAS-A IEngine\npublic interface IEngine { void Start(); }\npublic class GasEngine : IEngine { public void Start() {} }\npublic class ElectricEngine : IEngine { public void Start() {} }\n\npublic class Car {\n    private readonly IEngine _engine;\n    public Car(IEngine engine) => _engine = engine;\n    public void Drive() => _engine.Start();\n}\n\n\u002F\u002F Đổi Car điện = inject ElectricEngine, không sửa Car\n",[516,3004,3005,3010,3015,3020,3025,3030,3035,3039,3044,3049,3054,3059,3063,3068,3073,3078,3083,3087,3091],{"__ignoreMap":514},[519,3006,3007],{"class":521,"line":522},[519,3008,3009],{},"\u002F\u002F ❌ Lạm dụng inheritance — hierarchy phình to\n",[519,3011,3012],{"class":521,"line":528},[519,3013,3014],{},"public class Vehicle { ... }\n",[519,3016,3017],{"class":521,"line":534},[519,3018,3019],{},"public class Car : Vehicle { ... }\n",[519,3021,3022],{"class":521,"line":540},[519,3023,3024],{},"public class ElectricCar : Car { ... }\n",[519,3026,3027],{"class":521,"line":546},[519,3028,3029],{},"public class TeslaCar : ElectricCar { ... }\n",[519,3031,3032],{"class":521,"line":552},[519,3033,3034],{},"\u002F\u002F 4 cấp → fragile, khó test, khó thay đổi\n",[519,3036,3037],{"class":521,"line":558},[519,3038,1180],{"emptyLinePlaceholder":1179},[519,3040,3041],{"class":521,"line":564},[519,3042,3043],{},"\u002F\u002F ✅ Composition — Car HAS-A IEngine\n",[519,3045,3046],{"class":521,"line":570},[519,3047,3048],{},"public interface IEngine { void Start(); }\n",[519,3050,3051],{"class":521,"line":576},[519,3052,3053],{},"public class GasEngine : IEngine { public void Start() {} }\n",[519,3055,3056],{"class":521,"line":581},[519,3057,3058],{},"public class ElectricEngine : IEngine { public void Start() {} }\n",[519,3060,3061],{"class":521,"line":587},[519,3062,1180],{"emptyLinePlaceholder":1179},[519,3064,3065],{"class":521,"line":593},[519,3066,3067],{},"public class Car {\n",[519,3069,3070],{"class":521,"line":599},[519,3071,3072],{},"    private readonly IEngine _engine;\n",[519,3074,3075],{"class":521,"line":604},[519,3076,3077],{},"    public Car(IEngine engine) => _engine = engine;\n",[519,3079,3080],{"class":521,"line":610},[519,3081,3082],{},"    public void Drive() => _engine.Start();\n",[519,3084,3085],{"class":521,"line":616},[519,3086,664],{},[519,3088,3089],{"class":521,"line":622},[519,3090,1180],{"emptyLinePlaceholder":1179},[519,3092,3093],{"class":521,"line":627},[519,3094,3095],{},"\u002F\u002F Đổi Car điện = inject ElectricEngine, không sửa Car\n",[427,3097,3099],{"id":3098},"bốn-tính-chất-trong-1-ví-dụ","Bốn tính chất trong 1 ví dụ",[470,3101,3102,3103,3106],{},"Đây là code minh hoạ ",[474,3104,3105],{},"đủ 4 tính chất"," trong cùng 1 mini-app:",[509,3108,3110],{"className":511,"code":3109,"language":513,"meta":514,"style":514},"\u002F\u002F Abstraction\npublic interface IShape {\n    double Area();\n    double Perimeter();\n}\n\n\u002F\u002F Abstract + Inheritance + Encapsulation\npublic abstract class ShapeBase : IShape {\n    public string Name { get; }                    \u002F\u002F encapsulation\n    protected ShapeBase(string name) => Name = name;\n    public abstract double Area();\n    public abstract double Perimeter();\n    public override string ToString() =>\n        $\"{Name}: area={Area():F2}, perimeter={Perimeter():F2}\";\n}\n\n\u002F\u002F Inheritance + Polymorphism\npublic class Circle : ShapeBase {\n    private readonly double _r;\n    public Circle(double r) : base(\"Circle\") => _r = r;\n    public override double Area() => Math.PI * _r * _r;\n    public override double Perimeter() => 2 * Math.PI * _r;\n}\n\npublic class Rectangle : ShapeBase {\n    private readonly double _w, _h;\n    public Rectangle(double w, double h) : base(\"Rectangle\") { _w = w; _h = h; }\n    public override double Area() => _w * _h;\n    public override double Perimeter() => 2 * (_w + _h);\n}\n\n\u002F\u002F Polymorphism in action\nIShape[] shapes = { new Circle(5), new Rectangle(3, 4) };\nforeach (var s in shapes) Console.WriteLine(s);\n",[516,3111,3112,3117,3122,3127,3132,3136,3140,3145,3150,3155,3160,3165,3170,3175,3180,3184,3188,3193,3198,3203,3208,3213,3218,3222,3226,3231,3236,3241,3246,3251,3255,3259,3265,3271],{"__ignoreMap":514},[519,3113,3114],{"class":521,"line":522},[519,3115,3116],{},"\u002F\u002F Abstraction\n",[519,3118,3119],{"class":521,"line":528},[519,3120,3121],{},"public interface IShape {\n",[519,3123,3124],{"class":521,"line":534},[519,3125,3126],{},"    double Area();\n",[519,3128,3129],{"class":521,"line":540},[519,3130,3131],{},"    double Perimeter();\n",[519,3133,3134],{"class":521,"line":546},[519,3135,664],{},[519,3137,3138],{"class":521,"line":552},[519,3139,1180],{"emptyLinePlaceholder":1179},[519,3141,3142],{"class":521,"line":558},[519,3143,3144],{},"\u002F\u002F Abstract + Inheritance + Encapsulation\n",[519,3146,3147],{"class":521,"line":564},[519,3148,3149],{},"public abstract class ShapeBase : IShape {\n",[519,3151,3152],{"class":521,"line":570},[519,3153,3154],{},"    public string Name { get; }                    \u002F\u002F encapsulation\n",[519,3156,3157],{"class":521,"line":576},[519,3158,3159],{},"    protected ShapeBase(string name) => Name = name;\n",[519,3161,3162],{"class":521,"line":581},[519,3163,3164],{},"    public abstract double Area();\n",[519,3166,3167],{"class":521,"line":587},[519,3168,3169],{},"    public abstract double Perimeter();\n",[519,3171,3172],{"class":521,"line":593},[519,3173,3174],{},"    public override string ToString() =>\n",[519,3176,3177],{"class":521,"line":599},[519,3178,3179],{},"        $\"{Name}: area={Area():F2}, perimeter={Perimeter():F2}\";\n",[519,3181,3182],{"class":521,"line":604},[519,3183,664],{},[519,3185,3186],{"class":521,"line":610},[519,3187,1180],{"emptyLinePlaceholder":1179},[519,3189,3190],{"class":521,"line":616},[519,3191,3192],{},"\u002F\u002F Inheritance + Polymorphism\n",[519,3194,3195],{"class":521,"line":622},[519,3196,3197],{},"public class Circle : ShapeBase {\n",[519,3199,3200],{"class":521,"line":627},[519,3201,3202],{},"    private readonly double _r;\n",[519,3204,3205],{"class":521,"line":632},[519,3206,3207],{},"    public Circle(double r) : base(\"Circle\") => _r = r;\n",[519,3209,3210],{"class":521,"line":638},[519,3211,3212],{},"    public override double Area() => Math.PI * _r * _r;\n",[519,3214,3215],{"class":521,"line":644},[519,3216,3217],{},"    public override double Perimeter() => 2 * Math.PI * _r;\n",[519,3219,3220],{"class":521,"line":650},[519,3221,664],{},[519,3223,3224],{"class":521,"line":656},[519,3225,1180],{"emptyLinePlaceholder":1179},[519,3227,3228],{"class":521,"line":661},[519,3229,3230],{},"public class Rectangle : ShapeBase {\n",[519,3232,3233],{"class":521,"line":1270},[519,3234,3235],{},"    private readonly double _w, _h;\n",[519,3237,3238],{"class":521,"line":1275},[519,3239,3240],{},"    public Rectangle(double w, double h) : base(\"Rectangle\") { _w = w; _h = h; }\n",[519,3242,3243],{"class":521,"line":1281},[519,3244,3245],{},"    public override double Area() => _w * _h;\n",[519,3247,3248],{"class":521,"line":1287},[519,3249,3250],{},"    public override double Perimeter() => 2 * (_w + _h);\n",[519,3252,3253],{"class":521,"line":1293},[519,3254,664],{},[519,3256,3257],{"class":521,"line":1298},[519,3258,1180],{"emptyLinePlaceholder":1179},[519,3260,3262],{"class":521,"line":3261},32,[519,3263,3264],{},"\u002F\u002F Polymorphism in action\n",[519,3266,3268],{"class":521,"line":3267},33,[519,3269,3270],{},"IShape[] shapes = { new Circle(5), new Rectangle(3, 4) };\n",[519,3272,3274],{"class":521,"line":3273},34,[519,3275,3276],{},"foreach (var s in shapes) Console.WriteLine(s);\n",[465,3278,3280,3281],{"color":1046,"icon":3279},"i-lucide-arrow-right","Tiếp theo: ",[2707,3282,3283],{"href":323},"SOLID — 5 nguyên lý",[3285,3286,3287],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":514,"searchDepth":528,"depth":528,"links":3289},[3290,3291,3294,3295,3299,3303,3304],{"id":429,"depth":528,"text":430},{"id":490,"depth":528,"text":491,"children":3292},[3293],{"id":1089,"depth":534,"text":1090},{"id":1133,"depth":528,"text":1134},{"id":1695,"depth":528,"text":1696,"children":3296},[3297,3298],{"id":2159,"depth":534,"text":2160},{"id":2182,"depth":534,"text":2183},{"id":2535,"depth":528,"text":2536,"children":3300},[3301,3302],{"id":2546,"depth":534,"text":2547},{"id":2941,"depth":534,"text":2942},{"id":2969,"depth":528,"text":2970},{"id":3098,"depth":528,"text":3099},"Encapsulation, Abstraction, Inheritance, Polymorphism — định nghĩa, ví dụ song song C# \u002F TypeScript, biến thể nâng cao.","md",null,{},{"title":317,"icon":320},{"title":422,"description":3305},"LgySvq6oRyAKNQTMerZ7c3YRsCkx0NLDabHdOo_wssA",[3313,3315],{"title":311,"path":312,"stem":313,"description":3314,"icon":81,"children":-1},"OOP language-agnostic — 4 tính chất, SOLID, design pattern. Ví dụ song song C# và TypeScript.",{"title":322,"path":323,"stem":324,"description":3316,"icon":325,"children":-1},"SRP, OCP, LSP, ISP, DIP — case study refactor mỗi nguyên lý. Ví dụ C# + TypeScript.",1783490358296]