面向物件——繼承和多型
阿新 • • 發佈:2018-11-03
面向物件——繼承和多型
一. 繼承
1.繼承:
是一種機制,可以進行程式碼的重用——基類(超類) 子類(派生類) 子類繼承了 父類的除建構函式外的所有屬性
2.super關鍵字:
- super():----->呼叫基類的建構函式 //必須放在第一行
- super.data------->訪問基類的資料成員
- super.func();—>呼叫基類的成員方法
class Base{ protected int a; public Base (int a){ fun1(); this.a=a; } public void fun1() { System.out.println("Base.fun1()"+ this.a); } } class Childern extends Base{ private int b; public Childern(int a,int b) { super(a); super.a = 10; super.fun1(); a=10; this.b=b; System.out.println("Childern.init()..."); } public void fun1() { System.out.println("Childern.fun1()"); } public void fun1(int a) { System.out.println("Childern.fun1(int)"); } }
3.派生類構造物件的初始化順序
class Base{
protected int a;
public Base (int a){
fun1();
System.out.println("Base.init()...");
this.a=a;
}
static {
System.out.println("Base.static...");
}
{
System.out.println("Base.instance...");
}
public void fun1(){
System.out.println("Base.fun1()..."+this.a);
}
public static void fun2(){
System.out.println("Base.fun2()...");
}
}
class Childern extends Base{
private int b;
public Childern(int a,int b) {
super(a);
a=10;
this.b=b;
System. out.println("Childern.init()...");
}
static {
System.out.println("Childern.static...");
}
{
System.out.println("Childern.instance...");
}
public void fun1(){
System.out.println("Childern.fun1()...");
}
public void fun1(int a){
System.out.println("Childern.fun1(int)...");
}
public static void fun2(){
System.out.println("Childern.fun2()...");
}
}
public class Test1031_2 {
public static void main(String[] args) {
Base base =new Childern(1,2);
}
}
列印結果為:
Base.static...
Childern.static...
Base.instance...
Childern.fun1()...
Base.init()...
Childern.instance...
Childern.init()...
可以看出派生類構造物件的初始化順序:
- 基類的靜態塊初始化,
- 派生類的靜態塊初始化
- 基類的例項塊初始化
- 基類的建構函式
- 派生類的例項塊初始化
- 派生類的建構函式
4.基類的資料成員在派生類當中的訪問許可權
同包子類 | 同包非子類 | 不同包子類 | 不同包非子類 | |
---|---|---|---|---|
public | 可以 | 可以 | 可以 | 可以 |
private | 不可以 | 不可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 不可以 | 不可以 |
預設許可權 | 可以 | 可以 | 不可以 | 不可以 |
5.基類和派生類之間的相互賦值
派生類的值可以賦值給基類;
但是基類的值不能賦值給派生類
例如:上面那段程式碼 然後主函式改成:
public static void main1(String[] args) {
Base base = new Base(1);
Childern childern = new Childern(1,2);
base = childern;//這句就是正確的
childern = base;//這句就是錯誤的,error
}
6.過載:overlode; 函式名相同,引數列表不相同,與函式返回值無關 並不一定在同一個類當中;繼承關係上也可以構成過載;
重寫/覆蓋:overwrite;函式名相同,引數列表相同,函式返回值相同
三.多型:
基類引用了派生類物件,並且基類和派生類有同名的覆蓋方法
動多型:發生在執行的時候
靜多型:發生在編譯的時候
方法表是在編譯的時候生成的,
一般的物件放在堆裡 class物件例外放在方法區
方法表和型別一一對應
public static void main2(String[] args) {
Base base=new Base(1);
Childern childern=new Childern(1,2);
base=childern;
}
public static void main3(String[] args) {
Base base=new Base(1);
base.fun1();
System.out.println("===============");
Childern childern=new Childern(1,2);
childern.fun1();
}
public static void main4(String[] args) {
Base base=new Childern(1,2);
base.fun1();//動多型 執行的時候
Base.fun2();//靜多型 編譯的時候
}