『壹』 如何在java類中定義介面屬性並如何使用介面的方法
摘要
一, 介面基礎知識
1, java語言不支持一個類有多個直接的父類(多繼承),但可以實現(implements)多個介面,間接的實現了多繼承.
2, 與介面相關的設計模式:
1, 定製服務模式
設計精粒度的介面,每個介面代表相關的一組服務,通過繼承來創建復合介面
2, 適配器模式
當每個系統之間介面不匹配時,用適配器來轉換介面
3, 默認適配器模式
為介面提供簡單的默認實現
4, 代理模式
為介面的實現類創建代理類,使用者通過代理來獲得實現類的服務
5, 標識類型模式
用介面來標識一種沒有任何行為的抽象類型
6, 常量介面模式
在介面中定義靜態常量,在其它類中通過import static語句引入這些常量
3, 介面的特徵歸納:
1, 介面中的成員變數默認都是public,static,final類型的(都可省略),必須被顯示初始化,即介面中的成員變數為常量(大寫,單詞之間用"_"分隔)
2, 介面中的方法默認都是public,abstract類型的(都可省略),沒有方法體,不能被實例化
public interface A
{
int CONST = 1; //合法,CONST默認為public,static,final類型
void method(); //合法,method()默認為public,abstract類型
public abstract void method2(); //method2()顯示聲明為public,abstract類型
}
3, 介面中只能包含public,static,final類型的成員變數和public,abstract類型的成員方法
public interface A
{
int var; //錯,var是常量,必須顯示初始化
void method(){...}; //錯,介面中只能包含抽象方法
protected void method2(); //錯,介面中的方法必須是public類型
static void method3(){...}; //錯,介面中不能包含靜態方法
}
4, 介面中沒有構造方法,不能被實例化
public interface A
{
public A(){...}; //錯,介面中不能包含構造方法
void method();
}
5, 一個介面不能實現(implements)另一個介面,但它可以繼承多個其它的介面
public interface A
{
void methodA();
}
public interface B
{
void methodB();
}
public interface C extends A, B //C稱為復合介面
{
void methodC();
}
public interface C implements A{...} //錯
6, 介面必須通過類來實現它的抽象方法
public class A implements B{...}
7, 當類實現了某個介面時,它必須實現介面中的所有抽象方法,否則這個類必須聲明為抽象的
8, 不允許創建介面的實例(實例化),但允許定義介面類型的引用變數,該引用變數引用實現了這個介面的類的實例
public class B implements A{}
A a = new B(); //引用變數a被定義為A介面類型,引用了B實例
A a = new A(); //錯誤,介面不允許實例化
9, 一個類只能繼承一個直接的父類,但可以實現多個介面,間接的實現了多繼承.
public class A extends B implements C, D{...} //B為class,C,D為interface
4, 通過介面,可以方便地對已經存在的系統進行自下而上的抽象,對於任意兩個類,不管它們是否屬於同一個父類,只有它
們存在相同的功能,就能從中抽象出一個介面類型.對於已經存在的繼承樹,可以方便的從類中抽象出新的介面,但從類
中抽象出新的抽象類卻不那麼容易,因此介面更有利於軟體系統的維護與重構.對於兩個系統,通過介面交互比通過抽象
類交互能獲得更好的松耦合.
5, 介面是構建松耦合軟體系統的重要法寶,由於介面用於描述系統對外提供的所有服務,因此介面中的成員變數和方法都
必須是public類型的,確保外部使用者能訪問它們,介面僅僅描述系統能做什麼,但不指明如何去做,所有介面中的方法
都是抽象方法,介面不涉及和任何具體實例相關的細節,因此介面沒有構造方法,不能被實例化,沒有實例變數.二, 比較抽象類與介面
1, 抽象類與介面都位於繼承樹的上層
相同點
1, 代表系統的抽象層,當一個系統使用一顆繼承樹上的類時,應該盡量把引用變數聲明為繼承樹的上層抽象類型,
這樣可以提高兩個系統之間的送耦合
2, 都不能被實例化
3, 都包含抽象方法,這些抽象方法用於描述系統能提供哪些服務,但不提供具體的實現
不同點:
1, 在抽象類中可以為部分方法提供默認的實現,從而避免在子類中重復實現它們,這是抽象類的優勢,但這一優勢
限制了多繼承,而介面中只能包含抽象方法.
由於在抽象類中允許加入具體方法,因此擴展抽象類的功能,即向抽象類中添加具體方法,不會對它的子類造
成影響,而對於介面,一旦介面被公布,就必須非常穩定,因為隨意在介面中添加抽象方法,會影響到所有的實
現類,這些實現類要麼實現新增的抽象方法,要麼聲明為抽象類
2, 一個類只能繼承一個直接的父類,這個父類可能是抽象類,但一個類可以實現多個介面,這是介面的優勢,但這
一優勢是以不允許為任何方法提供實現作為代價的三, 為什麼Java語言不允許多重繼承呢?
當子類覆蓋父類的實例方法或隱藏父類的成員變數及靜態方法時,Java虛擬機採用不同的綁定規則,假如還允許
一個類有多個直接的父類,那麼會使綁定規則更加復雜,因此,為了簡化系統結構設計和動態綁定機制,Java語言
禁止多重繼承.
而介面中只有抽象方法,沒有實例變數和靜態方法,只有介面的實現類才會實現介面的抽象方法(介面中的抽象方
法是通過類來實現的),因此,一個類即使有多個介面,也不會增加Java虛擬機進行動態綁定的復雜度.因為Java虛
擬機永遠不會把方法與介面綁定,而只會把方法與它的實現類綁定.四, 使用介面和抽象類的總體原則:
1, 用介面作為系統與外界交互的窗口
站在外界使用者(另一個系統)的角度,介面向使用者承諾系統能提供哪些服務,站在系統本身的角度,介面制定
系統必須實現哪些服務,介面是系統中最高層次的抽象類型.通過介面交互可以提高兩個系統之間的送耦合
系統A通過系統B進行交互,是指系統A訪問系統B時,
把引用變數聲明為系統B中的介面類型,該引用變數引用系統B中介面的實現類的實例.
public interface B
{
}
public class C implements B
{
}
public class A
{
}
B a = new C();
2, 介面本身必須非常穩定,介面一旦制定,就不允許隨遇更加,否則對外面使用者及系統本身造成影響
3, 用抽象類來定製系統中的擴展點
抽象類來完成部分實現,還要一些功能通過它的子類來實現 2008/1/9
一, Java多態機制中的綁定規則深入剖析
class Base
{
String var = "BaseVar"; //實例變數
static String staticVar = "StaticBaseVar"; //靜態變數 void method() //實例方法
{
System.out.println("Base method");
} static void staticMethod() //靜態方法
{
System.out.println("Static Base method");
}
}public class Sub extends Base
{
String var = "SubVar"; //實例變數
static String staticVar = "StaticSubVar"; //靜態變數
void method() //隱藏父類的method()方法
{
System.out.println("Sub method");
} static void staticMethod() //隱藏父類的staticMethod()方法
{
System.out.println("Static Sub method");
} String subVar = "Var only belonging to Sub"; void subMethod()
{
System.out.println("method only belonging to Sub");
} public static void main(String args[])
{
//引用變數who被聲明為Base類型,引用Sub類的實例
Base who = new Sub();
//成員變數(靜態變數,實例變數)與引用變數所聲明的類型(Base類型)的成員變數綁定
System.out.println("who.var = "+who.var); //所以,列印Base類的var變數
System.out.println("who.staticVar = "+who.staticVar); //所以,列印Base類的staticVar變數 //實例方法與引用變數實際引用的對象(Sub對象)的方法綁定
who.method(); //所以,列印Sub實例的method()方法 //靜態方法與引用變數所聲明的類型(Base類型)的方法綁定
who.staticMethod(); //所以,列印Base類的staticMethod()方法
}
}
【分析過程】
1, 對於一個引用類型的變數,Java編譯器按照它聲明的類型來處理.
例如在以下代碼中,編譯器認為who是Base類型的引用變數,不存在subVar成員變數喝subMethod()方法,編譯報錯
Base who = new Sub(); //引用變數who被聲明為Base類型,引用Sub類的實例
who.subVar = "123"; //編譯錯,在Base類中沒有subVar屬性
who.subMethod(); //編譯錯,在Base類中沒有submethod()方法
如果要訪問Sub類的成員,必須通過強制類型轉換:
Base who = new Sub();
//把Base引用類型的who成員變數強制轉換為Sub引用類型
//把引用變數轉換為子類的類型稱為向下轉型,把引用變數轉換為父類的類型稱為向上轉型
((Sub)who).subVar = "123";
((Sub)who).subMethod();
Java編譯器允許在具有直接或間接繼承關系的類之間進行類型轉換,對於向上轉型,Java編譯器會自動進行,對於
向下轉型,需要進行強制類型轉換
如果兩種類型之間沒有繼續關系,即不在繼承樹的同一個繼承分支上,那麼Java編譯器不允許進行類型轉換
2, 對於一個引用類型的變數,運行時Java虛擬機按照它實際引用的對象來處理
例如以下代碼雖編譯可通過,但運行時會拋出ClassCastException運行時異常
Base who = new Base(); //who引用Base類的實例
Sub s = (Sub)who; //運行時會拋出ClassCastException
在運行時,子類的對象可以轉換為父類類型,而父類的對象實際上無法轉換為子類類型
3, 在運行時環境中,通過引用類型變數來訪問所引用對象的方法和屬性時,Java虛擬機採用以下綁定規則:
1, 實例方法與引用變數實際引用的對象的方法綁定,這種綁定屬於動態綁定,因為是在運行時由Java虛擬機
動態決定的
2, 靜態方法與引用變數所聲明的類型的方法綁定,這種綁定屬於靜態綁定,因為實際上是在編譯階段就已經
綁定
3, 成員變數(靜態變數,實例變數)與引用變數所聲明的類型的成員變數綁定,這種綁定屬於靜態綁定,因為
實際上是在編譯階段就已經綁定
『貳』 JAVA中定義介面時可以包涵哪些成員
在介面類中,成員變數必須都是常量,也就是final修飾的。
介面中的方法默認都是public abstract 都是抽象的,比如 public abstract int(int a,int b);
因為,java中沒有多重繼承,只可以實現多個介面,而有很多的天然性,也就是static final這種類型數據,我們通過實現多個介面,就可以獲得各種不同的天然屬性。
(2)java介面中定義屬性擴展閱讀:
在Java語言規范中,一個方法的特徵僅包括方法的名字、參數的數目和類型,而不包括方法的返回類型、參數名以及所拋出來的異常。在Java編譯器檢查方法的重載時,會根據這些條件判斷兩個方法是否是重載方法。但在Java編譯器檢查方法的置換時,則會進一步檢查兩個方法(分處超類型和子類型)的返還類型和拋出的異常是否相同。
『叄』 java的介面、類、屬性、方法各有哪些修飾符
1、 介面的修飾符只有:public 2、 類的修飾符分為:可訪問控制符和非訪問控制符兩種。 可訪問控制符是:公共類修飾符 public 非訪問控制符有:抽象類修飾符 abstract ;最終類修飾符 final 1、公共類修飾符public: Java 語言中類 的可訪問控制符只有一個: public 即公共的。每個 Java 程序的主類都必須是 public 類作為公共工具供其它類和程序使用的應定義為 public 類。 2 、抽象類修飾符abstract:凡是用 abstract 修飾符修飾的類,被稱為抽象類。所謂抽象類是指這種類沒有具體對象的一種概念類。這樣的類就是 Java 語言的 abstract 類。 3、最終類修飾符final:當一個類不可能有子類時可用修飾符 final 把它說明為最終類。被定義為 final 的類通常是一些有固定作用、用來完成某種標准功能的類。 4、類預設訪問控制符:如果一個類沒有訪問控制符,說明它具有預設的訪問控制符特性。此時,這個類只能被同一個包中的類訪問或引用。這一訪問特性又稱為包訪問性。 3、屬性的控制修飾符也分為:可訪問控制符和非訪問控制符兩類。 可訪問控制符有 4 種:公共訪問控制符: public ;私有訪問控制符: private ;保護訪問控制符: protected ;私有保護訪問控制符: private protected 非訪問控制符有 4 種:靜態域修飾符: static ;最終域修飾符: final ;易失 ( 共享 ) 域修飾符: volatile ;暫時性域修飾符: transient 1、公共訪問控制符 public :用 public 修飾的域稱為公共域。如果公共域屬於一個公共類,則可以被所有其它類所引用。由於 public 修飾符會降低運行的安全性和數據的封裝性,所以一般應減少 public 域的使用。 2、私有訪問控制符 private : 用 private 修飾的成員變數 ( 域 ) 只能被該類自身所訪問,而不能被任何其它類 ( 包括子類 ) 所引用。 3、保護訪問控制符 protected :用 protected 修飾的成員變數可以被三種類所引用:①該類自身;②與它在同一個包中的其它類;③在其它包中的該類的子類。使用修飾符 protected 的主要作用是允許其它包中它的子類來訪問父類的特定屬性。 4、私有保護訪問控制符 private protected :用修飾符 private protected 修飾的成員變數可以被該類本身或該類的子類兩種類訪問和引用。 5、靜態域修飾符 static :用 static 修飾的成員變數僅屬於類的變數,而不屬於任何一個具體的對象,靜態成員變數的值是保存在類的內存區域的公共存儲單元,而不是保存在某一個對象的內存區間。任何一個類的對象訪問它時取到的都是相同的數據;任何一個類的對象修改它時 , 也都是對同一個內存單元進行操作。 6、最終域修飾符 final :最終域修飾符 final 是用來定義符號常量的。一個類的域 ( 成員變數 ) 如果被修飾符 final 說明,則它的取值在程序的整個執行過程中都是不變的。 7、易失 ( 共享 ) 域修飾符 volatile :易失 ( 共享 ) 域修飾符 volatile 是用來說明這個成員變數可能被幾個線程所控制和修改。也就是說在程序運行過程中,這個成員變數有可能被其它的程序影響或改變它的取值。因此,在使用中要注意這種成員變數取值的變化。通常 volatile 用來修飾接受外部輸入的域。 8、暫時性域修飾符 transient :暫時性域修飾符 transient 用來定義一個暫時性變數。其特點是:用修飾符 transient 限定的暫時性變數,將指定 Java 虛擬機認定該暫時性變數不屬於永久狀態,以實現不同對象的存檔功能。否則,類中所有變數都是對象的永久狀態的一部分,存儲對象時必須同時保存這些變數。 4、方法的控制修飾符也分為:可訪問控制符和非訪問控制符兩類。 可訪問控制符有 4 種:公共訪問控制符: public ;私有訪問控制符: private ;保護訪問控制符: protected ;私有保護訪問控制符: private protected 非訪問控制符有 5 種:抽象方法控制符: abstract ;靜態方法控制符: static ;最終方法控制符: final ;本地方法控制符: native ;同步方法控制符: synchronized 1、抽象方法控制符 abstract :用修飾符 abstract 修飾的方法稱為抽象方法。抽象方法是一種僅有方法頭,沒有方法體和操作實現的一種方法。 2、靜態方法控制符 static :用修飾符 static 修飾的方法稱為靜態方法。靜態方法是屬於整個類的類方法;而不使用 static 修飾、限定的方法是屬於某個具體類對象的方法。 由於 static 方法是屬於整個類的,所以它不能操縱和處理屬於某個對象的成員變數,而只能處理屬於整個類的成員變數,即 static 方法只能處理 static 的域。 3、最終方法控制符 final :用修飾符 final 修飾的方法稱為最終方法。最終方法是功能和內部語句不能更改的方法,即最終方法不能重載。這樣,就固定了這個方法所具有的功能和操作,防止當前類的子類對父類關鍵方法的錯誤定義,保證了程序的安全性和正確性。所有被 private 修飾符限定為私有的方法,以及所有包含在 final 類 ( 最終類 ) 中的方法,都被認為是最終方法。 4、本地方法控制符 native :用修飾符 native 修飾的方法稱為本地方法。為了提高程序的運行速度,需要用其它的高級語言書寫程序的方法體,那麼該方法可定義為本地方法用修飾符 native 來修飾; 5、同步方法控制符 synchronized :該修飾符主要用於多線程共存的程序中的協調和同步。
『肆』 如何在Java類中定義介面屬性並如何使用
在介面定義好屬性變數後,只要實現了該介面,那麼就可使用了
『伍』 java介面中可以定義類嗎
可以定義,也不僅限於抽象類。只是介面本身不能被實例化,介面內部的專類是可以屬實例化的。
調用介面的內部類有兩種方法:
1.介面名.類名
2.創建實現類implements介面,再直接實例化內部類
示例代碼:
public interface Test{
class A{
public int a=1;
}
}
--
public class Program {
public static void main(String[] args) {
Test.A a = new Test.A();
System.out.println(a.a);
new B().method();
}
}
class B implements Test{
void method(){
System.out.println(new A().a);
}
}
親測。正常運行列印'1' [換行]'1'