Java基礎之:OOP——介面
usb插槽就是現實中的介面,可以把手機,相機,u盤都插在usb插槽上,而不用擔心那個插槽是專門插哪個的,原因是做usb插槽的廠家和做各種設備的廠家都遵守了統一的規定包括尺寸,排線等等,
而在java中我們也可以實作類似這樣的功能,
簡單案例
package class_interface;
?
public class Class_Test {
?
public static void main(String[] args) {
Computer computer = new Computer();
//使用USB介面,多型傳入
//1. 在java中, 允許 將一個實作了某個介面的 類的物件,傳遞給該介面的一個參考
//2. 在介面使用程序中,仍然遵守我們的多型和動態系結機制
computer.work(new Phone()); //匿名物件做傳入引數
computer.work(new U_disk());
}
?
}
?
class Computer{
//Computer類使用了USB介面
public void work(USB usb) { //輸入引數實作介面的多型
usb.start();
usb.stop();
}
?
}
?
//宣告一個介面使用 interface 關鍵字
interface USB{
//對于介面內寫的所有方法而言,都是默認帶有abstract關鍵字修飾的,即抽象方法
public void start();
public void stop();
//在jdk8.0之后,介面中也可以實作方法,但必須是靜態方法與默認方法,例如:
//因為可能會出現一個介面我們會頻繁的使用,且對于介面中的某一個方法都實作一樣的作用,
//那么在介面中實作靜態/默認方法后,在實作介面的類中,直接呼叫此方法即可,不需要再重寫實作此方法
default public void hi() {
System.out.println("say hi....");
}
public static void hello() {
System.out.println("say hello....");
}
}
?
//實作一個介面使用 implements 關鍵字,介面與抽象類很類似
//實作了介面的類,也需要實作介面中的所有抽象方法
class Phone implements USB{
?
@Override
public void start() {
System.out.println("手機開始作業....");
}
?
@Override
public void stop() {
System.out.println("手機停止作業....");
hi();
}
}
?
class U_disk implements USB{
?
@Override
public void start() {
System.out.println("U盤開始作業....");
}
?
@Override
public void stop() {
System.out.println("U盤停止作業....");
}
}
程式輸出
手機開始作業....
手機停止作業....
say hi....
U盤開始作業....
U盤停止作業....
介面介紹
介面就是將沒有實作的抽象方法放在一起,當有類需要使用這些方法時,則根據實際情況將這個方法實作出來,
宣告語法:
-
創建介面
interface 介面名{
//屬性
//抽象方法
}
-
使用介面
class 類名 implements 介面名{
//類自己的屬性
//類自己的方法
//必須實作介面中的抽象方法
}
小結:介面是更加抽象的抽象的類,抽象類里的方法可以有方法體,介面里的所有方法都沒有
方法體,
介面使用細節
1) 介面不能被實體化
2) 介面中所有的方法是 public方法, 介面中抽象方法,可以不用abstract 修飾
3) 一個普通類實作介面,就必須將該介面的所有方法都實作,
4) 抽象類實作介面,可以不用實作介面的方法,
5) 一個類同時可以實作多個介面
6) 介面中的屬性,只能是final的,而且是 public static final 修飾符,比如: int a=1; 實際上是 public static final int a=1; (必須初始化)
7) 介面中屬性的訪問形式: 介面名.常量名
8) 一個介面不能繼承其它的類,但是可以繼承多個別的介面
9) 介面的修飾符 只能是 public 和默認,這點和類的修飾符是一樣的,
細節案例
package class_interface;
public class InterfaceDetail {
public static void main(String[] args) {
}
}
?
//介面命名習慣: 大寫I + 介面名 , 例如:IUser
interface IA{
public void m1();
public void m2();
}
?
interface IB{
public void m1();
public void m3();
}
?
?
//細節1.一個普通類實作介面,就必須將該介面的所有方法都實作,
class CA implements IA{
?
@Override
public void m1() {
?
}
?
@Override
public void m2() {
}
}
?
//細節2.抽象類實作介面,可以不用實作介面的方法,
abstract class CB implements IA{
//這點很容易理解,因為抽象類中允許繼承下來的抽象方法不進行重寫實作,
}
?
//細節3:一個類同時可以實作多個介面 ,且必須實作多個介面中的所有抽象方法
//這里我們會發現,IA與IB介面中,m1()方法重名了,但在CC類中實作并沒有報錯,
//理解:因為m1()方法,僅是介面定義的一個規范,需要類來實作這個規范,而我們只要實作了m1()方法,則IA與IB介面可以使用
class CC implements IA,IB{
?
@Override
public void m3() {
}
?
@Override
public void m1() {
}
?
@Override
public void m2() {
}
}
?
//細節4:介面中的屬性,只能是final的,而且是 public static final 修飾符,
//比如: int a=1; 實際上是 public static final int a=1; (必須初始化)
interface IC{
int a = 1;
// private int b = 2;
/*
* 這里使用private宣告之后,報錯:
* Illegal modifier for the interface field IC.b; only public, static & final are permitted
*/
}
?
//細節5:介面中屬性的訪問形式: 介面名.常量名
class CD implements IC{
//這點也很好理解,因為屬性a是默認被static修飾的,所以只能使用介面名訪問
public void say() {
System.out.println(IC.a);
}
}
?
//細節6:一個介面不能繼承其它的類,但是可以繼承多個別的介面
interface ID extends /*CD*/ IA,IB,IC{
//如果繼承CD類的話,報錯:
//The type CD cannot be a superinterface of ID; a superinterface must be an interface
/*
* 這點容易出現混淆,因為我們之前說Java是單繼承的,但介面這里好像又出現了多繼承的情況
* 我們可以這樣理解,電腦通過USB介面連接上了USB轉換器,通過USB轉換器,我們連接上了讀卡器
* 那么就說,USB介面通過繼承USB連接器擴展了可以連接讀卡器的功能,
* 所以對于介面的繼承而言,并不像是父類與子類的關系,而是使用繼承機制,擴展單個介面的功能,
*/
}
?
//細節7:介面的修飾符 只能是 public 和默認,這點和類的修飾符是一樣的,
/*private*/ interface IE {
/*
* 使用private 報錯:Illegal modifier for the interface IE; only public & abstract are permitted
* 這里可以看到只能使用public與abstract修飾,當然也可以不修飾(即默認),
* 而使用abstract修飾又顯得有一些多余,因為介面本來就是抽象的概念,
*/
}
實作介面與繼承父類之間的區別
-
繼承的價值主要在于:解決代碼的復用性和可維護性,
-
介面的價值主要在于:設計,設計好各種規范(方法),讓其它類去實作這些方法,
-
介面比繼承更加靈活,繼承是滿足 is - a的關系,而介面只需滿足 like - a的關系,
-
介面在一定程度上實作代碼解耦,
簡單案例
package class_interface;
?
public class ImplementsVSExtends {
/*
* 討論實作介面 與 繼承類,到底有什么樣的區別
* 雖然兩者都具有實作功能擴展的能力
*/
public static void main(String[] args) {
/*
* 可以看到這里 物件a 即能夠使用 父類 Person中的eat也能夠使用介面IFish中的swimming
* 但我們可以這樣理解,為什么要使用介面來定義swimming方法,
* 人類與生俱來的能力就一定會吃東西,但游泳并不是與生俱來的能力,即繼承Person
* 那么運動員為了擁有游泳的能力就去向小魚學習,即實作介面IFish,
*
* 總結:
* 繼承:父類是通過子類擴展其已有的方法與功能,
* 實作:類通過介面擴展類所需要的方法與功能,
*/
Athletes a = new Athletes("小范");
a.eat();
a.swimming();
?
}
}
?
class Person{
private String name;
public String getName() {
return name;
}
?
public void setName(String name) {
this.name = name;
}
public Person(String name) {
super();
this.name = name;
}
?
public void eat() {
System.out.println(name + "吃東西....");
}
}
?
interface IFish{
public void swimming();
}
?
class Athletes extends Person implements IFish{
?
public Athletes(String name) {
super(name);
}
?
@Override
public void swimming() {
System.out.println(getName() + "游泳.....");
}
}
程式輸出
小范吃東西....
小范游泳.....
介面的多型特性
在前面的Usb介面案例,Usb usb ,既可以接收手機物件,又可以接收U盤物件,就體現了 介面 多型 (介面參考可以指向實作了介面的類的物件)
簡單案例
演示一個案例:給Usb陣列中,存放 Phone 和 相機物件,Phone類還有一個特有的方法call(),請遍歷Usb陣列,如果是Phone物件,除了呼叫Usb 介面定義的方法外,還需要呼叫Phone 特有方法 call,以及U盤的特有方法read,
package class_interface.InterfacePolyArray;
?
public class InterfacePolyArray {
?
public static void main(String[] args) {
USB[] u = new USB[2];
u[0] = new Phone();
u[1] = new U_disk();
for (int i = 0; i < u.length; i++) {
work(u[i]);
}
}
public static void work(USB usb) { //輸入引數實作介面的多型
usb.start();
usb.stop();
if(usb instanceof Phone) {
((Phone) usb).call();
}else if(usb instanceof U_disk) {
((U_disk) usb).read();
}
}
?
}
?
interface USB{
public void start();
public void stop();
}
?
class Phone implements USB{
?
@Override
public void start() {
System.out.println("手機開始作業....");
}
?
@Override
public void stop() {
System.out.println("手機停止作業....");
}
public void call() {
System.out.println("手機開始打電話......");
}
}
?
class U_disk implements USB{
?
@Override
public void start() {
System.out.println("U盤開始作業....");
}
?
@Override
public void stop() {
System.out.println("U盤停止作業....");
}
public void read() {
System.out.println("U盤開始讀取資料.....");
}
}
程式輸出
手機開始作業....
手機停止作業....
手機開始打電話......
U盤開始作業....
U盤停止作業....
U盤開始讀取資料.....
介面的多型傳遞
介面的多型傳遞解讀:
-
當一個類實作了某個介面
-
這個類的物件可以賦給該介面的參考
-
如果這個類被繼承,那么這個類的子類的物件,也可以賦給該介面的參考
-
如果這個介面是繼承來的,那么這個物件也可以賦給該介面的上層介面的參考
-
不限于一級,可以多級傳遞.
簡單案例
package class_interface.InterfacePolymorphicPass;
/**
下面程式的繼承關系:
IC 繼承于 IB ,IB 繼承于 IA
CA 實作了介面 IC,CB 繼承于 CA
show方法的實際傳入引數:
傳入引數是IC時,可以識別CA與CB的物件 ,因為CA實作了IC 且 CB繼承于CA
而傳入引數是IA時,也可以識別CA與CB的物件,因為CA實作的IC是繼承于IA的(子類物件可以賦值給父類參考),
?
*/
public class InterfacePolymorphicPass {
?
public static void main(String[] args) {
CA ca = new CA();
CB cb = new CB();
show(ca);
show2(ca);
show3(ca);
System.out.println("=================");
show(cb);
show2(cb);
show3(cb);
}
public static void show(IC ic) {
ic.m4();
}
public static void show2(IB ib) {
ib.m3();
}
public static void show3(IA ia) {
ia.m1();
ia.m2();
}
}
?
interface IA{
void m1();
void m2();
}
?
interface IB extends IA{
void m3();
}
?
interface IC extends IB{
void m4();
}
?
class CA implements IC{
?
@Override
public void m1() {
System.out.println("CA--IA--m1");
}
?
@Override
public void m2() {
System.out.println("CA--IA--m2");
}
?
@Override
public void m3() {
System.out.println("CA--IB--m3");
}
?
@Override
public void m4() {
System.out.println("CA--IC--m4");
}
}
?
class CB extends CA{
@Override
public void m3() {
System.out.println("CB--IB--m3");
}
@Override
public void m4() {
System.out.println("CB--IC--m4");
}
}
程式輸出
CA--IC--m4
CA--IB--m3
CA--IA--m1
CA--IA--m2
============
CB--IC--m4
CB--IB--m3
CA--IA--m1
CA--IA--m2
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/235258.html
標籤:其他
上一篇:dataframe的一些用法
