【Java】Java核心知識點與相應面試技巧(七)——類與對象(二)

Java 類與對象篇

1.上期面試題解析:


上文鏈接:https://blog.csdn.net/weixin_73492487/article/details/146607026


  1. 創建對象時的內存分配過程?

① 加載類 ② 堆內存分配空間 ③ 默認初始化 ④ 顯式初始化 ⑤ 構造器執行

  1. this和super能否同時出現?

不能,二者都必須位于構造器首行

  1. 以下代碼輸出什么?
    class A {int i = 10;void print() { System.out.println(i); }
    }class B extends A {int i = 20;public static void main(String[] args) {new B().print(); }
    }
    

輸出10(方法看運行時類型,字段看編譯時類型)
方法看運行時類型:在 Java 中,方法的調用是動態綁定的,這意味著方法的調用是基于實際對象的類型來決定的,而不是對象的聲明類型。
字段看編譯時類型:而字段的訪問是靜態綁定的,即編譯時綁定。即使對象的實際類型發生了變化,編譯時類型決定了我們訪問的是哪個字段。也就是說,字段的訪問與對象的聲明類型相關,而與實際類型無關,不受運行時類型影響。

2.多態(Polymorphism)

2.1 實現條件

  • 繼承體系:存在父子類關系
  • 方法重寫:子類重寫父類方法
  • 向上轉型:父類引用指向子類對象(向上轉型:低轉高,自動轉換)
    Animal animal = new Dog(); // 向上轉型
    

2.2 動態綁定機制

class Animal {void sound() { System.out.println("Animal sound"); }
}class Dog extends Animal {@Overridevoid sound() { System.out.println("Woof!"); }
}public class Test {public static void main(String[] args) {Animal a = new Dog();a.sound(); // 輸出"Woof!"(運行時類型決定方法調用)}
}

核心特性

  • 編譯看左邊(檢查父類是否存在該方法,聲明/引用決定可以調用的方法,若不存在該方法,則編譯錯誤)
  • 運行看右邊(實際執行子類重寫方法,引用指向的對象具體決定調用的方法)
  • 成員變量無多態(編譯運行都看左邊)

3. instanceof 與類型轉換

3.1 類型檢查

Object obj = new String("Hello");
if(obj instanceof String) { // 返回trueSystem.out.println("是字符串類型");
}

分析:instanceof 用于判斷一個對象是否是某個類的實例,或者是否實現了某個接口,并且返回一個布爾值

2.2 類型轉換規則

轉換類型語法風險
向上轉型自動轉換無風險
向下轉型強制轉換 + 類型檢查可能拋出ClassCastException

分析:在進行類型轉換之前,可以使用 instanceof 來判斷是否可以安全地進行轉換,從而避免 ClassCastException。

安全轉換模式

if(animal instanceof Dog) {Dog dog = (Dog)animal; // 安全轉換
}

父類與子類間的類型轉換:

//父類Animal
class Animal {public void eat() {System.out.println("Animal is eating");}
}//子類Dog繼承了父類的eat方法
class Dog extends Animal {public void bark() {System.out.println("Dog is barking");}
}public class Test {public static void main(String[] args) {//一個對象的實際類型是確定的,但可以指向的引用類型就不確定了//父類引用指向了子類Animal animal = new Dog();animal.eat();  // 可以調用 Animal 類中的方法// animal.bark();  // 編譯錯誤,Animal 類型沒有 bark 方法if (animal instanceof Dog) {Dog dog = (Dog) animal;  // 強制類型轉換dog.bark();  // 可以調用 Dog 類中的 bark 方法}}
}

4. static 關鍵字詳解

4.1 靜態成員 vs 實例成員

維度靜態成員實例成員
所屬層級類級別對象級別
內存分配類加載時初始化對象創建時分配
訪問方式類名.成員 或 對象.成員必須通過對象訪問
生命周期與類共存亡隨對象回收而銷毀
線程安全需額外同步控制實例隔離更安全

4.2 靜態代碼塊與初始化順序

class MyClass {static int staticVar;	//靜態變量int instanceVar;// 靜態代碼塊(類加載時執行一次,只執行一次)static {staticVar = 100;System.out.println("靜態代碼塊");}// 實例代碼塊(每次new對象時執行,用于賦初始值){instanceVar = 50;System.out.println("實例代碼塊");}public MyClass(){System.out.println("構造方法");}
}public class Test{public static void main(String[] args){MyClass mc=new MyClass();System.out.println("==========");MyClass ms=new MyClass();}
}

初始化順序
靜態變量/代碼塊 → 實例變量/代碼塊 → 構造器

輸出:
靜態代碼塊
實例代碼塊
構造方法
==========
實例代碼塊
構造方法

4.3 static修飾特性

靜態變量:
  • 靜態變量被所有實例共享
  • 靜態變量在內存中只有一份副本
  • 靜態變量的生命周期與類的生命周期相同,即在類加載時分配內存,直到程序結束時才釋放(從屬于類)
靜態方法:
  • 靜態方法只能訪問靜態變量和調用其他靜態方法
  • 可以通過類名直接調用,且不能直接訪問實例變量和實例方法
  • 不能使用this/super關鍵字
  • 不能被重寫(但可隱藏)
class Parent {static void staticMethod() {System.out.println("Parent static method");}
}class Child extends Parent {//與父類方法相獨立static void staticMethod() {System.out.println("Child static method");}
}public class Test {public static void main(String[] args) {Parent p = new Parent();Parent c = new Child();Child d = new Child();p.staticMethod();  // 輸出 "Parent static method"c.staticMethod();  // 輸出 "Parent static method" (靜態方法調用是根據引用類型來決定的)d.staticMethod();  // 輸出 "Child static method" (靜態方法調用是根據引用類型來決定的)//靜態方法是屬于類的,而不是對象的。所以,當你調用靜態方法時,它是通過類名來解析的,而不是通過對象引用來解析//當子類定義了一個與父類中靜態方法相同的方法時,在子類中的靜態方法不會被真正地“重寫”,父類和子類的靜態方法仍然是相互獨立的。}
}
靜態代碼塊:
  • 靜態代碼塊在類加載時自動執行,且只執行一次。
  • 通常用于靜態變量的初始化。
靜態導入:
  • 使用 import static 語句導入類的靜態成員,可以直接訪問類的靜態方法或靜態變量。
import static java.lang.Math.*;public class Test {public static void main(String[] args) {double result = sqrt(25);  // 直接使用 Math 類中的 sqrt 方法,無需寫類名(Math.sqrt())System.out.println(result);  // 輸出 5.0}
}
靜態內部類(由 static 修飾的內部類):
  • 靜態內部類不依賴外部類的實例,可以直接創建
  • 可以訪問外部類的靜態成員,但不能訪問外部類的實例成員和實例方法
class Outer {static int staticVar = 10;int var; 	//靜態內部類不可訪問//由static修飾的內部類(靜態內部類)static class Inner {void display() {System.out.println("Static Inner class, staticVar: " + staticVar);}}
}public class Test {public static void main(String[] args) {Outer.Inner inner = new Outer.Inner();  // 直接通過外部類創建靜態內部類的實例inner.display();  }
}

輸出:
Static Inner class, staticVar: 10


5. 抽象類(Abstract Class)

5.1 定義與特征

abstract class Animal {// 抽象方法abstract void sound();// 非抽象方法/具體方法(子類會繼承)void sleep() {System.out.println("Sleeping...");}
}class Dog extends Animal {// 實現抽象方法@Overridevoid sound() {System.out.println("Bark");}
}public class Test {public static void main(String[] args) {Animal animal = new Dog();animal.sound(); // 輸出 "Bark"animal.sleep(); // 輸出 "Sleeping..."}
}

定義:
抽象類是一種不能直接實例化的類。它可以包含抽象方法和非抽象方法。抽象方法是沒有實現的方法,只有方法的聲明,沒有方法體,子類需要實現這些抽象方法。抽象類通常用于定義一種通用的模板或接口,子類繼承它并提供具體的實現。

核心特性

  • abstract關鍵字修飾
  • 不能實例化(只能被繼承
  • 可以包含抽象方法和具體方法(抽象方法必須在抽象類中)
    • 抽象方法:沒有方法體,必須在子類中實現。
    • 非抽象方法:有方法體,子類可以繼承并使用,也可以覆蓋(重寫)
  • 子類必須實現(重寫)所有抽象方法(除非子類也是抽象類,那么就需要子類的子類去實現這些抽象方法)
  • 可以包含構造方法:抽象類可以有構造方法,子類通過super()調用父類的構造方法。
  • 可以包含成員變量(任意訪問修飾符)
abstract class Shape {//成員變量int x, y;// 抽象類的構造方法,初始化共同的屬性public Shape(int x, int y) {this.x = x;this.y = y;}//抽象方法,必須實現abstract void draw();
}class Circle extends Shape {int radius;public Circle(int x, int y, int radius) {super(x, y);  // 調用父類構造方法this.radius = radius;}@Overridevoid draw() {System.out.println("Drawing a circle at (" + x + ", " + y + ") with radius " + radius);}
}public class Test {public static void main(String[] args) {Circle circle = new Circle(5, 10, 7);circle.draw();  // 輸出: Drawing a circle at (5, 10) with radius 7}
}

5.2 使用場景

  • 代碼復用:多個子類共享部分實現
  • 模板方法模式:定義算法框架,具體步驟由子類實現
  • 強制規范:要求子類必須實現特定功能

6. 接口(Interface)

6.1 定義與演進

// Java 8+ 接口(是一種約束,只有抽象方法)
public interface Flyable {// 常量(默認 public static final)double MAX_SPEED = 1000.0;// 抽象方法(默認 public abstract)void fly();// 默認方法(Java 8+)默認方法有方法體,可以提供默認實現。//默認方法是 可選 的,接口的實現類可以選擇覆蓋它,也可以使用接口提供的默認實現。default void land() {System.out.println("Landing...");}// 靜態方法(Java 8+),可以通過接口直接調用,而不需要依賴于接口的實現類。//靜態方法 不能被實現類重寫,因為它屬于接口本身。static void showMaxSpeed() {System.out.println("Max speed: " + MAX_SPEED);}// 私有方法(Java 9+)只能在接口內部使用,不能被接口的實現類直接訪問。private void checkSpeed() {// 內部復用代碼}
}

定義:
接口是一個抽象類型,它是類與類之間的一種協議,用來指定類必須實現的方法。接口只包含 抽象方法(沒有方法體)和 常量,從 Java 8 開始,接口也可以包含 默認方法(有實現)和 靜態方法。

核心特性

  • 不能直接實例化: 你不能創建接口的對象,必須通過實現接口的類來實例化對象
  • 沒有構造方法: 接口沒有構造方法,因此不能創建接口實例
  • implements實現,支持多繼承多實現(一個類可實現多個接口)
  • 所有方法默認public abstract(Java 8前)
  • 變量默認public static final
  • Java 8+ 支持默認方法和靜態方法
  • Java 9+ 支持私有方法

示例:

interface Logger {private void log(String message) {System.out.println("Logging message: " + message);}default void info(String message) {log(message);  // 接口調用自身私有方法}default void warn(String message) {log(message);  // 接口調用自身私有方法}
}class MyLogger implements Logger {// 不需要實現 log() 方法,只需要調用 info() 或 warn() 方法,來提示登陸信息
}public class Test {public static void main(String[] args) {MyLogger logger = new MyLogger();logger.info("Info message");logger.warn("Warning message");// 輸出:// Logging message: Info message// Logging message: Warning message}
}

6.2 使用場景

  • 多繼承行為:定義多個能力(Flyable, Runnable等)
  • 策略模式:通過不同實現類改變算法
  • API定義:解耦接口與實現(面向接口編程)
  • 函數式接口(@FunctionalInterface):Lambda表達式基礎

7. 抽象類 vs 接口對比

維度抽象類接口(Java 8+)
實例化不能不能
方法實現可包含具體方法默認方法/靜態方法/私有方法
成員變量任意類型和修飾符只能是public static final常量
繼承/實現單繼承(extends)多實現(implements)
構造器
設計目的代碼復用 + 規范約束行為規范定義
訪問控制支持各種訪問修飾符默認public(Java 9支持private)

? 高頻面試題

  1. 以下代碼輸出什么?

    class A {static { System.out.print("1"); }{ System.out.print("2"); }public A() { System.out.print("3"); }
    }class B extends A {static { System.out.print("4"); }{ System.out.print("5"); }public B() { System.out.print("6"); }
    }public class Test {public static void main(String[] args) {new B(); }
    }
    
  2. 靜態方法能否調用非靜態方法?為什么?

  3. 如何實現線程安全的單例模式?

  4. 以下代碼是否合法?

    class Test {static int a = b; static int b = 10;
    }
    
  5. 何時選擇抽象類?何時選擇接口?

  6. 以下代碼是否合法?為什么?

    abstract class A {abstract void method1();final void method2() {}
    }interface B {default void method3() {}static void method4() {}
    }
    

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/899494.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/899494.shtml
英文地址,請注明出處:http://en.pswp.cn/news/899494.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

筆記:遇見未來——6G協同創新技術研討會

https://www.cww.net.cn/article?id564308 研討會由中國移動研究院首席科學家易芝玲博士主持。來自清華大學-中國移動聯合研究院、北京郵電大學-中國移動研究院聯合創新中心、東南大學-中國移動研究院聯合創新中心、中關村泛聯移動通信技術創新應用研究院等合作載體的知名教授…

Python Cookbook-4.14 反轉字典

任務 給定一個字典,此字典將不同的鍵映射到不同的值。而你想創建一個反轉的字典,將各個值反映射到鍵。 解決方案 可以創建一個函數,此函數傳遞一個列表推導作為dict的參數以創建需要的字典。 def invert_dict(d):return dict([(v,k) for …

深度學習在測距模型中的應用

一、單目視覺測距和雙目視覺測距簡介 1、單目視覺測距 模型:深度估計(Depth Estimation) 原理:通過深度學習模型(如MonoDepth2、MiDaS)或傳統的計算機視覺方法(如單目相機結合物體大小推斷&am…

Linux Mem -- Slub內存分配器的幾點疑問及解答

目錄 1 怎樣通過object地址獲取其對應的struct slab? 2 struct page、struct folio和struct slab類型之間轉換,怎么保證內部關鍵數據的傳遞? 3 怎樣判斷一個內存空間是屬于slab、page管理? 4 struct page 結構中 __mapcou…

pip install cryptacular卡住,卡在downloading階段

筆者安裝pip install cryptacular卡在downloading階段,但不知道為何 Collecting cryptacularCreated temporary directory: /tmp/pip-unpack-qfbl8f08http://10.170.22.41:8082 "GET http://repo.huaweicloud.com/repository/pypi/packages/42/69/34d478310d6…

Lag-Llama時間序列模型簡單實現數據預測

前言: 最近在大模型預測,簡單了解了lag-llama開源項目,網上也有很多講解原理的,這里就將如何快速上手使用說一下,只懂得一點點皮毛,有錯誤的地方歡迎大佬指出。 簡單介紹: Lag-Llama 是一個開…

Plastiform復制膠泥:高精度表面復制與測量的高效工具

在工業制造和質量檢測領域,表面復制和測量是確保產品質量的關鍵環節。Plastiform復制膠泥作為一種創新材料,憑借其出色的性能和多樣化的應用,為用戶提供了可靠的解決方案。它能夠快速捕捉復雜表面的細節,確保測量結果的準確性&…

AI大模型、機器學習以及AI Agent開源社區和博客

以下梳理了適合學習 AI大模型、機器學習、AI Agent和多模態技術 的英文網站、社區、官網和博客,按類別分類整理: 一、官方網站與開源平臺 1. AI大模型 (Large Language Models) ? OpenAI ? 官網: openai.com ? 內容: GPT系列模型文檔、研究論文、AP…

python 上下文管理器with

with 上下文管理器 上下文管理器示例如下:若想不使用with關鍵字 上下文管理器 任何實現了 enter() 和 exit() 方法的對象都可稱之為上下文管理器,上下文管理器對象可以使用 with 關鍵字。 必須同時具有__enter__和__exit__,就可以使用with語句…

買賣股票的最佳時機(121)

121. 買賣股票的最佳時機 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int cur_min prices[0];int max_profit 0;for (int i 1; i < prices.size(); i) {if (prices[i] > cur…

CesiumJS 本地數據瓦片加載南北兩極出現圓點問題

const imageryProvider new UrlTemplateImageryProvider({url: "/gisimg/{z}/{x}/{reverseY}.png",minimumLevel: 0,maximumLevel: 19})上面這段代碼是加載本地切片&#xff0c;但是有個致命問題就是會出現南北兩極顯示藍色圓點 解決方案&#xff1a; 加上這句話&am…

Linux編譯器gcc/g++使用完全指南:從編譯原理到動靜態鏈接

一、gcc/g基礎認知 在Linux開發環境中&#xff0c;gcc和g是我們最常用的編譯器工具&#xff1a; gcc&#xff1a;GNU C Compiler&#xff0c;專門用于編譯C語言程序g&#xff1a;GNU C Compiler&#xff0c;用于編譯C程序&#xff08;也可編譯C語言&#xff09; &#x1f4cc…

Vue學習筆記集--computed

computed 在 Vue 3 的 Composition API 中&#xff0c;computed 用于定義響應式計算屬性 它的核心特性是自動追蹤依賴、緩存計算結果&#xff08;依賴未變化時不會重新計算&#xff09; 基本用法 1. 定義只讀計算屬性 import { ref, computed } from vue;const count ref(…

飛致云榮獲“Alibaba Cloud Linux最佳AI鏡像服務商”稱號

2025年3月24日&#xff0c;阿里云云市場聯合龍蜥社區發布“2024年度Alibaba Cloud Linux最佳AI鏡像服務商”評選結果。 經過主辦方的嚴格考量&#xff0c;飛致云&#xff08;即杭州飛致云信息科技有限公司&#xff09;憑借旗下MaxKB開源知識庫問答系統、1Panel開源面板、Halo開…

Vue如何利用Postman和Axios制作小米商城購物車----簡版

實現功能&#xff1a;全選、單選、購物數量顯示、合計價格顯示 實現效果如下&#xff1a; 思路&#xff1a; 1.數據要利用寫在Postman里面&#xff0c;通過地址來調用Postman里面的數據。 2.寫完數據后&#xff0c;給寫的數據一個名字&#xff0c;然后加上一個空數組&#xf…

第一篇:系統分析師首篇

目錄 一、目標二、計劃三、完成情況1.宏觀思維導圖2.過程中的團隊管理和其它方面的思考 四、意外之喜(最少2點)1.計劃內的明確認知和思想的提升標志2.計劃外的具體事情提升內容和標志 一、目標 通過參加考試&#xff0c;訓練學習能力&#xff0c;而非單純以拿證為目的。 1.在復…

CSS學習筆記4——盒子模型

目錄 盒子模型是什么&#xff1f; 盒子模型的組成 一、div標簽 二、邊框屬性 1、border-style:邊框樣式 2、border-width:邊框寬度 3、border-color:邊框顏色、border&#xff1a;綜合設置 4、border-radius:圓角邊框 5、border-image&#xff1a;圖像邊框 三、邊距屬性…

復現文獻中的三維重建圖像生成,包括訓練、推理和可視化

要復現《One - 2 - 3 - 45 Fast Single Image to 3D Objects with Consistent Multi - View Generation and 3D Diffusion (CVPR)2024》文獻中的三維重建圖像生成&#xff0c;包括訓練、推理和可視化&#xff0c;并且確保代碼能正常運行&#xff0c;下面是基本的實現步驟和示例…

stable diffusion 本地部署教程 2025最新版

前提&#xff1a; 需要環境 git git下載地址Git - Downloading Package ? 直接裝即可 python3.10.6 下載地址 Python Release Python 3.10.6 | Python.org ? 記得python環境一定要3.10.6&#xff01;&#xff01;&#xff01; 第一個版本 項目地址https://github.…

【二刷代碼隨想錄】螺旋矩陣求解方法、推薦習題

一、求解方法 &#xff08;1&#xff09;按點模擬路徑 在原有坐標的基準上&#xff0c;疊加 橫縱坐標 的變化值&#xff0c;求出下一位置&#xff0c;并按題完成要求。但需注意轉角的時機判斷&#xff0c;特別是最后即將返回上一出發點的位置。 &#xff08;2&#xff09;按層…