資料來源:哈克農
什麼是構造函數?
建構函式是一種在類別中定義的特殊方法,其名稱與類別名稱相同。Java 建構函式就像沒有傳回型別的方法。 建構函數在物件的初始化中發揮最重要的作用,在本文中,我們將列出涵蓋 Java 建構函數的面試問題範例。您還將了解 Java 中建構函數的重要性,查看程式碼範例和其他重要細節,這些細節將幫助您在面試中回答有關 Java 建構函數的問題。為什麼需要構造函數?詳細解釋
假設我們有一個名為Student的類別。我們有實例變數 name 和roll_number。class Student{
String name;
int rollNo;
}
現在,如果我們建立 1000 個對象,那麼 JVM 將使用其預設類型Name = null和rollNo = 0來初始化這些值。識別這些單獨的物件是不可能的,並且為每個物件賦值會增加程式碼量,這被認為是不好的程式設計實踐。因此,為了避免這種情況,使用了建構函數。也就是說,Java中建構函數的目的是初始化類別實例變數的值。
Java中有哪些類型的建構子?
Java 中存在三種不同類型的建構子:- 預設構造函數
- 無參構造函數
- 參數化建構函數
Java中的預設建構子是什麼?
預設建構子是 JVM 在運行時建立的建構子(如果類別中沒有定義建構子)。預設建構函數的主要工作是根據實例的預設類型初始化其值。Java 中的預設建構函式範例:class DefaultConstructor{
int id;
String name;
}
現在對於這個類,如果我們建立一個對象,那麼在 JVM 內部將會有一個預設建構函數,它被賦予一個預設值。
DefaultConstructor df= new DefaultConstructor();
現在,如果我們列印該值,我們將得到:
列印 = df.id = 0.df.name = null。
什麼是無參構造函數?
無參構造函數是可以明確定義以初始化實例值的建構子。例如:class NoArgConstuctor{ int a; int b;
//No Argument Constructor
NoArgConstuctor(){
a = 10;
b = 20;
}
}
什麼是參數化建構函數?
參數化建構子是接受參數來初始化實例的建構子。例如:class ParameterizedConstuctor{
String name;
int age;
//Parameterized Constructor
ParameterizedConstuctor(String name, int age){
this.name = name;
this.age = age;
}
}
定義建構函式的規則是什麼?
要定義建構函數,必須遵循以下幾條規則:-
建構函數名稱必須與類別名稱相符。
-
Java 中不應該有建構函式回傳型別。
-
建構子唯一適用的修飾符是:
- 民眾
- 預設
- 受保護的
- 私人的
-
建構函數可以採用任意數量的參數。
-
建構函式中不允許使用修飾符final、synchronized、static 和abstract。
-
構造函數不支援其主體內的return語句。
-
建構函式中的throw語句可能會出現異常。
-
將throws 子句與建構子一起使用是可以接受的。
-
構造函數不應產生遞歸。
什麼時候可以使用私有建構函式?
如果我們不想從外部建立某個類別的對象,我們可以使用封閉或私有建構子。透過將建構函數宣告為私有,我們只能在類別中建立物件。單例類別是使用私有建構函數的一個很好的例子。如果我們不明確定義預設建構函數存取修飾符,它將是什麼?
預設建構函式存取修飾符始終與類別修飾符相同。如果類別是公共的,那麼建構函數也會是公共的。如果類別是私有的,那麼建構函數也會是私有的。其他存取修飾符也會發生同樣的情況。寫出下面程式碼片段的輸出並解釋
class InterviewBit{
InterviewBit(){
System.out.println(" Welcome to InterviewBit ");
}
}
class ScalerAcademy extends InterviewBit{
ScalerAcademy(){
System.out.println(" Welcome to Scaler Academy by InterviewBit");
}
}
class Main{
public static void main(String[] args) {
ScalerAcademy sc = new ScalerAcademy();
}
}
上面的程式碼將會列印:
歡迎來到採訪比特。歡迎來到 InterviewBit 的 Scaler 學院。
我們會得到這個輸出,因為如果我們在第一行的建構函式中不包含super()或this()關鍵字,JVM 會在執行時自動將其放入。JVM 這樣做是因為它繼承自另一個類,其功能也將在衍生類別中實作。因此,在給基類實例分配預設值時,JVM預設添加了super()關鍵字。
檢查程式碼並指出它是有效還是無效。解釋一下原因
class InterviewBit{
InterviewBit(){
System.out.println(" Welcome to InterviewBit ");
}
}
class ScalerAcademy extends InterviewBit{
ScalerAcademy(){
this();
System.out.println(" Welcome to Scaler Academy by InterviewBit");
}
}
class Main{
public static void main(String[] args) {
ScalerAcademy sc = new ScalerAcademy();
}
}
上面的程式碼無效,因為它與Scaler Academy建構函式內的建構子相同。這會在建構函式中建立遞歸,這是不允許的。因此,我們將收到與呼叫遞歸構造函數相關的編譯時錯誤。
我們可以在 Java 的一個類別中使用兩個建構子嗎?
是的,我們可以在一個類別中使用任意數量的建構函數,但要滿足兩個條件:- 建構函數參數必須不同。
- 構造函數中不應該有遞歸。
InterviewBit(){
this("Scaler"); // Calling parameterized constructor
System.out.println(" No Argument Constructor");
}
InterviewBit(String name){
this(); // Calling no-arg constructor
System.out.println(" Constructor with Parameters.");
}
此程式碼無效,因為它將建立遞歸。不帶參數的建構函數會呼叫帶參數的建構函數,帶參數的建構函數會呼叫不帶參數的建構函數。
我們可以重寫 Java 中的建構函式嗎?
不,構造函數重載的概念在 Java 中不適用。Java中的建構子可以是final的嗎?
沒有構造函數可以是最終的。這是因為Final關鍵字用於停止重寫派生類別中的方法。但在建構子中,不適用重寫的概念,因此不需要寫final關鍵字。如果我們在建構函式中寫入final關鍵字,我們將得到一個稱為必需回傳類型的編譯時錯誤,因為編譯器將其視為方法。Java中的建構子可以是靜態的嗎?
不,Java 構造函數不能是靜態的。這是因為當我們希望成員屬於類別而不是物件時,使用 static 關鍵字。但建構函數的目的是初始化對象,因此編譯器會將其視為方法。我們將得到一個必需的返回類型錯誤。描述一下super()、super和this()、this的差別
super()和this()是建構函式呼叫。僅用於呼叫父類別或當前類別的建構子。請注意,“super”和“this”是關鍵字,用於指定其自己的類別或基底類別的實例的成員。考慮下面的程式碼:class InterviewBit{
String message = " Welcome to InterviewBit";
}
public class Scaler extends InterviewBit
{
String message = " Welcome to Scaler Academy";
public void printMethod(){
//this will print the message variable of the current class.
System.out.println(this.message);
//this will print the message variable of Base class.
System.out.println(super.message);
}
public static void main(String[] args) {
Scaler sa = new Scaler();
sa.printMethod();
}
}
在此程式碼片段中,this.message將列印訊息“ Welcome to Scaler Academy ”,super.message將列印“ Welcome to InterviewBit ”。這就是這兩個關鍵字如何用來引用基底類別和衍生類別的成員實例。
什麼是析構函數?Java中存在析構函數嗎?
析構函數用於釋放程式所取得的記憶體。例如,如果程式在執行期間需要內存,則析構函數會釋放該內存,以便其他程式可以使用它。Java中沒有析構函數的概念,因為Java中釋放記憶體的工作是由垃圾收集器處理的。Java 中的建構函式鍊是什麼?
當一個建構函式被另一個建構函式呼叫時,這可以稱為建構函式鏈。構造函數呼叫不必在同一個類別上進行。父類別也可以這樣做。例如,請考慮下圖。 接下來我們可以看一下用這些實例變數的值來初始化物件的程式碼:class EmployeeAddess{
int pinCode;
String address;
String mobNo;
EmployeeAddress(int pinCode, String address, String mobNo){
this.pinCode = pinCodel
this.address = address;
this.mobNo = mobNo;
}
}
class Employees extends EmployeeAddress{
int ID;
String name;
String designation;
String department;
Employee(int ID, String name, String designation,String department,
int pinCode, String address, String mobNo){
//Calling Constructor for Base class to initialize the object.
//This can be a constructor chaining.
super(pinCode, address, mobNo);
this.ID = ID;
this.name = name;
this.designation = designation;
this.department = department;
}
}
public class Main{
Employee emp = new Employee(101, "XYX", "SDE", "Cloud", 123456, "no 150, xys, xys, INDIA", "999999999");
}
在上面的程式碼中,我們建立了一個Employee類別對象,其中包含員工詳細資料及其地址。Employee地址類別由Employee類別繼承。現在,為了實例化位址的物件值,我們不會為員工的位址分配明確值。相反,我們使用Employee Address類別的建構子來執行此操作。在super(arguments)的幫助下,我們形成了一個建構函式鏈來初始化值。這就是構造函數鏈。
確定程式碼的程式輸出並解釋你的答案。
class InterviewBit{
void InterviewBit(){
System.out.println(" Java Constructor interview questions by InterviewBit");
}
int InterviewBit(int val){
System.out.println(" Java Constructor. And Value = "+val);
}
}
public class Main{
InterviewBit ib1 = new InterviewBit();
InterviewBit ib2 = new InterviewBit();
}
上面的程式碼不會印任何內容,因為InterviewBit()在這裡不是建構子。由於使用了Void和int關鍵字,它變成了一種方法。因此我們不呼叫該方法。我們不會得到任何輸出,因為要執行該方法,我們需要在物件上明確地呼叫它。
編寫一個程序,使用建構函數將物件的值複製到新物件中
class Rectangle{
int length;
int breadth;
Rectangle(int length, int breadth){
this.length = length;
this.breadth = breadth;
}
//Overloaded Constructor for copying the value of old Object to new object
Rectangle(Rectangle obj){
this.length = obj.length;
this.breadth = obj.breadth;
}
}
public class Main{
Rectangle obj1 = new Rectangle(10, 5);
//New Object of rectangle class will be created with the value from obj1.
Rectangle obj2 = new Rectangle(obj1);
}
GO TO FULL VERSION