繼承
繼承后類和類之間關(guān)系的說法
class A extends B{} A類是B類的一種, 誰是誰的一種
class Student extends Person
class Teacher extends Person
class Object類,所有類都繼承Object
繼承后子類和父類之間的成員變量特點
- 成員變量特點 : 如果子類自己有,就是使用自己的,如果自己沒有使用父類繼承
- 方法中調(diào)用本類的成員 this.調(diào)用
- 要是調(diào)用父類的成員 ,關(guān)鍵字super.調(diào)用
super關(guān)鍵字
在繼承中, super關(guān)鍵字用來調(diào)用父類的成員, 子類中調(diào)用自己的成員是this,調(diào)用父類的成員是super
super : 表示父類的內(nèi)存中的存儲位置
繼承后子類和父類之間成員方法特點
當子類中出現(xiàn)了和父類一模一樣的方法, 這樣的現(xiàn)象稱為子類重寫父類的方法.
- 方法的重寫(override) :
- 方法的重載(overload),同一個類中,方法名一樣,參數(shù)列表不同
- 方法的重寫(override),子類中的方法和父類的方法一樣 (方法的聲明一樣)
- 允許特點 : 如果子類重寫了父類的方法(子類自己有),運行子類的.如果子類沒有,運行父類繼承的
- 方法重寫的注意事項
- 重寫的時候,子類方法的權(quán)限必須大于或者等于父類方法的權(quán)限 public protected default private
- 父類的方法是private修飾的,但是私有修飾的成員,子類不知道父類有這個成員,繼承不過來,因此就不存在重寫的問題
方法重寫的案例
繼承的本身含義,為了擴展,為了延伸
/*
* 早年的移動電話
* 打電話,發(fā)信息,來電
*/
public class Phone {
public void call() {
System.out.println("手機撥號打電話");
}
public void sendMessage() {
System.out.println("手機發(fā)信息");
}
public void receive() {
System.out.println("響鈴");
System.out.println("顯示姓名和號碼");
}
}
/*
* 新的智能手機
* 繼續(xù)使用原有手機的功能 繼承
* 擴展自己的新功能 方法重寫
*/
public class IPhone extends Phone{
//擴展自己的新功能 方法重寫
//重寫來電方法
public void receive() {
/*
* 響鈴,顯示姓名和號碼
* 父類的方法已經(jīng)實現(xiàn)了
* 直接使用父類已經(jīng)做好的方法!!
*/
super.receive();
System.out.println("顯示大頭像");
System.out.println("顯示歸屬地");
System.out.println("顯示推銷");
}
}
繼承后子類和父類之間構(gòu)造方法特點
特點 : 子類的構(gòu)造方法,第一行有一個默認的隱式的代碼, super()
不寫super(),也會存在的 javac編譯器幫你寫
super() 作用,調(diào)用父類的無參數(shù)構(gòu)造方法!!
無論子類重載多少個構(gòu)造方法,第一行默認的語句都是 super()
如果父類中,沒有無參數(shù)的構(gòu)造方法
子類的構(gòu)造方法中,我們自己要手寫一個super(傳遞參數(shù))
如果父類中,有多個構(gòu)造方法. 子類的構(gòu)造方法,任意的調(diào)用一個即可
this()和super()
- this訪問本類成員
- super調(diào)用父類成員
- 確定 : 構(gòu)造方法第一行代碼,默認的是super()
- this()和super() 在構(gòu)造方法中,都要站在第一行,不能同時出現(xiàn),只能選擇一個
- 寫this()的構(gòu)造方法,會通過其他的構(gòu)造方法,間接調(diào)用到父類構(gòu)造方法
抽象類
抽象概念 : 凡是說不清的,講不明白的就是抽象
抽象類由來 : 繼承思想,是子類的共性內(nèi)容,抽取形成父類.有些功能在父類中無法具體表現(xiàn)了.
抽象類和抽象方法定義
- 抽象方法定義 : 關(guān)鍵字 abstract
- 修飾符 (權(quán)限 抽象) 返回值類 方法名(參數(shù)列表);
- 抽象方法沒有方法體 {} 不存在的
- 方法定義分號結(jié)束
- 抽象的方法,必須存在于抽象的類中,因此這個類也要抽象修飾
/*
* 動物類 :
* 定義動物的行為 ,吃飯行為 (方法)
* 動物吃什么,這個細節(jié)根本就說不清楚
*/
public abstract class Animal {
public abstract void eat() ;
}
抽象類的使用
- 抽象類不能實例化對象,不能new對象
- 抽象類不能創(chuàng)建對象的原因,方法是抽象的,調(diào)用沒有意義
- 需要定義子類繼承抽象類
- 子類必須要重寫抽象方法 (override)
- 去掉抽象修飾符和分號,添加{}方法體
- 創(chuàng)建子類的對象
/*
* Cat貓類,屬于動物的一種,繼承Animal
*/
public class Cat extends Animal{
/*
* 重寫父類的抽象方法 eat()
*/
public void eat() {
System.out.println("貓吃貓糧");
}
}
抽象類中成員的定義
- 抽象類中能否定義非抽象的方法 (普通方法) 能
- 調(diào)用方法,只能依靠子類對象
- 抽象類中可以定義成員變量嗎,可以
- 變量是私有修飾,提供get set方法訪問變量 (get / set 方法使用子類對象調(diào)用)
- 抽象類中可以有構(gòu)造方法嗎, 抽象類也是類,必須有構(gòu)造方法
- 抽象類中,可以不定義抽象方法嗎,類中的方法全部都是普通方法
- 雖然沒有抽象方法,但是依然是抽象類,不能創(chuàng)建對象
public abstract class Animal {
public Animal() {
super();
}
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void eat();
//抽象類中能否定義非抽象的方法 (普通方法)
public void sleep() {
System.out.println("動物睡覺::");
}
}
抽象類的子類依然有可能還是抽象類
當一個子類繼承抽象類后,重寫了一部分抽象方法,另一部分抽象方法沒有重寫,子類還是一個抽象類,依然不能建立對象
public abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
/*
* 繼承父類Animal,重寫了一部分抽象方法
*
* sleep()方法沒有重寫
*/
public abstract class Cat extends Animal{
public void eat() {
}
//public abstract void sleep();
}
抽象類存在的意義
抽象類的案例
抽象類的員工案例 : 公司的組織
- 事務(wù)分析
- 財務(wù)部員工 : 姓名,工號. 行為 工作
- 研發(fā)部員工 : 姓名,工號. 行為 工作
- 事務(wù)之間存在共性, 抽取 (向上抽取) 形成父類
/*
* 公司類,共性內(nèi)容 姓名,工號,工作行為
*/
public abstract class Company {
private String name; //姓名
private String id; // 工號
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public abstract void work(); // 工作行為
}
/*
* 研發(fā)部員工,屬于公司一種繼承
*/
public class Development extends Company{
public void work() {
System.out.println("研發(fā)部的員工在研發(fā)芯片");
}
}
/*
* 財務(wù)部員工,是公司的一種 ,繼承
*/
public class Finance extends Company{
public void work() {
System.out.println("財務(wù)部員工在數(shù)錢");
}
}
public static void main(String[] args) {
//創(chuàng)建研發(fā)部對象
Development d1 = new Development();
//父類方法 get / set
d1.setName("張三");
d1.setId("研發(fā)部001");
System.out.println(d1.getName());
System.out.println(d1.getId());
//調(diào)用子類重寫的work方法
d1.work();
Development d2 = new Development();
d2.setName("李四");
d2.setId("研發(fā)部002");
System.out.println(d2.getName());
System.out.println(d2.getId());
d2.work();
Finance f1 = new Finance();
f1.setName("翠花");
f1.setId("財務(wù)部001");
System.out.println(f1.getName());
System.out.println(f1.getId());
f1.work();
Finance f2 = new Finance();
f2.setName("翠花plus");
f2.setId("財務(wù)部002");
System.out.println(f2.getName());
System.out.println(f2.getId());
f2.work();
}
案例改進
public void work() {
System.out.println("研發(fā)部的員工在研發(fā)芯片 " + super.getName() +".."+super.getId());
}
public static void main(String[] args) {
//創(chuàng)建研發(fā)部對象
Development d1 = new Development();
//父類方法 get / set
d1.setName("張三");
d1.setId("研發(fā)部001");
//調(diào)用子類重寫的work方法
d1.work();
Development d2 = new Development();
d2.setName("李四");
d2.setId("研發(fā)部002");
d2.work();
Finance f1 = new Finance();
f1.setName("翠花");
f1.setId("財務(wù)部001");
f1.work();
Finance f2 = new Finance();
f2.setName("翠花plus");
f2.setId("財務(wù)部002");
f2.work();
}
接口
接口在生活中到處都是, 筆記本USB接口,電源接口
接口 : 在程序中可以這樣理解, 當一個類中所有的方法全部是抽象方法的時候,這個類稱為接口.
接口是一種特殊的抽象類
接口定義關(guān)鍵字 interface
格式 :
public interface 接口名{
}
接口成員定義 (基于JDK7)
- JDK7 和 JDK8不一樣
- 成員變量
- 接口中定義成員變量,固定格式,定義修飾符是固定寫法
- public static final 數(shù)據(jù)類型 變量名 = 值;
- 修飾符,寫和不寫,沒有區(qū)別,不寫不代表沒有
- 成員方法
- 接口中的成員方法,固定格式
- public abstract 返回值類型 方法名(參數(shù)列表);
/*
* MyInterface名字,接口名
* 修改關(guān)鍵字
* 接口的源文件名.java, 編譯后還是.class文件
*/
public interface MyInterface {
//定義接口的成員變量
//public static final 數(shù)據(jù)類型 變量名 = 值;
//final最終的,不可改變, 看成常量
//命名規(guī)范 : 常量名字全大寫
public static final int A = 1;
//定義接口的成員方法
public abstract void inter();
}
接口的使用
- 接口的使用方式 :
- 接口不能實例化對象,不能new
- 定義類實現(xiàn)接口 (繼承父類,改為實現(xiàn)接口)
- 實現(xiàn)接口關(guān)鍵字
implements
- 類重寫接口的全部抽象方法
- 創(chuàng)建對象使用
public interface MyInterface {
public static final int A = 1;
public abstract void inter();
}
/*
* 定義類,實現(xiàn)接口
* 關(guān)鍵字 implements
*
* MyInterfaceImpl類實現(xiàn)了接口MyInterface
* MyInterfaceImpl類稱為接口MyInterface的實現(xiàn)類 (就是子類)
*/
public class MyInterfaceImpl implements MyInterface{
public void inter() {
System.out.println("實現(xiàn)類實現(xiàn)接口重寫方法");
}
}
public static void main(String[] args) {
//創(chuàng)建接口MyInterface的實現(xiàn)類對象
MyInterfaceImpl my = new MyInterfaceImpl();
//實現(xiàn)類對象調(diào)用方法, 實現(xiàn)類重寫方法
my.inter();
}
接口的多實現(xiàn)
類之間是單繼承關(guān)系,存在局限性.出現(xiàn)接口概念,可以讓一個類實現(xiàn)多個接口, 對單繼承的一種技術(shù)上的改進.
沒有多繼承的安全問題,可以多實現(xiàn)
多實現(xiàn)的寫法 :
public class A implements 接口B, 接口C{
}
public interface InterfaceB {
public abstract void interB();
}
public interface InterfaceC {
public abstract void interC();
}
/*
* 做接口的多實現(xiàn),同時實現(xiàn)接口B和C
* 必須重寫接口B和C的全部抽象方法
*/
public class A implements InterfaceB,InterfaceC{
public void interB() {
System.out.println("實現(xiàn)類A重寫接口B的方法");
}
public void interC() {
System.out.println("實現(xiàn)類A重寫接口C的方法");
}
}
public static void main(String[] args) {
//創(chuàng)建對象, 接口B和C的實現(xiàn)類 ,A類對象
A a = new A();
a.interB();
a.interC();
}