0701-070x 繼承

4.1 繼承的概述
4.2 繼承的特點
4.3super關鍵字
4.4函數覆蓋
4.5 子類的實例化過程
4.6 final關鍵字

------------------------------------------------------------------------------------------------------------------
現實中的事物之間存在種種共同點。

爲了創建方便,我們將現實中的事物的特點進行抽取,單獨進行描述.

優點:
1.提高了代碼的複用性
2.讓類之間產生了關係。有了這種關係,纔有了多態的特性。
注意:千萬不要爲了獲取其他類的一部分功能、簡化代碼就進行繼承。
必須是類之間有從屬關係纔可以繼承。(誰是誰的一種纔可以。)

-----------------------------------------------------------------------------------------------------------------
java中只支持單繼承,不支持多繼承。然而它通過了多實現的方式保留了多繼承機制;
另一方面,java還支持多重繼承(兒子有個父親,父親有個父親的父親)

爲什麼java不支持多繼承?
因爲多繼承容易產生衝突。如果兩個父類同時實現了同名但內容不同的功能,不好判斷究竟是繼承了哪一個。

如何使用一個體系中的功能:、
先查閱父類,再根據子類創建對象。
父類中定義的是該體系中的共性功能。通過了解共性功能,我們可以知道該體系的基本功能。
爲什麼這麼做?
1.父類可能是抽象類,無法直接創建對象;
2.子類實現完全,功能甚至更加豐富。

-----------------------------------------------------------------------------------------------------------------
除了繼承之外,java的類之間還有許多別的關係。如組合(聚合、聚集)。
舉個簡單的例子來說,老虎是貓科動物的一種,這就是繼承。老虎繼承了貓科動物的特性。
足球隊的每一個隊員都屬於足球隊,這樣的關係就是組合。
-----------------------------------------------------------------------------------------------------------------
class Fu
{
int num = 1;
}

class Zi extends Fu
{
int num = 2;
}

class ExtendsDemo2
{
public static void main(String [] args)
{
System.out.println("hi "+ num);
//System.out.println("hi "+ super.num);
}
}

研究問題:子類父類出現之後,類成員的特點發生了怎樣的變化?
類成員的組成:
1.成員變量:如果子類父類中出現了非私有的同名成員變量時,子類要訪問本類中的變量,用this;子類想訪問父類中的同名變量時,用super。super的使用和this的使用方法幾乎一致。this代表本類對象的引用,super代表父類對象的引用。
父類引用指向子類對象:多態的一種體現。

2.函數
3.構造函數


如果想要使用父類的功能,那麼可以使用super關鍵字,取父類中的同名變量。
父類先進入方法區。
------------------------------------------------------------------------------------------------------------------
2.函數
 當子類和父類中出現一模一樣的函數時,
當子類對象調用該函數,會運行子類函數的內容,如同父類的函數被覆蓋一樣。
這種情況是函數的另一個特性:覆蓋(重寫)


利用覆蓋的特性,我們可以增強代碼的拓展性。如果子類具備該功能函數,但期望的實現方式卻與弗雷不一樣,那麼這時沒必要定義新功能,使用覆蓋技術,即可保留父類的功能定義並重寫功能內容。

覆蓋:
1.子類覆蓋父類,必須保證子類權限大於父類權限,纔可以覆蓋,否則會編譯失敗。
2.靜態只能覆蓋靜態。(涉及到加載先後問題)

如果子類根本沒有繼承小權限的父類函數,那麼不算覆蓋。

記住:
重載:只看同名函數的參數列表
重寫(覆蓋):子父類方法一模一樣(含返回值類型)。如果返回值類型不一樣,會報錯。
------------------------------------------------------------------------------------------------------------------
3.構造函數。

子類在進行初始化的時候,會在其構造函數內部第一行自動添加super(),運行父類的構造函數。

 
class Fu
{
Fu()
{
System.out.println("fu");
}
}

class Zi extends Fu
{
Zi()
{
System.out.println("zi run");
}
}

class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi();
}
}

默認添加的super()會訪問父類中空參數的構造函數。而子類中所有的構造函數默認調用的都是沒有參數的那個父類構造函數。

爲什麼子類一定要訪問父類中的構造函數?
因爲子類要獲取父類中的各種數據,所以子類對象在建立時,需要先查看父i類是如何對這些成員進行初始化的,因此需要調用父類的構造函數。

如果想指定其它有參數的父類構造函數,可以通過super制定。

注意:super一定要在子類構造函數的第一行。

子類實例化過程 結論:
子類的所有構造函數,默認都會訪問父類中的空參數構造函數。因爲隱式super()

當父類中沒有空參數構造函數的時候,子類必須通過super指定構造函數。

當然,子類的構造函數也可以使用this來訪問本類構造函數。無論如何,子類中至少會有一個構造函數會訪問父類的構造函數。

-----------------------------------------------------------------------------------------------------------------
FINAL 關鍵字

final:最終。是一個修飾符。
特點:
1.可以修飾類、變量、函數。
2.被final修飾的類不可以被繼承。
3.被final修飾的成員函數不可以被複寫。
4.被final修飾的變量是一個常量,只能賦值一次,既可以修飾成員變量也可以修飾局部變量。
5.內部類定義在類中的局部位置上時,只能訪問該局部被final修飾的局部變量。(前四點要記住。

當描述事物的時候,一些數據出現之後值就不應該被改變,那麼這時爲了增強閱讀性,會用final修飾,提示用戶該數據不可以被改變。類似於c++中的const。

常量的書寫習慣是,全部大寫,單詞之間通過_下劃線進行連接。
凡是final,被複寫時就會編譯出錯。
出險原因:繼承打破了封裝。·final可以避免類被繼承,也可以避免被複寫。

-----------------------------------------------------------------------------------------------------------------

抽象類

class BaseStudent
{
void study()
{
System.out.println("study");
}
}

class AdvStudent
{
void study()
{
System.out.println("study");
}
}

class AbstractDemo
{
public static void main(String[] args)
{
System.out.println("hello world");
}
}


當我們需要同樣功能、不同內容的成員函數的時候,可以進行向上抽取。
這時,只抽取功能定義,不抽取功能主體。

這樣抽取出來的東西,因爲不具有方法體而不知道其具體的功能,所以是‘抽象’的,用abstract修飾。

抽象類的特點:
1.抽象方法一定定義在抽象類中。
2.抽象方法和抽象類都必須被abstract關鍵字修飾。
3.抽象類不可以用new創建對象。因爲有些方法沒有被具體實現。
4.抽象類中的方法要被使用,必須由子類複寫完所有的抽象方法之後,建立子類對象調用。
如果子類只覆蓋了部分抽象方法,則該子類依舊是一個抽象類。

抽象類和普通類的區別:
抽象類比一般類多了抽象方法(函數)。就是在類中可以定義抽象方法。
抽象類不可以實例化。


抽象類和普通類沒有太大的不同,該如何設計還是如何設計。
只不過,抽象類中出現了一些尚不能 確定的功能(抽象方法),需要由子類去實現。

注意:抽象類中可以沒有抽象方法。這樣做僅僅是不讓該類建立對象。(java中真有這樣的方法。)
----------------------------------------------------------------------------------------------------------------

加入我們開發一個系統時需要對員工進行建模。
員工含有:姓名 工號 工資

經理也是員工。經理除了員工屬性之外,還有獎金的屬性。

用繼承思想設計出員工類和經理類。要求類中提供必要的方法進行屬性訪問。

員工類:name id pay
經理類:繼承了員工,有bonus

class Employee
{
private String name;
private String id;
private double pay;
Employee(String name,String id,double pay)
{
this.name = name;
this.id = id;
this.pay = pay;
}

public abstract void work();//抽象類留空
}

class Manager extends Employee
{
private int bonus;
Manager(String name,String id,double pay,int bonus)
{
super(name,id,pay);
this.bonus = bonus;
}
public void work()
{
System.out.println("manager work");
}
}

class Pro extends Employee
{
pro(String name ,String id,int pay)
{
super(name,id,pay);
}

public void work()
{
System.out.println("pro work");
}
}

-------------------------------------------------------------------------------------------------------------------
需求:獲取一段程序運行的時間。

原理:獲取開始時間和結束時間。

需求一個類:system中的currentTimeMillis

class GetTime
{
public void getTime()
{
long start = System.currentTimeMillis();

for(int x = 0; x < 1000  ; x ++)
{
System.out.print("x");
}
long end = System.currentTimeMillis();

System.out.println("毫秒"+(end - start));
}
}
class TemplateDemo
{
public static void main(String[] args)
{

GetTime gt = new GetTime();
gt.getTime();
System.out.println("hello world ");
}
}

設計思想:把需要的代碼設計成一個函數,並變成抽象類。實現時先複寫需要運行部分的函數,然後在計時區記錄時間。

abstract class GetTime
{
public final void getTime ()
{
long start =  System.currentTimeMillis();
runcode();
long end =  System.currentTimeMillis();
}

public abstract void runcode();
}

當代碼完成優化後,可以解決一類問題了。
這種方式,我們叫做 模板方法設計模式。

什麼是模板方法?
在定義功能時,功能的一部分是確定的,但是有一部分是不確定的,而確定的部分需要依賴不確定的部分存在。

此時,將不確定的部分暴露出去,由該類的子類去完成。
-------------------------------------------------------------------------------------------------------------------
接口

格式:

interface{}

接口中的成員修飾符是固定的。
成員變量:public static final
成員函數:public abstract
接口的出現,意味着多繼承的另一種表達方式,即 多實現。

抽象類中可以有抽象方法也可以有非抽象方法。

如果一個抽象類中所有的方法都是抽象方法,那麼可以理解爲 是一個接口。(一種方便理解的說法。)

接口跟類表現方式差不多,但是換了個關鍵字。

interface{
public static final int NUM = 3;
public abstract void show();
}

接口定義的時候,格式特點:
1.接口中常見定義:常量,抽象方法。
2.接口中的成員都有固定修飾符:
常量:public static final
方法:public abstract(接口中所有的成員都是public的。

只要放在interface裏,就會被自動補齊相應修飾符。當然,爲了方便程序閱讀,儘量把所有的修飾符都寫完整。

新關鍵字:對於抽象類,我們使用繼承(extends)。對於接口,我們使用實現。(implement)

接口:是不可以創建對象的,因爲有抽象方法未被實現。

interface Inter
{
public static final int NUM = 3;
public abstract void show();
}

class Test implements Inter
{
  public void show(){};
}

class InterfaceDemo
{
public static void main(String[] args)
{
Test t = new Test();

System.out.println(t.NUM);//對象調用成員
System.out.println(Test.NUM);//類調用成員
System.out.println(Inter.NUM);//interface編譯之後也會生成一個class文件
}
}

然而並不能進行賦值。

接口可以被類多實現。也就是說,一個類可以同時實現多個接口。這是java支持多繼承的一種體現方式。

爲什麼接口可以避免衝突?
多繼承有方法體,而多實現不會有衝突的方法體。

一個類,在繼承一個類的同時,還可以實現別的接口。
接口與接口之間可以繼承。
---------------------------------------------------------------------------------------------------------------
接口的特點
接口是對外暴露的規則
接口是程序的功能拓展
接口可以用來多實現
類與接口之間是實現關係,而且類可以集成一個人類的同時實現多個接口
接口與接口之間可以繼承。

降低了耦合性。(你沒做完,我就不能動),增加了開發效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章