大家好,今天繼續分析250+ Java開發者面試題。分析的前幾部分:第一、第二、第三。那麼讓我們繼續吧。
<類別名稱>{繼承父類別}{介面的實作}
因此,我們擁有: {class 存取修飾符} - 只有public修飾符和缺少的存取修飾符(即default )可用於 class 。 {class static} - static是修飾符,表示該類別是靜態的,僅適用於內部類別(其他類別內部的類別)。 {class Finality} - 如我們所記得的,這是final修飾符,在它的存在下,類別變得不可繼承(來自盒子的範例 - String)。 {class abstraction} - 修飾符-abstract,表示該類別可能有未實現的方法。此修飾符與final修飾符衝突,即類別頭中只能有其中之一,因為abstract修飾符意味著給定的類別將被繼承並且其抽象部分將實現。而final表示這是該類別的最終(final)版本,並且不能被繼承。實際上,同時使用這兩個修飾符是荒謬的,編譯器不會允許我們這樣做。 <class>是必要的關鍵字,指示類別聲明。 <class name>是一個簡單的類別名,它是特定Java類別的識別碼。完全限定類別名稱由完全限定包名 + 組成。+ 簡單的類別名稱。 {繼承自父類別} - 使用extends關鍵字指定父類別(如果有)。例如, ..擴充 ParentClass。 {interfaceimplementation} - 使用implements關鍵字指定此類實作的介面(如果有)。例如: ...實作 FirstInterface、SecondInterface ... 好吧,作為類別頭的範例,考慮Lion類別的頭,它繼承自Cat並實作WildAnimal介面:
29. 是否可以在構造函數中使用 return ?
可以,但return右側沒有回傳值。即可以使用return; 作為構造函數中計算時的輔助構造,以便緊急完成(中斷)後續程式碼的執行並完成物件的初始化。例如,我們有一個類Cat,如果Cat無家可歸 - isHomeless = true,我們需要完成初始化,而不填寫其他字段(畢竟,它們對我們來說是未知的,因為貓無家可歸):public Cat(int age, String name, boolean isHomeless) {
if (isHomeless){
this.isHomeless = isHomeless;
return;
}
this.isHomeless = isHomeless;
this.age = age;
this.name = name;
}
但當涉及到特定值時,建構函數不能使用 return 來傳回值,因為:
- 當聲明建構函式時,你不會有任何類似回傳類型的東西;
- 通常,建構函數在實例化期間會隱式地呼叫;
- 建構子不是方法:它是一種單獨的機制,其唯一目的是初始化實例變量,而new運算子負責建立物件。
30. 建構函數是否可以拋出異常?
建構函數處理異常的方式與方法完全相同。而如果方法允許我們透過在方法頭中寫入throws <ExceptionType>來拋出異常,那麼建構函式允許我們這樣做,並且在繼承和定義繼承建構子時,我們可以擴展異常類型。例如,IOException -> Exception(但反之則不然)。作為建構子拋出異常的範例,我們以Cat類別為例。假設在創建它時我們想從控制台輸入姓名和年齡:public Cat() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
this.name = reader.readLine();
this.age = Integer.parseInt(reader.readLine());
}
由於reader.readLine()拋出 IOException,我們在標頭中將其指定為可能拋出的例外。
31. 類別頭由哪些元素組成?寫一個例子
說到構成類別頭的元素,讓我們來看一個小圖:- 強制組件將放在括號 <> 中
- 可選 - 在 {} 中
public final class Lion extends Cat implements WildAnimal
32. 方法頭由哪些元素組成?寫一個例子
同樣,在查看構成方法頭的元素時,請考慮一個小圖表,其中:- 強制組件位於括號 <> 中
- 可選 - 在 {} 中
public static void main(String[] args) throws IOException
33. 如果基礎物件中沒有定義(但定義了另一個建構函數),則在後代物件中建立預設建構函數
我不完全理解這個問題本身,但也許這意味著,例如,在父級中我們有一些自訂建構函數:public Cat(int age, String name) {
this.age = age;
this.name = name;
}
因此,在祖先類別中,我們肯定需要定義一個建構函數來填充(呼叫)父構造函數:
public class Lion extends Cat {
public Lion(int age, String name) {
super(age, name);
}
}
34.什麼時候使用this關鍵字?
在 Java 中,這有兩種不同的意義。1. 作為當前物件的引用,例如this.age = 9。也就是說,this引用它被呼叫的物件以及使用this 的程式碼所引用的物件。主要作用是增加程式碼的可讀性,避免歧義。例如,如果內部類別欄位的名稱和方法參數相同:public void setName(String name) {
this.name = name;
}
也就是說,this.name是物件名稱的字段 ,是方法參數,靜態方法中不能使用this引用。2. this可以以方法呼叫的形式在建構函式中使用,例如this(value)。在這種情況下,它將呼叫同一類別的另一個建構函數。簡而言之,在創建物件時可以同時呼叫兩個建構函式:
public Cat(int age, String name) {
this(name);
this.age = age;
}
public Cat(String name) {
this.name = name;
}
當建立Cat物件並呼叫第一個建構函式時,該物件的兩個欄位都會被呼叫並成功初始化。有一些細微差別:
- this()只在建構函數中起作用。
- 對另一個建構函式的參考必須位於建構函式區塊(主體)的第一行。因此,不能在一個建構函式中呼叫給定類別的多個(其他)建構函式。
35.什麼是初始化器?
據我了解,在這個問題中我們討論的是普通和統計初始化塊。首先,讓我們記住什麼是初始化。初始化是創建、激活、工作準備、參數確定。使程式或元件進入準備使用狀態。正如您所記得的,在物件建立期間,可以在聲明時直接初始化類別變數:class Cat {
private int age = 9;
private String name = "Tom";
或透過構造函數在外部設定它:
class Cat {
private int age;
private String name;
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
但還有另一種方法:透過初始化區塊設定內部物件變量,它看起來像類別內部的 大括號{ } ,沒有名稱(如方法或建構函數):
class Cat {
private int age;
private String name;
{
age = 10;
name = "Tom";
}
也就是說,初始化區塊是創建物件時載入的一段程式碼。通常,此類區塊用於執行載入類別時所需的一些複雜計算。這些計算的結果可以指定為變數的值。另外,除了常規初始化區塊之外,還有靜態初始化區塊,它們看起來相同,但在大括號之前有static關鍵字:
class Cat {
private static int age;
private static String name;
static{
age = 10;
name = "Tom";
}
該塊與前一個塊完全相同。但是,如果常規物件在每個物件初始化時觸發,則靜態物件只會在類別載入時觸發一次。在這樣的區塊中,通常也會為後續靜態類別變數的初始化進行一些複雜的計算。與靜態方法相同的限制也適用於靜態區塊:它不能使用非靜態數據,也不能使用對當前物件的引用 - this。接下來,我們可以看到類別的初始化順序(及其祖先),以便更好地理解初始化塊被觸發的時刻。
36.繼承一個類別public class Child extends Parent,寫出該物件的初始化順序
當Child類別被載入時,初始化順序如下:- 父類別的靜態欄位。
- 父類別的靜態初始化塊。
- Сhild類別的靜態字段。
- Child類別的靜態初始化區塊。
- Parent類別的非靜態欄位。
- 不是父類別的靜態初始化塊。
- 父類別的建構子。
- Child類別的非靜態欄位。
- 不是Child類別的靜態初始化區塊。
- Child類別的建構子。
37.你知道類別(物件)之間有哪些關係?
Java中類別之間的關係有兩種:- IS-A關係
Lion IS-A Cat
(但不是每隻貓都是獅子)介面的情況完全相同。如果Lion類別實作了WildAnimal接口,那麼它們也存在關係:
Lion IS-A WildAnimal
- HAS-A關係
Car HAS-A Passenger
反之亦然:如果Passenger引用了Car,那麼關係如下:
Passenger HAS-A Car
38.你知道物體之間有哪些關聯關係?
聚合和組合只不過是關聯的特殊情況。 聚合是一種關係,其中一個物件是另一個物件的一部分。例如,乘客可能在車上。此外,可能有幾位乘客,也可能完全沒有(如果我們談論的是特斯拉,則不需要司機)。例如:public class Car {
private List passengers = new ArrayList<>();
void setPassenger(Passenger passenger) {
passengers.add(passenger);
}
void move() {
for (Passenger passenger : passengers) {
System.out.println("Перевозка пассажира - " + passenger.toString());
}
passengers.clear();
}
}
也就是說,我們不關心乘客的數量(或是否有乘客):Car類的功能不依賴於此。聚合也意味著當一個物件被另一個物件使用時,第一個物件可以在其他物件中使用。例如,同一個學生可以既是針織俱樂部的成員,也是搖滾音樂團體的成員,同時又加入了英語學習者團體。如您所知,聚合是類別之間較鬆散的關聯關係。當一個物件不僅是另一個物件的一部分,而且另一個物件的工作非常依賴第一個物件時,組合是一種更嚴格的關係。例如,汽車引擎。儘管引擎可以脫離汽車而存在,但離開汽車就毫無用處。好吧,汽車沒有引擎就無法運作:
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
void startMoving() {
engine.start();
...
}
組合也意味著當一個物件被另一個物件使用時,第一個物件不能屬於任何其他物件。如果我們回到我們的例子,一台引擎只能屬於一輛汽車,但不能同時屬於兩輛或更多汽車。今天我們可能就停在這裡。
GO TO FULL VERSION