一、繼承
Java中使用關鍵字extends表示繼承,Java中所有的繼承都是公共繼承。
class Manager extends Employee
{
//............
}
子類可以增加域、增加方法或者覆蓋(重寫)父類的方法,但不可以刪除父類的任何域和方法。
子類覆蓋父類方法時,訪問權限不能比父類低,也即父類方法爲public,則子類覆蓋父類的方法也得爲public。
在子類中,如果想調用父類中的方法,而不是當前類的方法,則可以使用關鍵字super。
public float getSalary()
{
return super.getSalary() + bonus;
}
當然,對於子類的構造器,如果沒有顯式的調用父類的構造器,則會自動調用父類默認的構造器(沒有參數的構造器)。
如果此時父類沒有默認的構造器,則此時編譯器會因爲找不到父類的構造器而報錯。
class Employee
{
Employee(String name,int id)
{
//....................
}
}
class Manager extends Employee
{
Manager(String name,int id) //子類的構造方法沒有顯式調用父類構造器,且父類無默認的構造器,所以編譯時會報錯。
{
super.name = name ;
super.id = id;
}
}
多態:
一個對象變量可以引用多種實際類型的現象被稱爲多態。
Manager TempM = new Manager();
Employee TempE = TempM ;
TempE是Employee類型的,TempM是Manager類型的,Manager類繼承了Employee類。
TempE不能使用Manager類的特有方法,也即父類引用不能使用子類的特有方法。子類轉爲父類的引用不需要強制轉換。
public class Test21
{
public static void main(String[] args)
{
Manager TempM = new Manager("zhangs",001);
TempM.setBonus(500);
TempM.tobeString();
System.out.println(TempM.getSalary());
Employee[] staff = new Employee[3] ;
staff[0] = TempM ;
staff[0].tobeString();
// staff[0].setBonus(1000); //staff[0]是Employee類型,不能調用子類Manager的特有方法
System.out.println(staff[0].getSalary());
staff[1] = new Employee("lisi",002);
staff[1].tobeString();
System.out.println(staff[1].getSalary());
staff[2] = new Employee("wange",003);
staff[2].tobeString();
System.out.println(staff[2].getSalary());
staff[0] = new Employee("hj",004);
staff[0].tobeString();
System.out.println(staff[0].getSalary());
TempM.tobeString();
Employee TempM1 = new Manager("zhangs1",005);
System.out.println(TempM1.getSalary());
}
}
class Employee
{
public Employee(String name,int id)
{
this.name = name;
this.id = id;
nextId++;
salary=1000.0f;
}
public void tobeString()
{
System.out.println(name+id+nextId);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public float getSalary()
{
return salary;
}
public void setSalary(float salary)
{
this.salary = salary;
}
public static int getNextId()
{
return nextId ;
}
private String name;
private int id;
private static int nextId = 0;
private float salary ;
}
class Manager extends Employee
{
Manager(String name,int id)
{
super(name,id);
bonus=0 ;
}
public void tobeString()
{
System.out.println(super.getName()+super.getId()+super.getNextId()+bonus);
}
public float getSalary()
{
return super.getSalary()+bonus;
}
public void setBonus(float bonus)
{
this.bonus=bonus;
}
public float getBonus()
{
return bonus;
}
private float bonus;
}
動態綁定(未完全明白,JAVA2核心技術150頁):
所謂動態綁定,也即編譯器尋找具體執行方法的過程。
1、編譯器查看對象的聲明類型和方法名。
例如調用方法X.f(),X是聲明爲A類對象,則編譯器會搜索A類中所有方法名爲f的方法,以及搜索類A的父類中,所有方法名爲f且爲public訪問的方法。
2、編譯器通過具體方法的參數類型,選擇完全匹配的方法。1和2成爲重載解析。
3、如果方法是final,private,static或者構造器,則編譯器會很準確的找到該調用的方法,稱爲靜態綁定。
4、程序運行,虛擬機會調用所引用對象的實際類型最合適的那個類的方法。這其實是一個搜索對應方法的過程,搜索耗時間,所以虛擬機會預先建立一個方法表
阻止繼承:
對類使用final修飾或對方法使用final修飾可以阻止該類被繼承或者該方法再被繼承。
對象聲明爲final之後,只有其中的方法自動變爲final,但域不會變爲final。
強制類型轉換:
將一個類型轉換爲另外一個類型的過程稱爲類型轉換。
在類型強制轉換過程中,如果條件不滿足,可能拋出異常。
在進行類型轉換之前,一般需要檢查一下是否能夠成功進行類型轉換,使用instanceof運算符檢查,如果不能轉換,則編譯器就不會執行轉換操作。
if(staff instanceof Manager)
{
TempM = (Manager)staff ;
}
類型轉換
1、只能在編譯層次內進行類型轉換。
2、將超類轉爲子類之前,需要使用instanceof進行檢查。