第03天java面向?qū)ο?/b>
今日內(nèi)容介紹
·接口
·匿名對象&final
·多態(tài)
·接口
1.接口的概述
接口是功能的集合抹腿,同樣可看做是一種數(shù)據(jù)類型,是比抽象類更為抽象的”類”笔呀。
接口只描述所應該具備的方法幢踏,并沒有具體實現(xiàn),具體的實現(xiàn)由接口的實現(xiàn)類(相當于接口的子類)來完成许师。這樣將功能的定義與實現(xiàn)分離房蝉,優(yōu)化了程序設計僚匆。
·接口的格式&使用
1.接口的格式
與定義類的class不同,接口定義時需要使用interface關(guān)鍵字搭幻。
定義接口所在的仍為.java文件咧擂,雖然聲明時使用的為interface關(guān)鍵字的編譯后仍然會產(chǎn)生.class文件。這點可以讓我們將接口看做是一種只包含了功能聲明的特殊類檀蹋。
定義格式:
public interface接口名{
抽象方法1;
抽象方法2;
抽象方法3;
}
·接口的使用
接口中的方法全是抽象方法,直接new接口來調(diào)用方法沒有意義,Java也不允許這樣干
類與接口的關(guān)系為實現(xiàn)關(guān)系松申,即類實現(xiàn)接口。實現(xiàn)的動作類似繼承俯逾,只是關(guān)鍵字不同贸桶,實現(xiàn)使用implements
其他類(實現(xiàn)類)實現(xiàn)接口后,就相當于聲明:”我應該具備這個接口中的功能”桌肴。實現(xiàn)類仍然需要重寫方法以實現(xiàn)具體的功能皇筛。
格式:
class類implements接口{
重寫接口中方法
}
在類實現(xiàn)接口后,該類就會將接口中的抽象方法繼承過來坠七,此時該類需要重寫該抽象方法水醋,完成具體的邏輯。
3.案例代碼一:
packagecom.itheima_01;
/*
* Java語言的繼承是單一繼承彪置,一個子類只能有一個父類(一個兒子只能有一個親爹)
* Java語言給我們提供了一種機制拄踪,用于處理繼承單一的局限性的,接口
*
*接口:接口是一個比抽象類還抽象的類拳魁,接口里所有的方法全是抽象方法惶桐,接口和類的關(guān)系是實現(xiàn),implements
*interface
*
*格式:
*interface接口名{
*
*}
*
*/
publicclassInterfaceDemo {
publicstaticvoidmain(String[] args) {
BillGates gates =newBillGates();
gates.code();
}
}
classBoss {
publicvoidmanage() {
System.out.println("管理公司");
}
}
classProgrammer {
publicvoidcode() {
System.out.println("敲代碼");
}
}
//比爾蓋茨
classBillGatesextendsProgrammer {
}
3.接口中成員的特點
1的猛、接口中可以定義變量耀盗,但是變量必須有固定的修飾符修飾想虎,public static final所以接口中的變量也稱之為常量卦尊,其值不能改變。后面我們會講解fnal關(guān)鍵字
2舌厨、接口中可以定義方法岂却,方法也有固定的修飾符,public abstract
3裙椭、接口不可以創(chuàng)建對象躏哩。
4、子類必須覆蓋掉接口中所有的抽象方法后揉燃,子類才可以實例化扫尺。否則子類是一個抽象類。
1.案例代碼二:
packagecom.itheima_01;
/*
*接口的成員特點:
*只能有抽象方法
*只能有常量
*默認使用public&abstract修飾方法
*只能使用public&abstract修飾方法
*默認使用public static final來修飾成員變量
*
*建議:建議大家手動的給上默認修飾符
*
*注意:
*接口不能創(chuàng)建對象(不能實例化)
*類與接口的關(guān)系是實現(xiàn)關(guān)系炊汤,一個類實現(xiàn)一個接口必須實現(xiàn)它所有的方法
*/
publicclassInterfaceDemo2 {
publicstaticvoidmain(String[] args) {
//Animal a = new Animal();
//Animal.num;
}
}
interfaceAnimal {
publicstaticfinalintnum= 10;
publicabstractvoideat();
}
classCatimplementsAnimal {
publicvoideat() {
}
}
4.接口和類的關(guān)系
A:類與類之間:繼承關(guān)系,一個類只能直接繼承一個父類,但是支持多重繼承
B:類與接口之間:只有實現(xiàn)關(guān)系,一個類可以實現(xiàn)多個接口
C:接口與接口之間:只有繼承關(guān)系,一個接口可以繼承多個接口
1.案例代碼三:
packagecom.itheima_01;
/*
*
*類與類:繼承關(guān)系正驻,單一繼承弊攘,多層繼承
*類與接口:實現(xiàn)關(guān)系,多實現(xiàn)
*接口與接口的關(guān)系:繼承關(guān)系姑曙,多繼承
*/
publicclassInterfaceDemo3 {
publicstaticvoidmain(String[] args) {
}
}
interfaceInterAextendsInterB {
publicabstractvoidmethod();
}
interfaceInterB {
publicabstractvoidfunction();
}
interfaceInterCextendsInterA {
}
classDemoimplementsInterC {
@Override
publicvoidmethod() {
//TODOAuto-generated method
stub
}
@Override
publicvoidfunction() {
//TODOAuto-generated method
stub
}
}
5.接口的思想
前面學習了接口的代碼體現(xiàn)襟交,現(xiàn)在來學習接口的思想,接下里從生活中的例子進行說明伤靠。
舉例:我們都知道電腦上留有很多個插口捣域,而這些插口可以插入相應的設備,這些設備為什么能插在上面呢宴合?主要原因是這些設備在生產(chǎn)的時候符合了這個插口的使用規(guī)則焕梅,否則將無法插入接口中,更無法使用卦洽。發(fā)現(xiàn)這個插口的出現(xiàn)讓我們使用更多的設備丘侠。
接口的出現(xiàn)方便后期使用和維護,一方是在使用接口(如電腦)逐样,一方在實現(xiàn)接口(插在插口上的設備)蜗字。例如:筆記本使用這個規(guī)則(接口),電腦外圍設備實現(xiàn)這個規(guī)則(接口)脂新。
集合體系中大量使用接口
Collection接口
List接口
ArrayList實現(xiàn)類
LinkedList實現(xiàn)類
Set接口
6.接口優(yōu)點
1.類與接口的關(guān)系挪捕,實現(xiàn)關(guān)系,而且是多實現(xiàn)争便,一個類可以實現(xiàn)多個接口级零,類與類之間是繼承關(guān)系,java中的繼承是單一繼承滞乙,一個類只能有一個父類奏纪,打破了繼承的局限性。
2.對外提供規(guī)則(USB接口)
3.降低了程序的耦合性(可以實現(xiàn)模塊化開發(fā)斩启,定義好規(guī)則序调,每個人實現(xiàn)自己的模塊,提高了開發(fā)的效率)
7.接口和抽象類的區(qū)別
1.共性:
不斷的進行抽取兔簇,抽取出抽象的发绢,沒有具體實現(xiàn)的方法,都不能實例化(不能創(chuàng)建對象)
2.區(qū)別1:與類的關(guān)系
(1)類與接口是實現(xiàn)關(guān)系,而且是多實現(xiàn)垄琐,一個類可以實現(xiàn)多個接口边酒,類與抽象類是繼承關(guān)系缸濒,Java中的繼承是單一繼承据某,多層繼承,一個類只能繼承一個父類绊谭,但是可以有爺爺類
(2)區(qū)別2: 成員
a.成員變量
抽象類可以有成員變量翻擒,也可以有常量
接口只能有常量氓涣,默認修飾符public static final
b.成員方法
抽象類可以有抽象方法鹃操,也可以有非抽象方法
接口只能有抽象方法,默認修飾符public abstract
c.構(gòu)造方法
抽象類有構(gòu)造方法春哨,為子類提供
接口沒有構(gòu)造方法
8.運動員案例
1.案例代碼四:
//Person類
package com.itheima_02;
public class Person {
private String name;//姓名
private int age;//年齡
private String gender;//性別
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age, String
gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void eat() {
System.out.println("吃飯...");
}
public void sleep() {
System.out.println("Zzz....");
}
}
//Player類
package com.itheima_02;
//運動員
public abstract class Player extends Person {
//學習
public abstract void study();
}
//Coach類
package com.itheima_02;
//教練
public abstract class Coach extends Person {
//教
public abstract void teach();
}
//PingPangPlayer類
package com.itheima_02;
public class PingPangPlayerextends Player {
@Override
public void study() {
System.out.println("學習抽球");
}
}
//
BasketbalPlayer類
package com.itheima_02;
public class BasketbalPlayer extends Player
implements SpeakEnglish{
@Override
public void study() {
System.out.println("學習扣籃");
}
@Override
public void speak() {
System.out.println("說英語");
}
}
//
PingPangCoach類
package com.itheima_02;
public class PingPangCoach extends Coach{
@Override
public void teach() {
System.out.println("教抽球");
}
}
//
BasketbalCoach類
package com.itheima_02;
public class BasketbalCoach extends Coach
implements SpeakEnglish{
@Override
public void teach() {
System.out.println("教扣籃");
}
@Override
public void speak() {
System.out.println("說英語");
}
}
//
SpeakEnglish類
package com.itheima_02;
public interface SpeakEnglish {
public abstract void speak();
}
//
InterfaceTest類
package com.itheima_02;
/*
*籃球運動員和教練
乒乓球運動員和教練
現(xiàn)在籃球運動員和教練要出國訪問,需要學習英語
請根據(jù)你所學的知識,分析出來哪些是類,哪些是抽象類,哪些是接口
*/
public class InterfaceTest {
public static void main(String[] args) {
//創(chuàng)建籃球運動員的對象
BasketbalPlayer bp = new BasketbalPlayer();
bp.setName("女兆日月");
bp.setAge(35);
bp.setGender("男");
bp.eat();
bp.study();
bp.speak();
System.out.println("------------");
//創(chuàng)建乒乓球教練
PingPangCoach ppc = new PingPangCoach();
ppc.setName("劉胖子");
ppc.setAge(40);
ppc.setGender("男");
ppc.eat();
ppc.teach();
}
}
2.多態(tài)
1.多態(tài)概述
多態(tài)是繼封裝荆隘、繼承之后,面向?qū)ο蟮牡谌筇匦浴?/p>
現(xiàn)實事物經(jīng)常會體現(xiàn)出多種形態(tài)赴背,如學生椰拒,學生是人的一種,則一個具體的同學張三既是學生也是人凰荚,即出現(xiàn)兩種形態(tài)燃观。
Java作為面向?qū)ο蟮恼Z言,同樣可以描述一個事物的多種形態(tài)便瑟。如Student類繼承了Person類缆毁,一個Student的對象便既是Student,又是Person到涂。
2.多態(tài)的定義與使用格式
多態(tài)的定義格式:就是父類的引用變量指向子類對象
父類類型變量名= new子類類型();
變量名.方法名();
A:普通類多態(tài)定義的格式
父類變量名= new子類();
如:class Fu {}
class Zi extends Fu {}
//類的多態(tài)使用
Fu f = new Zi();
B:抽象類多態(tài)定義的格式
抽象類變量名= new抽象類子類();
如:abstract class Fu {
public abstract void method();
}
class Zi extends Fu {
public void method(){
System.out.println(“重寫父類抽象方法”);
}
}
//類的多態(tài)使用
Fu fu= new Zi();
C:接口多態(tài)定義的格式
接口變量名= new接口實現(xiàn)類();
如:interface Fu {
publicabstract void method();
}
class Zi implements Fu {
publicvoid method(){
System.out.println(“重寫接口抽象方法”);
}
}
//接口的多態(tài)使用
Fu fu = new Zi();
1.案例代碼五:
packagecom.itheima_01;
/*
*多態(tài)的前提:
*子父類的繼承關(guān)系
*方法的重寫
*父類引用指向子類對象
*
*動態(tài)綁定:運行期間調(diào)用的方法脊框,是根據(jù)其具體的類型
*
*
*
*
*/
publicclassPoymorphicDemo {
publicstaticvoidmain(String[] args) {
/*Cat c = new Cat();
c.eat();*/
//父類引用Animal a
//指向=
//子類對象new Cat()
Animal a =newCat();
a.eat();
}
}
classAnimal {
publicvoideat() {
System.out.println("吃東西");
}
}
classCatextendsAnimal {
publicvoideat() {
System.out.println("貓吃魚");
}
}
3.多態(tài)成員的特點
A:多態(tài)成員變量
當子父類中出現(xiàn)同名的成員變量時,多態(tài)調(diào)用該變量時:
編譯時期:參考的是引用型變量所屬的類中是否有被調(diào)用的成員變量践啄。沒有浇雹,編譯失敗。
運行時期:也是調(diào)用引用型變量所屬的類中的成員變量屿讽。
簡單記:編譯和運行都參考等號的左邊昭灵。編譯運行看左邊。
B:多態(tài)成員方法
編譯時期:參考引用變量所屬的類伐谈,如果沒有類中沒有調(diào)用的方法烂完,編譯失敗。
運行時期:參考引用變量所指的對象所屬的類诵棵,并運行對象所屬類中的成員方法抠蚣。
簡而言之:編譯看左邊,運行看右邊
1.案例代碼六:
packagecom.itheima_01;
/*
*
*多態(tài)的成員特點:
*成員變量編譯時看的是左邊非春,運行時看的左邊
*成員方法編譯時看的是左邊柱徙,運行時看右邊
*靜態(tài)方法編譯時看的是左邊,運行時看的也是左邊
*
*
*編譯時看的都是左邊奇昙,運行時成員方法看的是右邊,其他(成員變量和靜態(tài)的方法)看的都是左邊
*
*/
publicclassPoymorphicDemo2 {
publicstaticvoidmain(String[] args) {
Dad d =newKid();
//System.out.println(d.num);
//d.method();
d.function();//使用變量去調(diào)用靜態(tài)方法敌完,其實相當于用變量類型的類名去調(diào)用
}
}
classDad {
intnum= 20;
publicvoidmethod() {
System.out.println("我是父類方法");
}
publicstaticvoidfunction() {
System.out.println("我是父類靜態(tài)方法");
}
}
classKidextendsDad {
intnum= 10;
publicvoidmethod() {
System.out.println("我是子類方法");
}
publicstaticvoidfunction() {
System.out.println("我是子類靜態(tài)方法");
}
}
4.多態(tài)中向上轉(zhuǎn)型與向下轉(zhuǎn)型
多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型與向下轉(zhuǎn)型兩種:
A:向上轉(zhuǎn)型:當有子類對象賦值給一個父類引用時储耐,便是向上轉(zhuǎn)型,多態(tài)本身就是向上轉(zhuǎn)型的過程滨溉。
使用格式:
父類類型變量名= new子類類型();
如:Person p = new Student();
B:向下轉(zhuǎn)型:一個已經(jīng)向上轉(zhuǎn)型的子類對象可以使用強制類型轉(zhuǎn)換的格式什湘,將父類引用轉(zhuǎn)為子類引用长赞,這個過程是向下轉(zhuǎn)型。如果是直接創(chuàng)建父類對象闽撤,是無法向下轉(zhuǎn)型的
使用格式:
子類類型變量名= (子類類型)父類類型的變量;
如:Student stu = (Student) p;//變量p實際上指向Student對象
1.案例代碼七:
packagecom.itheima_01;
/*
*
*多態(tài)中的向上轉(zhuǎn)型和向下轉(zhuǎn)型:
*
*引用類型之間的轉(zhuǎn)換
*向上轉(zhuǎn)型
*由小到大(子類型轉(zhuǎn)換成父類型)
*向下轉(zhuǎn)型
*由大到小
*基本數(shù)據(jù)類型的轉(zhuǎn)換
*自動類型轉(zhuǎn)換
*由小到大
*byte short char ---int---long --- float --- double
*強制類型轉(zhuǎn)換
*由大到小
*
*
*
*/
publicclassPoymorphicDemo3 {
publicstaticvoidmain(String[] args) {
Animal2 a =newDog();//向上轉(zhuǎn)型
//a.eat();
Dog d = (Dog)a;//向下轉(zhuǎn)型
d.swim();
}
}
classAnimal2 {
publicvoideat() {
System.out.println("吃東西");
}
}
classDogextendsAnimal2 {
publicvoideat() {
System.out.println("啃骨頭");
}
publicvoidswim() {
System.out.println("狗刨");
}
}
5.多態(tài)的優(yōu)缺點
1.案例代碼八:
packagecom.itheima_01;
/*
*
*多態(tài)的優(yōu)缺點
*優(yōu)點:可以提高可維護性(多態(tài)前提所保證的)得哆,提高代碼的可擴展性
缺點:無法直接訪問子類特有的成員
*/
publicclassPoymorphicDemo4 {
publicstaticvoidmain(String[] args) {
MiFactory factory =newMiFactory();
factory.createPhone(newMiNote());
factory.createPhone(newRedMi());
}
}
classMiFactory {
/*public void createPhone(MiNotemi) {
mi.call();
}
public void createPhone(RedMimi) {
mi.call();
}*/
publicvoidcreatePhone(Phone p) {
p.call();
}
}
interfacePhone {
publicvoidcall();
}
//小米Note
classMiNoteimplementsPhone{
publicvoidcall() {
System.out.println("小米Note打電話");
}
}
//紅米
classRedMiimplementsPhone {
publicvoidcall() {
System.out.println("紅米打電話");
}
}
?W?????