這一期我們繼續介紹Java相關的面試題,這一次還是5道題。下面我們開始一一進行解答。
1.請簡要比較接口和抽象類的區別。
①:接口中不能包含任何非抽象方法,但是抽象類可以包含;
②:接口可以實現多繼承,抽象類不可以實現多繼承;
③:抽象類要被子類繼承,接口要被類實現;
④:接口裏定義的變量只能是公共的靜態的常量,抽象類中的變量是普通變量;
⑤:抽象類可以有構造器,接口不能有構造器。
具體可參照博客鏈接https://www.cnblogs.com/jmyyyy/p/10960271.html,這裏只列出常見的幾種區別了。
2.(1)什麼是內部類?請簡要說說內部類有哪些特點?
(2)什麼是靜態內部類?其有什麼特點?
(1)內部類就是定義在另一個類中內部的類,內部類的特點有:
①:內部類可以訪問其外部類的所有屬性和方法;
②:外部類無法直接訪問內部類的屬性和方法,需要實例化纔可以;
③:內部類如果和外部類有同名的屬性,優先執行內部類的屬性;
④:內部類不能定義static的變量。
下面我們寫一個簡單的例子,加深對內部類的理解。代碼如下:
public class Outer {
private int varOuter = 100;
private double x = 20.5;
/**
* 內部類:對於其他類中的類是隱藏的,不能被訪問;
* 不能定義static的變量,
* 內部類可以直接訪問到外部類的變量,無需實例化;
* 但是外部類想要訪問到內部類,需要實例化,
* 如果類不想被其他類使用,可以聲明爲內部類.
* 內部類如果和外部類有同名的屬性,優先執行內部類的屬性.
* @author autumn_leaf
*
*/
class Inner {
int varInner = 200; //變量定義
double x = 50.5;//內部變量x
//方法定義
public void showOuter() {
System.out.println(varOuter);//調用外部類的變量
System.out.println(x);//50.5
//20.5
System.out.println(Outer.this.x);//調用外部類的同名屬性
}
}
//外部類引用內部類必須要實例化
public void showInner() {
Inner i = new Inner();
System.out.println(i.varInner);//200
i.showOuter();//100
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.showInner();
}
}
(2)靜態內部類就是用static標識的內部類,其特點是可以定義靜態成員和非靜態成員,而非靜態內部類只能定義非靜態成員。
下面寫一個小的例子來簡要介紹靜態內部類的用法,代碼如下:
public class OuterStatic {
private int varOuter = 20;
//內部類可用修飾符:default public private protected
/**
* 定義一個靜態內部類,可以定義靜態的變量,也可以定義非靜態的變量
* 非靜態內部類不可以定義static的變量
*/
private static class innerStatic {
static int a;
int varInner = 200;
public void showOuter() {
//靜態內部類不能調用外部非static修飾的內容
//System.out.println(varOuter);
//可以調用類中定義的非靜態變量
System.out.println(varInner);
}
}
public static void main(String[] args) {
//調用靜態內部類
OuterStatic.innerStatic oi = new OuterStatic.innerStatic();
System.out.println(oi.varInner);
System.out.println(oi.a);
//調用非靜態內部類
Outer o = new Outer();
Outer.Inner i = o.new Inner();
System.out.println(i.varInner);
i.showOuter();
}
}
3.請簡要說說final關鍵字的用法。
final可以修飾屬性、方法以及類,其中:①被修飾的變量不能夠被重新賦值,可以在聲明時賦值,或者在構造器中賦值;②被修飾的類不能夠被繼承;③被修飾的方法不能在子類中被覆蓋,即不能夠被修改。下面寫一個簡單的例子,代碼如下:
public final class FinalDemo {
int a;//默認值爲0
static final int b = 1;//必須有值
//如果當前不是final修飾的類,那麼可能發生繼承關係
//父類被final修飾的方法,子類繼承的時候,不能進行覆蓋
static final void test() {
System.out.println("不能被修改!");
}
}
4.試比較Object類型與String類型equals方法的區別。
Object類型的equals方法只會比較是否是同一個對象,而String類型的equals方法優先判斷是否是同一個對象,若不是同一個對象,則按位進行比較。
下面寫一個簡單的例子來顯示剛剛的說明,代碼如下:
public class ObjectSample {
public static void main(String[] args) {
String str1 = new String("haha");
String str2 = "haha";
String str3 = "haha";
System.out.println(str1 == str2);//false str1進行了實例化,所以這裏不是同一個對象
System.out.println(str2 == str3);//true 指向同一個對象
//Object類型equals方法只會比較是否是同一對象
//String類型equals方法優先判斷是否同一個對象,若不是同對象,則按位進行比較
System.out.println(str1.equals(str2));//true
}
}
結果我已經註釋在後面了,下面我們查看一下equals方法的底層源碼,如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
5.嘗試對一個郵箱進行檢測並拋出異常,要求用戶名長度不能超過12位(@符號前面爲用戶名),@符號後面必須以.com或者.cn結尾,試寫出簡要的檢驗代碼。
我們首先定義一個異常EmailCheckException,代碼如下:
public class EmailCheckException extends Exception{
private static final long serialVersionUID = 1L;
public EmailCheckException(String msg) {
super(msg);
}
}
然後郵箱檢測類EmailCheck代碼如下:
import java.util.Scanner;
/**
* 郵箱檢測
* @author autumn_leaf
*
*/
public class EmailCheck {
public static void checkEmail(String email) throws EmailCheckException {
int unameLen = email.indexOf('@');
int begin = email.indexOf('@');
int end = email.lastIndexOf('@');
int dot = email.indexOf('.');//從開始位置.出現的位置
//用戶名長度判斷
if(unameLen > 12) {
throw new EmailCheckException("Email用戶名長度超過12位!");
}else if(begin != end) {
throw new EmailCheckException("Email中包含多個@!");
}
//未出現@或者@在開頭或者@在結尾
else if(begin == -1 || begin == 0 || begin == email.length()-1) {
throw new EmailCheckException("@沒有出現或者@位置不對!");
}else if(begin > dot) {
throw new EmailCheckException("@與.出現的位置不對!");
}else if(!email.endsWith(".com") && !email.endsWith(".cn")){
throw new EmailCheckException("郵箱結尾不是.com或者.cn!");
}
}
public static void main(String[] args) {
System.out.println("請輸入郵箱:");
Scanner sc = new Scanner(System.in);
String email = sc.nextLine();
try {
checkEmail(email);
} catch (EmailCheckException e) {
e.printStackTrace();
}
System.out.println("操作結束!");
}
}
上述代碼中我們先自定義一個郵箱異常類,然後定義一個郵箱檢測類,在函數中我們考慮以下幾點:
①:用戶名長度不能超過12;
②:只能有一個@符號;(沒有或者多個@都算錯)
③:@符號不能出現在第一個或者最後一個位置;
④:@必須出現在.前面;
⑤:email結尾必須以.com或者.cn結尾。
當這幾點都考慮好之後,函數基本就寫好了,然後我們在main方法中進行測試就行。
好了,第二期面試題分享就到這裏了,我們下期再見!